转自: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. [刘阳Java]_SpringMVC访问静态资源_第9讲

    有些时候我们在使用SpringMVC的时候造成无法访问静态资源文件(如:html,js,css,image等等).其主要的原因出在web.xml文件我们设置SpringMVC前端控制器的映射路径 &l ...

  2. 就这?一篇文章让你读懂 Spring 事务

    什么是事务 ▲ 百度百科 概括来讲,事务是一个由有限操作集合组成的逻辑单元.事务操作包含两个目的,数据一致以及操作隔离.数据一致是指事务提交时保证事务内的所有操作都成功完成,并且更改永久生效:事务回滚 ...

  3. vscode源代码管理(vscode报错 未找到Git,请安装Git,或在"git.path" 设置中配置)

    vscode源代码管理(vscode报错 未找到Git,请安装Git,或在"git.path" 设置中配置) 直接上图,电脑上已经安装git,由于vscode没有找到git,所以v ...

  4. Python - if 条件控制

    注意 本篇图片素材都来自慕课网,因为素材过于优秀,直接拿过来了,加水印只是为了防止整篇文章被搬 前言 程序并非是一成不变的向下执行,有的时候也要根据条件的不同选择不一样的代码,这个时候便用到了分支结构 ...

  5. phpcms开发使用

    二次开发入口文件: 1.dirname(__FILE___) 函数返回的是脚本所在在的路径 2.__FILE__ 当前运行文件的完整路径和文件名.如果用在被包含文件中,则返回被包含的文件名. 3.DI ...

  6. Hadoop 3.1.1 - 概述 - 单节点安装

    Hadoop: 单节点安装 目标 本文描述了如何安装和配置单机的 Hadoop,这样你可以使用 Hadoop MapReduce 和 Hadoop 分布式文件系统(HDFS)快速地尝试简单的操作. 前 ...

  7. 2020年度钻石C++C学习笔记(3)--《博学谷》

    1.Unix/Linux操作系统介绍 1.1 操作系统的作用 1.1.1 操作系统的目标 l 方便:使计算机系统易于使用 l 有效:以更有效的方式使用计算机系统资源 l 扩展:方便用户有效开发.测试和 ...

  8. .Netcore HttpClient源码探究

    源码搜索与概述 搜索HttpClient源码 https://source.dot.net/#System.Net.Http/System/Net/Http/HttpClient.cs 1.HttpC ...

  9. 第5篇-调用Java方法后弹出栈帧及处理返回结果

    在前一篇 第4篇-JVM终于开始调用Java主类的main()方法啦 介绍了通过callq调用entry point,不过我们并没有看完generate_call_stub()函数的实现.接下来在ge ...

  10. Azure 实践(1)- Azure Devops Server 安装

    1.Azure Devops介绍 Azure DevOps Server 2020 (之前的名称为TFS),作为微软Azure DevOps 的企业私有(on-premises)服务器,是一个为开发团 ...