• zuul路由网关


      zuul作为网关组件,主要用来管理api请求接口(统一对外暴露,负载均衡),身份认证,流量监控等。它是通过servlet来实现的,核心是一系列过滤器,可以在请求的发起跟相应返回阶段进行一系列的处理。
    ------------------------------------------------------------------------------------------------------------------------
    原理简介
      过滤器分类:
        PRE过滤器:在请求路由到具体的服务之前执行,可以用作安全验证,例如身份验证,参数验证等;
        ROUTING过滤器:用于将请求路由到具体的微服务实例,默认情况下使用http client进行网络请求;
        POST过滤器:在请求被路由到微服务后执行,一般用作收集统计信息,及将响应传输到客户端;
        ERROR过滤器:在其他过滤器发生错误时执行;
      zuul采用了动态读取、编译和运行这些过滤器。过滤器之间不能直接通信,而是通过RequestContext对象共享数据,每个请求都会创建一个RequestContext对象。zuul请求的生命周期如图:
     
      request请求进入zuul网关后,先进入pre 类别的过滤器,进行一系列验证操作或判断,然后交给routing filter进行路由转发,转发到具体的微服务实例进行逻辑处理并返回数据;当具体的服务处理完成后,最后又post filters进行处理,该类型的过滤器处理完成后,将response信息返回给客户端。
    demo搭建
      pom主要内容:
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zuul</artifactId>
    </dependency>
    
      zuul功能开启:
      在启动类加注解@EnableZuulProxy跟@EnableEurekaClient,启用相应功能。
      yml文件配置:
    server:
      port: 5000
    spring:
      application:
        name: zuul-demo
    eureka:
      client:
        registerWithEureka: true
        fetchRegistry: true
        serverUrl:
          defaultZone: http://127.0.0.1:8761/eureka
    zuul:
      routes:
        smsapi:
          path: /sms/**
          serviceId: sms-module
        consumerapi:
          path: /consumertest/**
          serviceId: consumer-module
     
      routes下的smsapi是路由名字,随便起,可以配置多个,每个要配相应的规则。path表示要匹配的url路径,/sms/**表示匹配包含sms的url,将其路由到sms-module服务。第二个consumerapi是路由名,path跟serviceId同上。配置完成后,我们分别启动eureka-server,跟两个服务sms-module跟consumertest,其中sms-module启用三个实例(只需要启动一个服务多个实例即可测试)。
    zuul默认结合ribbon的负载均衡测试:
      各个服务启动后服务实例信息如下:
     
       访问zuul进行测试,可以看到能正常返回结果:
     
       url中包含两个sms的原因是sms-module的controller的RequestMapping为sms:
     
       多次访问,可以发现zuul对sms-module的请求会分到不同的实例中,说明zuul默认集成了ribbon做了负载均衡处理。
    自定义过滤器测试:
      既然zuul的主要功能之一是对请求进行拦截校验,那我们就做一个对请求进行校验的例子。比如很多网站都有token授权,我们不做token授权,做一个对url参数进行校验的filter,原理是类似的。
      filter代码:
    @Component
    public class MyFilter extends ZuulFilter {
        @Override
        public String filterType() {
            return FilterConstants.PRE_TYPE;
        }
        @Override
        public int filterOrder() {
            return 0;
        }
        //是否走过滤逻辑
        @Override
        public boolean shouldFilter() {
            return true;
        }
        //判断url中是否包含参数testParam,不包含则拦截请求
        @Override
        public Object run() {
            RequestContext ctx = RequestContext.getCurrentContext();
            HttpServletRequest request = ctx.getRequest();
            String testParam = request.getParameter("testParam");
            if( null == testParam){
                System.out.println("缺失关键参数,驳回请求");
                ctx.setSendZuulResponse(false);//是否把该请求转发给具体服务
                ctx.setResponseStatusCode(401);
                try {
                    ctx.getResponse().getWriter().write("qing  jiancha  canshu  shifou  wanzheng");
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }
            return null;
        }
    }
    
      自定义过滤器只需要继承ZuulFilter并实现4个方法即可。四个方法解释:
        filterType:同开头的过滤器分类,分为4中过滤器。
        filterOrder:执行顺序或者优先级,返回int数值,数值越小优先级越高。
        shoudlFilter:是否走过滤器逻辑,true则会走run方法,false不会。
        run:过滤器主要逻辑处理方法。
      还是同样的请求,发现添加过滤器后被拦截了:
      加上参数后再次请求,可以通过并返回正常数据:
     
    熔断器测试:
      zuul作为netflix的组件,可以与hystrix结合实现熔断器功能,zuul实现熔断功能需要实现ZuulFallbackProvider接口。该接口有两个方法:
      getRoute:用于指导熔断功能用于哪些微服务;
      fallbackResponse:进入熔断功能时只需的逻辑;
      代码:
    @Component
    public class MyFallbackProvider implements ZuulFallbackProvider {
        @Override
        public String getRoute() {
            return "sms-module"; //匹配所有,用“*”
        }
        @Override
        public ClientHttpResponse fallbackResponse() {
            return new ClientHttpResponse() {
                @Override
                public HttpStatus getStatusCode() throws IOException {return HttpStatus.OK;}
                @Override
                public int getRawStatusCode() throws IOException {return 200;}
                @Override
                public String getStatusText() throws IOException { return "OK";}
                @Override
                public void close() {}
                @Override
                public InputStream getBody() throws IOException {
                    return new ByteArrayInputStream("{"msg":"error, 少年,你的程序出异常了,这里是失败回调函数"}".getBytes());
    //                return new ByteArrayInputStream("少年,你的程序出异常了,这里是失败回调函数".getBytes());
                }
                @Override
                public HttpHeaders getHeaders() {
                    HttpHeaders headers = new HttpHeaders();
                    headers.setContentType(MediaType.APPLICATION_JSON);
                    return headers;
                }
            };
        }
    }
       停掉sms-module的相关实例,再次访问:
     
    ------------------------------------------------------------------------------------------------------------------------
    这样吧先。

  • 相关阅读:
    《Java多线程编程核心技术》读后感(五)
    《Java多线程编程核心技术》读后感(四)
    《Java多线程编程核心技术》读后感(三)
    《Java多线程编程核心技术》读后感(二)
    《Java多线程编程核心技术》读后感(一)
    使用httpClient下载网页
    HrrpClient使用
    爬虫基本结构
    仿响应式html:JS来判断页面是在手机端还是在PC端打开的方法
    Python 进程管理工具 Supervisor 使用教程
  • 原文地址:https://www.cnblogs.com/nevermorewang/p/9346730.html
Copyright © 2020-2023  润新知