一 前言

经过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

springcloud-zuul进阶篇的更多相关文章

  1. 白话SpringCloud | 第十章:路由网关(Zuul)进阶:过滤器、异常处理

    前言 简单介绍了关于Zuul的一些简单使用以及一些路由规则的简单说明.而对于一个统一网关而言,需要处理各种各类的请求,对不同的url进行拦截,或者对调用服务的异常进行二次处理等等.今天,我们就来了解下 ...

  2. springcloud(十一):服务网关Zuul高级篇

    时间过的很快,写springcloud(十):服务网关zuul初级篇还在半年前,现在已经是2018年了,我们继续探讨Zuul更高级的使用方式. 上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制 ...

  3. 跟我学SpringCloud | 第十篇:服务网关Zuul高级篇

    SpringCloud系列教程 | 第十篇:服务网关Zuul高级篇 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如无特殊说明,本系列教程全 ...

  4. 跟我学SpringCloud | 第十七篇:服务网关Zuul基于Apollo动态路由

    目录 SpringCloud系列教程 | 第十七篇:服务网关Zuul基于Apollo动态路由 Apollo概述 Apollo相比于Spring Cloud Config优势 工程实战 示例代码 Spr ...

  5. Spring+SpringMVC+MyBatis+easyUI整合进阶篇(十五)阶段总结

    作者:13 GitHub:https://github.com/ZHENFENG13 版权声明:本文为原创文章,未经允许不得转载. 一 每个阶段在结尾时都会有一个阶段总结,在<SSM整合基础篇& ...

  6. 跟我学SpringCloud | 第三篇:服务的提供与Feign调用

    跟我学SpringCloud | 第三篇:服务的提供与Feign调用 上一篇,我们介绍了注册中心的搭建,包括集群环境吓注册中心的搭建,这篇文章介绍一下如何使用注册中心,创建一个服务的提供者,使用一个简 ...

  7. 跟我学SpringCloud | 第十三篇:Spring Cloud Gateway服务化和过滤器

    SpringCloud系列教程 | 第十三篇:Spring Cloud Gateway服务化和过滤器 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich. ...

  8. Membership三步曲之进阶篇 - 深入剖析Provider Model

    Membership 三步曲之进阶篇 - 深入剖析Provider Model 本文的目标是让每一个人都知道Provider Model 是什么,并且能灵活的在自己的项目中使用它. Membershi ...

  9. idea 插件的使用 进阶篇

    CSDN 2016博客之星评选结果公布    [系列直播]零基础学习微信小程序!      "我的2016"主题征文活动   博客的神秘功能 idea 插件的使用 进阶篇(个人收集 ...

随机推荐

  1. C++之void是什么?

    void关键字的使用规则: 1. 如果函数没有返回值,那么应声明为void类型: 2. 如果函数无参数,那么应声明其参数为void: 3. 如果函数的参数可以是任意类型指针,那么应声明其参数为void ...

  2. Idea 工具快捷合集

    官方下载地址 https://www.jetbrains.com/idea/download/#section=windows 商业版 与 社区版,商业版具有更多的功能 快捷一.修改 terminal ...

  3. 计算机二级-C语言-程序设计题-190119记录-求出一个二维数组每一列的最小值。

    //编写一个函数:tt指向一个M行N列的二维数组,求出二维数组每列中最小的元素,并依次放入pp所指的一维数组中.二维数组中的数在主函数中赋予. //重难点:求出的是每一列的最小值,这里要注意,学会简化 ...

  4. 大端(bigend)与小端(littleend)

                                      大端:是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中: 小端:是指数据的高位保存在内存的高地址中,而数据的高 ...

  5. 域名和URL各部分组成

    什么是域名? 域名,是由一串用点分隔的名字组成的Internet上某一台计算机或计算机组的名称,用于在数据传 输时标识计算机的电子方位. IP地址是Internet主机的作为路由寻址用的数字型标识,人 ...

  6. 《如何写好商业计划书》---创业学习---训练营第三课---HHR---

    一,<开始上课> 1,投资人不愿意约见的原因:创始人没有把项目的投资价值和亮点呈现在商业计划书里. 2,BP的三个常见的错误:不够完整,关键内容没有呈现出来:华而不实:篇幅过长. 3,预热 ...

  7. bootstrap与vue,react的区别

    链接(与Vue区别):https://www.php.cn/faq/423095.html 链接(BootStrap, React, Vue的比较):https://www.jianshu.com/p ...

  8. ES6-const定义常量

    在es5中我们一般将变量名大写来表明这是一个常量,但其实它是可以修改的. 在es6中可以用const来定义常量,它定义的常量不能修改.     const NAME = 'tom';     NAME ...

  9. ubuntu16.04安装node.js、npm

    ubuntu16.04安装node.js.npm1.请尽量避免在 Ubuntu 上使用 apt-get 来安装 node.js, 如果你已经这么做了,请手动移除: sudo apt-get purge ...

  10. Pandas的Categorical Data类型

    pandas从0.15版开始提供分类数据类型,用于表示统计学里有限且唯一性数据集,例如描述个人信息的性别一般就男和女两个数据常用'm'和'f'来描述,有时也能对应编码映射为0和1.血型A.B.O和AB ...