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 插件的使用 进阶篇(个人收集 ...
随机推荐
- 你了解真正的 restful API 吗?
本文原创地址,博客:https://jsbintask.cn/2019/03/20/api/restful-api-best-practices/(食用效果最佳),转载请注明出处! 前言 在以前,一个 ...
- Pandas 记录
过滤不为空的数据 df[df['PLANR']==''] 获取某列某行数据(某个单元格数据) df['MNG02'][0] 根据判断条件筛选数据 df[df['DAT00'] < temp_ti ...
- 3、高级方法(Advanced Recipes)
学习目录:树莓派学习之路-GPIO Zero 官网地址:https://gpiozero.readthedocs.io/en/stable/recipes_advanced.html 环境:Ubunt ...
- 吴裕雄 python 机器学习——模型选择参数优化暴力搜索寻优GridSearchCV模型
import scipy from sklearn.datasets import load_digits from sklearn.metrics import classification_rep ...
- easyapi用法
https://www.easyapi.com/api/?documentId=1773&themeId=
- jdk rpm安装实现
wget https://download.oracle.com/otn/java/jdk/8u211-b12/478a62b7d4e34b78b671c754eaaf38ab/jdk-8u211 ...
- JDK8;HashMap:再散列解决hash冲突 ,源码分析和分析思路
JDK8中的HashMap相对JDK7中的HashMap做了些优化. 接下来先通过官方的英文注释探究新HashMap的散列怎么实现 先不给源码,因为直接看源码肯定会晕,那么我们先从简单的概念先讲起 ...
- 《Web安全攻防 渗透测试实战指南 》 学习笔记 (五)
Web安全攻防 渗透测试实战指南 学习笔记 (五) 第四章 Web安全原理解析 (一) (一)SQL注入的原理 1.web应用程序对用户输入数据的合法性没有判断. 2.参数用户可控:前端传给 ...
- django之路由分组,路由分发,FBV,CBV,ORM框架
今日的内容: a. 路由系统 1. 创建app 2. 路由的分组 3. 路由的分发 - 正则表达式匹配 b. django的orm(模型model) 1. 创建模型的步骤 2. orm基本的增删改查 ...
- python3.8的PySimpleGUI学习的温度转换(℃转℉)
一.代码1: #导出模块 import PySimpleGUI as sg #总体布局,sg.InputText(),默认size=(45,1). layout = [ [sg.Text('Celci ...