springcloud-zuul进阶篇
一 前言
经过zuul初级篇(博客或者公主号springcloud专栏可以找到)的学习,读者都懂得如何简单的使用zuul进行路由网关配置,在进阶篇中你将获得zuul核心功能过滤器的基本使用,通过zuul实现文件上传等;
二管理端点
默认情况下使用@EnableZuulProxy注解和 Spring Boot Actuator集成方式会有两个端点 Routes
和 Filters
;
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 可以的到具体过滤器信息如下;每个过滤器模块中具体包含哪些具体过滤器请读者看返回结果;
- error 过滤器
- post 过滤器
- pre 过滤器
- 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的核心特色如下
- Type : 过滤器类型定义了在路由期间过滤器被执行的顺序;
- Execution Order: 同一类型的过滤器中,能够定义多个过滤器的执行顺序;
- Criteria: 过滤器被执行的条件;
- Action: 过滤条件满足情况下,被执行的动作;
zuul 提供了一个框架去动态的读取,编译,和运行过滤器;过滤器之间的交流机制是通过RequestContext
进行分享各自的状态;RequestContext
中有各自独立的 request
(request 由 ThreadLocal 持有) 进行 存储数据;每个ThreadLocal 都会负责各自请求信息,错误信息,真实的 HttpServletRequest
和 HttpServletResponse
;RequestContext 扩展于 ConcurrentHashMap
,所以任何的信息基本都能存储;
3.2 过滤器类型
过滤器类型就对应了 zuul Request 的整个生命周期,具体的流程可以参照来自zuul官网下图;
- PRE 过滤器 在 routing 到 origin 之前执行;主要包括请求认证,选择origin server , debug日志信息;
- ROUTING 过滤器 在 routing 到 origin 之间执行; 建立和发送亲求,支持Apache HttpClient 和 Netflix Ribbon
- POST 过滤器 在 routing 到 origin 之后 执行;处理响应信息,比如添加响应头,收集统计信息和指标,将响应输送给客户端;
- ERROR 过滤器,当发生异常时就会执行;
3.3 自定义filter
自定义filter需要实现 ZuulFilter
;主要实现方法如下
- filterOrder 定义过滤器执行顺序;官网默认不同的过滤器顺序如下
PRE_DECORATION_FILTER_ORDER
,SIMPLE_HOST_ROUTING_FILTER_ORDER
,PRE_DECORATION_FILTER_ORDER
- filterType 定义过滤器类型;通常就是
PRE_TYPE
,ROUTE_TYPE
,POST_TYPE
- shouldFilter 判定是否执行过滤器
- 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进阶篇的更多相关文章
- 白话SpringCloud | 第十章:路由网关(Zuul)进阶:过滤器、异常处理
前言 简单介绍了关于Zuul的一些简单使用以及一些路由规则的简单说明.而对于一个统一网关而言,需要处理各种各类的请求,对不同的url进行拦截,或者对调用服务的异常进行二次处理等等.今天,我们就来了解下 ...
- springcloud(十一):服务网关Zuul高级篇
时间过的很快,写springcloud(十):服务网关zuul初级篇还在半年前,现在已经是2018年了,我们继续探讨Zuul更高级的使用方式. 上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制 ...
- 跟我学SpringCloud | 第十篇:服务网关Zuul高级篇
SpringCloud系列教程 | 第十篇:服务网关Zuul高级篇 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如无特殊说明,本系列教程全 ...
- 跟我学SpringCloud | 第十七篇:服务网关Zuul基于Apollo动态路由
目录 SpringCloud系列教程 | 第十七篇:服务网关Zuul基于Apollo动态路由 Apollo概述 Apollo相比于Spring Cloud Config优势 工程实战 示例代码 Spr ...
- Spring+SpringMVC+MyBatis+easyUI整合进阶篇(十五)阶段总结
作者:13 GitHub:https://github.com/ZHENFENG13 版权声明:本文为原创文章,未经允许不得转载. 一 每个阶段在结尾时都会有一个阶段总结,在<SSM整合基础篇& ...
- 跟我学SpringCloud | 第三篇:服务的提供与Feign调用
跟我学SpringCloud | 第三篇:服务的提供与Feign调用 上一篇,我们介绍了注册中心的搭建,包括集群环境吓注册中心的搭建,这篇文章介绍一下如何使用注册中心,创建一个服务的提供者,使用一个简 ...
- 跟我学SpringCloud | 第十三篇:Spring Cloud Gateway服务化和过滤器
SpringCloud系列教程 | 第十三篇:Spring Cloud Gateway服务化和过滤器 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich. ...
- Membership三步曲之进阶篇 - 深入剖析Provider Model
Membership 三步曲之进阶篇 - 深入剖析Provider Model 本文的目标是让每一个人都知道Provider Model 是什么,并且能灵活的在自己的项目中使用它. Membershi ...
- idea 插件的使用 进阶篇
CSDN 2016博客之星评选结果公布 [系列直播]零基础学习微信小程序! "我的2016"主题征文活动 博客的神秘功能 idea 插件的使用 进阶篇(个人收集 ...
随机推荐
- C++之void是什么?
void关键字的使用规则: 1. 如果函数没有返回值,那么应声明为void类型: 2. 如果函数无参数,那么应声明其参数为void: 3. 如果函数的参数可以是任意类型指针,那么应声明其参数为void ...
- Idea 工具快捷合集
官方下载地址 https://www.jetbrains.com/idea/download/#section=windows 商业版 与 社区版,商业版具有更多的功能 快捷一.修改 terminal ...
- 计算机二级-C语言-程序设计题-190119记录-求出一个二维数组每一列的最小值。
//编写一个函数:tt指向一个M行N列的二维数组,求出二维数组每列中最小的元素,并依次放入pp所指的一维数组中.二维数组中的数在主函数中赋予. //重难点:求出的是每一列的最小值,这里要注意,学会简化 ...
- 大端(bigend)与小端(littleend)
大端:是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中: 小端:是指数据的高位保存在内存的高地址中,而数据的高 ...
- 域名和URL各部分组成
什么是域名? 域名,是由一串用点分隔的名字组成的Internet上某一台计算机或计算机组的名称,用于在数据传 输时标识计算机的电子方位. IP地址是Internet主机的作为路由寻址用的数字型标识,人 ...
- 《如何写好商业计划书》---创业学习---训练营第三课---HHR---
一,<开始上课> 1,投资人不愿意约见的原因:创始人没有把项目的投资价值和亮点呈现在商业计划书里. 2,BP的三个常见的错误:不够完整,关键内容没有呈现出来:华而不实:篇幅过长. 3,预热 ...
- bootstrap与vue,react的区别
链接(与Vue区别):https://www.php.cn/faq/423095.html 链接(BootStrap, React, Vue的比较):https://www.jianshu.com/p ...
- ES6-const定义常量
在es5中我们一般将变量名大写来表明这是一个常量,但其实它是可以修改的. 在es6中可以用const来定义常量,它定义的常量不能修改. const NAME = 'tom'; NAME ...
- ubuntu16.04安装node.js、npm
ubuntu16.04安装node.js.npm1.请尽量避免在 Ubuntu 上使用 apt-get 来安装 node.js, 如果你已经这么做了,请手动移除: sudo apt-get purge ...
- Pandas的Categorical Data类型
pandas从0.15版开始提供分类数据类型,用于表示统计学里有限且唯一性数据集,例如描述个人信息的性别一般就男和女两个数据常用'm'和'f'来描述,有时也能对应编码映射为0和1.血型A.B.O和AB ...