转自:https://blog.csdn.net/pengjunlee/article/details/87162192

自定义路由规则

在《API Gateway 的路由和过滤(Zuul)》一章中,我们并未对Zuul的路由规则进行设置,默认会使用服务的 ID 对服务进行路由,即:在源服务的URI之前增加 /service-id 前缀。

# Zuul 默认路由地址
http://<zuul-host>:<zuul-port>/service-id/[service-URI]

除了可以直接使用默认的路由规则外,Zuul还提供了很多配置项允许我们对路由映射规则进行自定义,例如:

zuul:
ignoredServices: '*'
routes:
message-service: /zuul-msg/**

示例中这个配置的作用是:忽略除 message-service 外的所有服务(不对它们进行路由),只将message-service 服务路由到 /zuul-msg/** 地址上。

zuul.ignored-services  # 忽略指定微服务,多个微服务之间使用逗号分隔
zuul.routes.service-id # 指定service-id服务的路由地址

注意:在 zuul.routes 中配置了的服务,即使被包含在 zuul.ignored-services 配置中也不会被忽略。

若将上例中的配置改成如下,则表示除 message-service 外的所有服务都使用默认的路由规则。

zuul:
routes:
message-service: /zuul-msg/**

如果你希望对某一个路由进行更精细的控制,可以独立地指定该服务的路由地址和它的service-id,例如:

zuul:
routes:
message:
path: /zuul-msg/**
serviceId: message-service

或者,像下面这样指定一个该服务的物理地址来替代上例中的service-id:

zuul:
routes:
message:
path: /zuul-msg/**
url: http://localhost:8771/

连续多次访问 http://localhost:8791/zuul-msg/api/v1/msg/get 返回结果相同,见下图:

可以看出,通过url配置的路由不会被当作HystrixCommand执行,自然也就不会使用Ribbon在多个Url之间进行负载均衡。所以,推荐使用serviceId进行配置。或者,指定一个包含有多个可用服务列表的serviceId,例如:

zuul:
routes:
message:
path: /zuul-msg/**
serviceId: msg-servers hystrix:
command:
msg-servers:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000 msg-servers:
ribbon:
NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
listOfServers: http://localhost:8771/,http://localhost:8772/
ConnectTimeout: 1000
ReadTimeout: 3000
MaxTotalHttpConnections: 500
MaxConnectionsPerHost: 100

还有另外一种方法也可以达到上述目标:使用service-id为要路由的服务指定一个Ribbon客户端,并设置Ribbon禁用Eureka,例如:

zuul:
routes:
message:
path: /zuul-msg/**
serviceId: msg-servers ribbon:
eureka:
enabled: false msg-servers:
ribbon:
listOfServers: http://localhost:8771/,http://localhost:8772/

如果你的service-id命名满足一定的规则,可以使用正则表达式从service-id中提取一些变量作为你的路由地址,例如:

	@Bean
public PatternServiceRouteMapper serviceRouteMapper() {
return new PatternServiceRouteMapper("(?<name>^.+)-(?<version>v.+$)", "${version}/${name}");
}

在这个示例中,一个名称为myusers-v1的服务会被路由到 /v1/myusers/** 地址上。在这里你可以使用任意正则表达式,但是要保证所有的命名组必须都包含servicePattern和routePattern两部分。如果servicePattern不匹配service-id,就会使用默认的规则,即在服务原有的URI之前增加 /service-id 前缀。Zuul的这一特性默认是关闭的,而且只能被应用到已经发现的服务。

对那些要忽略的微服务也可以采用模式匹配进行更加精细的控制,例如:

zuul:
ignoredPatterns: /**/v2/**
routes:
message-service: /zuul-msg/**

该例中的配置会忽略所有包含 /v2/ 的请求。

使用 zuul.prefix 配置项可以为所有的路由地址都添加一个前缀,例如 /abc 。

zuul:
prefix: /abc
routes:
message-service: /zuul-msg/** 

添加前缀之后路由地址为:http://localhost:8791/abc/zuul-msg/api/v1/msg/get 。

默认情况下,Zuul代理会在将请求转发出去之前先将其中的前缀字符串剔除掉。如果你不想剔除前缀,可以设置 zuul.stripPrefix=false。如果你只是想不剔除指定某一个服务中的前缀,可以使用如下配置:

zuul:
prefix: /abc
# stripPrefix: false
routes:
message-service: /zuul-msg/**
stripPrefix: false

zuul.routes 中的配置条目最终都会被绑定到一个ZuulProperties类型的对象,在 ZuulProperties 中还有一个 retryable 标识,将该标识设置成 ture 能够让Ribbon客户端对失败的请求自动进行重试。

zuul.routes 中配置的路由地址最终都会被存储在一个Map中,路由的地址即为Map的key,Map的value是一个ZuulRoute类型的对象。在yaml配置文件中,路由地址相同的两个服务,后面的会覆盖前面的配置,从而导致先配置的服务不可用。

注意:如果需要保留路由的顺序,需要使用yaml文件,因为使用properties文件时会丢失顺序。

目前,Zuul已经使用 Apache HTTP Client 替换掉了已经过时的Ribbon RestClient 来作为自己的HTTP Client。你若想继续使用 RestClient 或者 okhttp3.OkHttpClient,只需要将 ribbon.restclient.enabled 或者 ribbon.okhttp.enabled 设置为 true 即可。当然,你也可以使用自定义的 Apache HTTP client 或者 OK HTTP client,提供一个相应的 ClosableHttpClient 或者OkHttpClient 类型的 Bean即可。

设置请求头

默认情况下,Zuul会为转发的请求添加一些 X-Forwarded-* 请求头,可以通过配置项 zuul.addProxyHeaders = false 来关闭它。请求中的前缀默认会被剔除,同样地,请求中的X-Forwarded-Prefix 请求头也会被摘取出来。

在同一个系统中,请求头在多个服务之间是可以共享的,但是你可能并不希望某些敏感的请求头信息泄露到下游的外部服务器,你可以把这些敏感请求头配置到zuul.sensitiveHeaders列表,从而禁止它们被传递到下游。例如:

zuul:
sensitiveHeaders: Cookie,Set-Cookie,Authorization
routes:
message-service: /zuul-msg/**
sensitiveHeaders: token

sensitiveHeaders就相当于是一个向下游传递的请求头黑名单,默认包含了 Cookie,Set-Cookie和Authorization三个请求头。因此,如果你需要向下传递所有的请求头信息,需要明确地把sensitiveHeaders设置成一个空列表,如下:

zuul:
sensitiveHeaders:
routes:
message-service: /zuul-msg/**

另外,你还可以把那些不需要传递到下游的请求头或响应头配置到 zuul.ignoredHeaders 中,可以达到相同的作用。默认情况下,当类路径中不包含 Spring Security 时,ignoredHeaders 列表是空的;当类路径中包含 Spring Security时,ignoredHeaders 列表会被初始化包含一些由Spring Security指定的 security 头信息,例如 involving caching。这种情况下如果你需要把这些 security 头信息传递到下游,可以添加 zuul.ignoreSecurityHeaders = false 配置项。

管理终端

默认情况下,当@EnableZuulProxy与Actuator一起使用时,Actuator健康监控页面会增加两个终端:Routes和Filters。

需要在pom.xml中引入Actuator依赖:

		<!-- Actuator 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

并在application.yml文件中增加配置:

management:
security:
enabled: false
endpoints:
web:
exposure:
include: hystrix.stream,*

访问 /actuator/routes 终端会返回一个映射路由的列表,如下图。

访问 /actuator/routes/details 终端会返回一个映射路由的详细信息列表,如下图。

访问 /actuator/filters 终端会返回一个包含了过滤器类型和配置的Map对象。

编码设置

  在对进来的请求进行处理的时候,请求参数会被解码以便在Zuul过滤器中能够对它们进行一些修改,然后又会在路由过滤器中重新编码并发送出去,重新编码后的结果跟原来的输入可能会有所不同,这在多数情况下是没什么问题的,但是在一些对复杂的请求字符串编码比较挑剔的Web服务器中仍有可能会出问题。解决的办法就是添加如下的配置来强制使用原始编码的请求字符串,相当于直接使用 HttpServletRequest.getQueryString()方法来获取请求字符串。

  在对进来的请求进行处理的时候,会先对请求的URI进行解码,再和路由地址进行匹配,然后又会在路由过滤器中对请求的URI重新编码并发送给后端,当你的URI中包含 “/” 字符时这可能会引发一些意想不到的问题。解决的办法就是添加如下的配置来强制使用原始编码的请求URI,相当于直接使用 HttpServletRequest.getRequestURI()方法来获取请求URI。

禁用Zuul过滤器

Spring Cloud的Zuul自带了一些过滤器Bean,默认情况下它们都是启用的。如果你想禁用其中的某一个过滤器,可以使用如下配置: 

zuul.<SimpleClassName>.<filterType>.disable=true

按照惯例,过滤器所在包名中 “filters” 字符串后面的就是过滤器的类型了,例如,禁用 org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter ,配置如下:

zuul.SendResponseFilter.post.disable=true

超时设置

如果你需要设置通过Zuul路由的请求的Socket超时时间和Read超时时间,有两种配置方法,需要根据你的配置情况进行选择:

如果使用了服务发现,使用ribbon.ReadTimeout 和 ribbon.SocketTimeout 进行配置。

如果是通过指定URL的方式进行路由,使用zuul.host.connect-timeout-millis 和 zuul.host.socket-timeout-millis进行配置。

参考文章
https://github.com/spring-projects/spring-retry

https://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html#netflix-zuul-starter

【springcloud】Zuul高级配置(zuul--2)的更多相关文章

  1. 【springcloud】Zuul高级配置(zuul--3)

    转自:https://blog.csdn.net/pengjunlee/article/details/87285673 为路由提供HystrixFallback 当Zuul中某一个路由的断路器被断开 ...

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

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

  3. SpringCloud:Zuul路由配置超时问题

    测试访问时长 修改下业务类,增加sleep休眠时长,以此查看Zuul的熔断 @GetMapping("/test1") public Object test1() { try { ...

  4. SpringCloud:路由ZUUL的配置详解

    以下是两种配置文件的配置方式,可以根据需要选取对自己项目有利的配置. 自定义访问路径(path) 配置application.yml文件 #provider-user:是你的微服务模块的名称,及spr ...

  5. ⑤SpringCloud 实战:引入Zuul组件,开启网关路由

    这是SpringCloud实战系列中第4篇文章,了解前面第两篇文章更有助于更好理解本文内容: ①SpringCloud 实战:引入Eureka组件,完善服务治理 ②SpringCloud 实战:引入F ...

  6. spring cloud 配置zuul实用

    在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 技术背景 前面我们通过Ribbon或Feign实现了微服务之间的调用和负载均衡 ...

  7. SpringCloud学习系列之七 ----- Zuul路由网关的过滤器和异常处理

    前言 在上篇中介绍了SpringCloud Zuul路由网关的基本使用版本,本篇则介绍基于SpringCloud(基于SpringBoot2.x,.SpringCloud Finchley版)中的路由 ...

  8. springCloud学习4(Zuul服务路由)

    镇博图 springcloud 总集:https://www.tapme.top/blog/detail/2019-02-28-11-33 本篇中 Zuul 版本为 1.x,目前最新的是 2.x,二者 ...

  9. SpringCloud笔记七:Zuul

    目录 什么是Zull 为什么需要Zuul 新建Zuul项目 运行Zuul Zuul的基本配置 忽略微服务的真实名称 设置统一公共前缀 总结 什么是Zull Zuul就是一个网关,实现的功能:代理.路由 ...

随机推荐

  1. 使用vue-preview报错Cannot read property 'open' of undefined

    最近在做一个vue项目中时,需要使用vue-preview插件制作缩略图,首先在终端使用npm i vue-preview -S指令安装了vue-preview插件,然后在main.js中,导入并引用 ...

  2. 【贪心】数列分段Section I luogu-1181

    题目描述 对于给定的一个长度为\(N\)的正整数数列\(A_i\),现要将其分成连续的若干段,并且每段和不超过\(M\)(可以等于\(M\)),问最少能将其分成多少段使得满足要求. 分析 简单思考一下 ...

  3. js之 foreach, map, every, some

    js中array有四个方法 foreach, map, every, some,其使用各有倾向. 关注点一:foreach 和 map 无法跳出循环,每个元素均执行 foreach 和 map 无法跳 ...

  4. Python自动化测试面试题-Redis篇

    目录 Python自动化测试面试题-经验篇 Python自动化测试面试题-用例设计篇 Python自动化测试面试题-Linux篇 Python自动化测试面试题-MySQL篇 Python自动化测试面试 ...

  5. 第三篇--如何修改exe文件版本号和文件信息

    控制台程序添加版本信息方法: 项目右键 Add-->Resource-->选择Version-->new,然后就可以修改里面的信息了,重新编译一下就OK.

  6. Pycharm关联gitlab(http方式)

    Pycharm支持关联gitlab仓库,关联后对远端项目的克隆和提交都很方便.当初笔者在关联时遇到了很多坑,网上也没找到相关解决办法,所以在这里分享下完整的关联过程. 一.安装git 下载地址http ...

  7. 在js中对属性的操作

    一:访问属性 两种方法: ①:对象名.属性名 function  test(sno,age,sex){      this.sno=sno,      this.age=age, this.sex=s ...

  8. 公有组件ShowCodeList实现原理之一一下拉框的实现

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. ThinkPHP 2.x 任意代码执行漏洞

    直接访问 http://192.168.49.2:8080/index.php?s=/index/index/name/$%7B@phpinfo()%7D

  10. 自学 linux——14.mysql的基本操作

    MySQL的基本操作 1.名词介绍 以Excel文件举例: 数据库:可以看作是整个excel文件. 数据表:可以看作是一个excel文件中的工作表. 行(记录):可以看作是一个工作表中的一行 列(字段 ...