• springcloud-zuul进阶篇


    一 前言

    经过zuul初级篇(博客或者公主号springcloud专栏可以找到)的学习,读者都懂得如何简单的使用zuul进行路由网关配置,在进阶篇中你将获得zuul核心功能过滤器的基本使用,通过zuul实现文件上传等;

    二管理端点

    默认情况下使用@EnableZuulProxy注解和 Spring Boot Actuator集成方式会有两个端点 RoutesFilters

    2.1 zuul-server

    在zuul-server中添加依赖actuator

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    

    在 application.yml中添加配置如下,开启routes端点

    management:
      endpoints:
        web:
          exposure:
            include: routes,filters
    

    启动 eureka-server, zuul-server;

    2.2 ruotes端点

    访问地址http://localhost:8100/actuator/routes 可以查看如下结果,表明集成成功;

    {
    /api/**: "zuul-client",
    /eureka-server-cluster/**: "eureka-server-cluster",
    /zuul-client/**: "zuul-client"
    }
    

    还可以详细的查看routes 端点具体的内容;访问地址 http://localhost:8100/actuator/routes/details 可以查看到如下内容;

    {
    	"/api/**": {
    		"id": "zuul-client",
    		"fullPath": "/api/**",
    		"location": "zuul-client",
    		"path": "/**",
    		"prefix": "/api",
    		"retryable": false,
    		"customSensitiveHeaders": false,
    		"prefixStripped": true
    	},
    	"/eureka-server-cluster/**": {
    		"id": "eureka-server-cluster",
    		"fullPath": "/eureka-server-cluster/**",
    		"location": "eureka-server-cluster",
    		"path": "/**",
    		"prefix": "/eureka-server-cluster",
    		"retryable": false,
    		"customSensitiveHeaders": false,
    		"prefixStripped": true
    	},
    	"/zuul-client/**": {
    		"id": "zuul-client",
    		"fullPath": "/zuul-client/**",
    		"location": "zuul-client",
    		"path": "/**",
    		"prefix": "/zuul-client",
    		"retryable": false,
    		"customSensitiveHeaders": false,
    		"prefixStripped": true
    	}
    }
    

    2.3 filter端点

    访问地址http://localhost:8100/actuator/filters 可以的到具体过滤器信息如下;每个过滤器模块中具体包含哪些具体过滤器请读者看返回结果;

    1. error 过滤器
    2. post 过滤器
    3. pre 过滤器
    4. route 过滤器
    {
    	"error": [{
    		"class": "org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter",
    		"order": 0,
    		"disabled": false,
    		"static": true
    	}],
    	"post": [{
    		"class": "org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter",
    		"order": 1000,
    		"disabled": false,
    		"static": true
    	}],
    	"pre": [{
    		"class": "org.springframework.cloud.netflix.zuul.filters.pre.DebugFilter",
    		"order": 1,
    		"disabled": false,
    		"static": true
    	}, {
    		"class": "org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilter",
    		"order": -1,
    		"disabled": false,
    		"static": true
    	}, {
    		"class": "org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter",
    		"order": -2,
    		"disabled": false,
    		"static": true
    	}, {
    		"class": "org.springframework.cloud.netflix.zuul.filters.pre.ServletDetectionFilter",
    		"order": -3,
    		"disabled": false,
    		"static": true
    	}, {
    		"class": "org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter",
    		"order": 5,
    		"disabled": false,
    		"static": true
    	}],
    	"route": [{
    		"class": "org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter",
    		"order": 100,
    		"disabled": false,
    		"static": true
    	}, {
    		"class": "org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter",
    		"order": 10,
    		"disabled": false,
    		"static": true
    	}, {
    		"class": "org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter",
    		"order": 500,
    		"disabled": false,
    		"static": true
    	}]
    }
    

    三 过滤器

    3.1 过滤器特征

    在zuul的request和response工作过程的核心就是以过滤器为基础执行一系列的动作;zuul的核心特色如下

    1. Type : 过滤器类型定义了在路由期间过滤器被执行的顺序;
    2. Execution Order: 同一类型的过滤器中,能够定义多个过滤器的执行顺序;
    3. Criteria: 过滤器被执行的条件;
    4. Action: 过滤条件满足情况下,被执行的动作;

    zuul 提供了一个框架去动态的读取,编译,和运行过滤器;过滤器之间的交流机制是通过RequestContext 进行分享各自的状态;RequestContext 中有各自独立的 request (request 由 ThreadLocal 持有) 进行 存储数据;每个ThreadLocal 都会负责各自请求信息,错误信息,真实的 HttpServletRequestHttpServletResponse;RequestContext 扩展于 ConcurrentHashMap ,所以任何的信息基本都能存储;

    3.2 过滤器类型

    过滤器类型就对应了 zuul Request 的整个生命周期,具体的流程可以参照来自zuul官网下图;

    1. PRE 过滤器 在 routing 到 origin 之前执行;主要包括请求认证,选择origin server , debug日志信息;
    2. ROUTING 过滤器 在 routing 到 origin 之间执行; 建立和发送亲求,支持Apache HttpClient 和 Netflix Ribbon
    3. POST 过滤器 在 routing 到 origin 之后 执行;处理响应信息,比如添加响应头,收集统计信息和指标,将响应输送给客户端;
    4. ERROR 过滤器,当发生异常时就会执行;

    3.3 自定义filter

    自定义filter需要实现 ZuulFilter ;主要实现方法如下

    1. filterOrder 定义过滤器执行顺序;官网默认不同的过滤器顺序如下 PRE_DECORATION_FILTER_ORDERSIMPLE_HOST_ROUTING_FILTER_ORDER, PRE_DECORATION_FILTER_ORDER
    2. filterType 定义过滤器类型;通常就是 PRE_TYPE , ROUTE_TYPE, POST_TYPE
    3. shouldFilter 判定是否执行过滤器
    4. run 执行过滤器

    如下代码中是一个PRE过滤器,简单实现了个业务逻辑,对请求的信息进行日志跟踪,获得request上下文进行自定义业务逻辑操作;

    /**
     * @Author lsc
     * <p> 前置过滤器示例 </p>
     */
    @Component
    public class QueryParamPreFilter extends ZuulFilter {
    
        private Logger logger = LoggerFactory.getLogger(this.getClass());
    
        @Override
        public String filterType() {
            return  PRE_TYPE;
        }
    
        @Override
        public int filterOrder() {
            return PRE_DECORATION_FILTER_ORDER - 1;
        }
    
        @Override
        public boolean shouldFilter() {
            // 读者可以拿到请求上下文做业务判断是否执行过滤器
           return true;
        }
    
        @Override
        public Object run() throws ZuulException {
            System.out.println("----pre filter  be excuted");
            //// 获得当前request 请求上下文
            RequestContext ctx = RequestContext.getCurrentContext();
            // 获得 request
            HttpServletRequest request = ctx.getRequest();
            // 获得远程主机 ip
            String remoteHost = request.getRemoteHost();
            // 获得请求参数
            String username = request.getParameter("username");
            // 打印日志信息
            logger.info("the remote host is {} and params is {}",remoteHost,username);
            // 设置 key
            if (username!=null){
                ctx.put("zszxz", "you can set service");
            }
            return null;
        }
    }
    

    执行结果

    ----pre filter  be excuted
    2020-01-30 17:40:22.472  INFO 20792 --- [nio-8100-exec-4] c.z.z.server.filter.QueryParamPreFilter  : the remote host is 0:0:0:0:0:0:0:1 and params is zszxz
    
    

    四文件上传

    4.1 application.yml

    在实现文件上传之前需要给配置文件中zuul加上超时设置,和文件大小限制

    spring:
      application:
        name: zuul-server # 应用名称
      servlet:
        multipart:
          max-file-size: 200MB #单个文件上传大小
          max-request-size: 600MB #连续上传文件大小
          location: / #临时目录
          
    # hystrix 超时设置
    hystrix:
      command:
        default:
          execution:
            isolation:
              thread:
                timeoutInMilliseconds: 60000
                
    # ribbon 超时设置
    ribbon:
      ConnectTimeout: 3000
      ReadTimeout: 60000
      
    

    4.2 controller

    以下是一个简单的文件上传示例;

    /**
     * @Author lsc
     * <p>zuul文件上传 </p>
     */
    @RestController
    public class ZuulFileUploadController {
    
        @PostMapping("/file/upload")
        public String fileUpload(@RequestParam("file") MultipartFile file) throws IOException {
            // 上传简单文件名
            String originalFilename = file.getOriginalFilename();
            byte[] bytes = file.getBytes();
            File saveFile = new File(originalFilename);
            FileCopyUtils.copy(bytes,saveFile);
            return saveFile.getAbsolutePath();
        }
    }
    

    4.3 测试

    简单的通过postman测试如下,正确的返回了图片所在的路径;

    五 参考文档

    Netflix-zuul https://github.com/Netflix/zuul/

    springcloud官方文档 https://cloud.spring.io/spring-cloud-static/Finchley.SR4/single/spring-cloud.html

  • 相关阅读:
    在 Java SE 6 中监视和诊断性能问题
    Codeforces Round #491 (Div. 2)部分题解
    BZOJ1607: [Usaco2008 Dec]Patting Heads 轻拍牛头(模拟 调和级数)
    BZOj1261: [SCOI2006]zh_tree(dp)
    BZOJ1569: [JSOI2008]Blue Mary的职员分配(dp 暴力)
    BZOJ4300: 绝世好题(dp)
    树上莫队算法
    SPOJ COT2
    BZOJ1086: [SCOI2005]王室联邦(贪心,分块?)
    Educational Codeforces Round 42 (Rated for Div. 2)
  • 原文地址:https://www.cnblogs.com/zszxz/p/12244920.html
Copyright © 2020-2023  润新知