美文网首页
Zuul路由网关与过滤器

Zuul路由网关与过滤器

作者: superxcp | 来源:发表于2020-02-01 15:31 被阅读0次

    技术需求点:
    1.介绍Zuul网关路由和过滤器两大功能的工作原理;
    2.模拟Zuul路由网关功能;
    3.使用Zuul网关过滤器实现简单的请求鉴权;

    一.Zuul介绍

    来自客户端的请求,一切对服务的请求都会经过Zuul网关,然后由网关实现鉴权、动态路由等操作,Zuul就是我们的统一入口。

    Zuul是Netflix开源的微服务网关,可以和SpringCloud系列的组件(Eureka、Ribbon、Hystrix、Feign等)配合使用,它的核心是一系列的过滤器,主要可以完成以下功能:

    • 安全认证:拒绝不符合要求的请求;
    • 性能监控:在网关的边缘位置追踪并统计数据,以视图方式展现;
    • 压力测试:逐渐增加指向集群的流量,测试性能;
    • 负载均衡:为每种负载类型分配对应容量,丢弃过量的请求;
    • 静态响应处理:在服务边界位置直接返回结果;
    • 动态路由:动态的将请求理由到不同的后端集群;
    • 多区域弹性:跨越AWS Region进行请求路由,只在实现ELB使用的多样化,让系统边缘更贴近系统使用者;
    图片来源参考4.png

    二.路由功能

    使用SpringBoot和SpringCloud搭建项目的详细方法请参考我的SpringCloud+SpringBoot搭建服务注册与调用平台这篇文章,本文是在这篇文章搭建的服务基础上添加Zuul网关的。

    1.项目结构


    image.png

    2.pom依赖

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            </dependency>
    

    3.配置文件
    Zuul网关是一个单独的服务,也可以被注册到eureka注册中心,所以我们在zuul服务里配置service-id就可以找到被调用的服务,zuul的路由功能表现在path的配置里,请求地址【类似http://127.0.0.1:9093/user-service/user】中只有带着/user-service才可以被正确的转发。

    spring.application.name=gateway
    server.port=9093
    
    #设置服务注册中心地址,指向另一个注册中心
    eureka.client.serviceUrl.defaultZone=http://192.168.33.100:8761/eureka/,http://192.168.33.101:8761/eureka/
    
    #1.user-service-rouuts:路由id,相当于个路由器,负责转发请求
    #2.zuul.routes.user-service-routes.path:请求地址中必须带着/user-service才会被网关认为是有效请求
    #3.zuul.routes.user-service-routes.service-id:调用哪个服务处理请求,根据服务id寻找服务
    zuul.routes.user-service-routes.path=/user-service/ ** # "**"前面没有空格,简书格式有点问题,不加空格下面的代码就是灰色的
    zuul.routes.user-service-routes.service-id=eureka-provider
    
    • 配置优化
      实际上,path和service-id可以不配,zuul会用service-id作为默认的路由id,比如我们的服务id是eureka-provider,使用【http://127.0.0.1:9093/eureka-provider/user】就可以通过网关访问到eureka-provider的user接口。
      但是有时实际业务中有一些需要特殊配置的路由,例如在链接前面加个前缀,不希望某些服务经过网关(静态网页等资源)等,这时候就必须配置path和service-id了,再加上这样的配置:
    zuul.prefix=api
    zuul.ignored-services=eureka-consumer
    

    4.启动类

    @EnableZuulProxy
    @EnableFeignClients
    @SpringCloudApplication
    public class ZuulApplication {
        public static void main(String[] args) {
            SpringApplication.run(ZuulApplication.class,args);
        }
    }
    

    5.测试结果
    输入http://127.0.0.1:9093/user-service/user发现可以请求成功

    image.png

    输入http://127.0.0.1:9093/user发现请求失败

    image.png

    三.过滤器

    Zuul作为网关的一个重要功能,就是实现请求的鉴权,比如服务端需要判定客户端的请求是合法的才处理,鉴权极大的提高了系统的安全性,避免被暴力攻击。鉴权往往是通过Zuul的过滤器实现的,即在请求进入业务代码之前,对请求的合法性进行判定。(过滤器的使用场景还有异常处理,服务调用时长统计等)

    1.ZuulFilter的生命周期


    image.png

    请求首先会经过pre类型的过滤器,然后到达routing类型过滤器,进行路由,请求此时到达真正的服务提供者执行请求,返回结果后,会到达post过滤器,然后返回响应。整个过程中,如果出现异常,会交给error过滤器处理,但是不同阶段进入error过滤器的时机是不同的,感兴趣的同学可查阅官方文档,在此不再赘述。

    2.ZuulFilter类

    @Component
    public class MyZuulFilter extends ZuulFilter {
    
        @Override
        public String filterType() {
            return FilterConstants.PRE_TYPE;
        }
    
        @Override
        public int filterOrder() {
            return FilterConstants.PRE_DECORATION_FILTER_ORDER-1;
        }
    
        @Override
        public boolean shouldFilter() {
            return true;
        }
    
        @Override
        public Object run() throws ZuulException {
            System.out.println("pre过滤器=============");
    
            RequestContext requestContext = new RequestContext();
            HttpServletRequest request = requestContext.getRequest();
            String access = request.getParameter("access-token");
            if(!StringUtils.isBlank(access)){
                requestContext.setSendZuulResponse(false);
                requestContext.setResponseStatusCode(HttpStatus.SC_METHOD_NOT_ALLOWED);
            }
            return null;
        }
    }
    

    ZuulFilter里面有四个抽象方法必须被重写,

    • filterType:过滤类型,有pre(前置过滤)、post(后置过滤)、routing(业务代码前过滤)、error(异常过滤器),一个过滤器只属于一种类型;
    • filterOrder:过滤器的执行优先级,数值最小的先被执行;
    • shouldFilter:是否开启过滤器,返回值为boolean类型;
    • run:过滤器中需要执行的业务代码;

    只要把该类@Component一下就生效了,很简单。

    Zuul由动态读取、编译和执行Filter框架的能力,每个Filter之间没有直接联系,但都可以通过RequestContext共享一些状态数据。

    3.测试结果
    输入http://127.0.0.1:9093/user-service/user?access-token=1发现可以请求成功

    image.png
    输入http://127.0.0.1:9093/user-service/user请求返回405
    image.png

    四.Zuul的回退机制和高可用
    1.通过实现FallbackProvider 接口可以实现Zuul的容错与回退功能,详细参考https://blog.csdn.net/qq_27384769/article/details/82991261这篇文章;

    2.作为网关这么重要的角色,实现高可用是非常必要的,一般在Zuul网关之前我们会加一个nginx,利用nginx实现负载均衡和高可用,或者客户端的请求先向Eureka Server获取网关地址的方式实现。

    参考文章:

    参考1:https://www.jianshu.com/p/174cbb706c39
    参考2:https://www.cnblogs.com/duanxz/p/7527765.html
    参考3:https://blog.csdn.net/qq_27384769/article/details/82991261
    参考4:https://www.cnblogs.com/tripleDemo/p/11649966.html
    参考5,源码:https://segmentfault.com/a/1190000015915402

    相关文章

      网友评论

          本文标题:Zuul路由网关与过滤器

          本文链接:https://www.haomeiwen.com/subject/iqhszctx.html