路由是微服务体系结构的一个组成部分。例如,/可能映射到web应用程序,/api/users映射到用户服务,/api/shop映射到商店服务。Zuul是Netflix基于JVM的路由器和服务器端负载均衡器。
Netflix使用Zuul做以下用途:
- 身份验证
- 洞察
-
压力测试
- 金丝雀测试
- 动态路由
- 服务迁移
- 甩负荷
- 安全性
- 静态响应处理
- 主动/主动交通管理
zuul的规则引擎允许基本上用任何JVM语言编写规则和过滤器,并且内置了对Java和Groovy的支持。
配置属性zuul.max.host.connections已被两个新属性zuul.host.maxTotalConnections and zuul.host.maxPerRouteConnections, 默认值分别为200和20。
所有路由的默认Hystrix隔离模式(ExecutionIsolationStrategy)是信号量。如果首选THREAD隔离模式,zuul.ribbonIsolationStrategy可被设置为THREAD。
怎样引入ZUUL
group org.springframework.cloud
and artifact id spring-cloud-starter-netflix-zuul
.
嵌入式Zuul反向代理
Spring Cloud创建了一个嵌入式Zuul代理,以简化一个非常常见的用例的开发,在这个用例中,UI应用程序希望代理调用一个或多个后端服务。对于用户界面来说,该特性非常有用,可以代理到所需的后端服务,避免了独立管理所有后端的CORS和身份验证问题。
要启用它,请使用@EnableZuulProxy注释Spring启动主类,并将本地调用转发到适当的服务。按照惯例,ID为“users”的服务将从位于/users的代理接收请求(去掉前缀)。代理使用Ribbon定位要通过discovery转发的实例,所有请求都在hystrix命令中执行,因此失败将显示在hystrix metrics中,一旦电路打开,代理将不会尝试联系服务。
要跳过自动添加服务,请设置zuul.ignored-serviceso哦服务id模式列表。如果服务匹配被忽略的模式,但也包含在显式配置的路由映射中,那么它将不会被忽略。例子:
application.yml.
zuul:
ignoredServices: '*'
routes:
users: /myusers/**
在本例中,除了“users”之外,所有服务都将被忽略。
要增加或更改代理路由,可以添加以下外部配置:
application.yml.
zuul:
routes:
users: /myusers/**
这意味着对“/myusers”的http调用被转发到“users”服务(例如,“/myusers/101”被转发到“/101”)。
要对路由进行更细粒度的控制,可以独立指定路径和serviceId:
application.yml.
zuul:
routes:
users:
path: /myusers/**
serviceId: users_service
这意味着对“/myusers”的http调用被转发到“users_service”服务。路由必须有一个可以指定为ant样式模式的“路径”,因此“/myusers/*”只匹配一个级别,而“/myusers/**”则是分层匹配的。
后端位置可以指定为“serviceId”(用于来自discovery的服务)或“url”(用于物理位置),例如:
zuul:
routes:
users:
path: /myusers/**
url: http://example.com/users_service
这些简单的url路由不会作为一个HystrixCommand执行,也不会用Ribbon加载多个url。要实现这一点,可以使用静态服务器列表指定serviceId:
zuul:
routes:
echo:
path: /myusers/**
serviceId: myusers-service
stripPrefix: true
hystrix:
command:
myusers-service:
execution:
isolation:
thread:
timeoutInMilliseconds: ...
myusers-service:
ribbon:
NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
listOfServers: http://example1.com,http://example2.com
ConnectTimeout: 1000
ReadTimeout: 3000
MaxTotalHttpConnections: 500
MaxConnectionsPerHost: 100
另一种方法是指定服务路由并为serviceId配置Ribbon客户机(这需要禁用Ribbon中的Eureka支持:更多信息请参见上文),例如。
application.yml.
zuul:
routes:
users:
path: /myusers/**
serviceId: users
ribbon:
eureka:
enabled: false
users:
ribbon:
listOfServers: example.com,google.com
您可以使用regexmapper在serviceId和路由之间提供约定。它使用名为groups的正则表达式从serviceId中提取变量并将它们注入到路由模式中。
ApplicationConfiguration.java.
@Bean
public PatternServiceRouteMapper serviceRouteMapper() {
return new PatternServiceRouteMapper(
"(?<name>^.+)-(?<version>v.+$)",
"${version}/${name}");
}
这意味着serviceId“myusers-v1”将映射到路由“/v1/myusers/**”。可以接受任何正则表达式,但是所有命名组必须同时出现在servicePattern和routePattern中。如果servicePattern与serviceId不匹配,则使用默认行为。在上面的示例中,serviceId“myusers”将映射到route“/myusers/**”(未检测到版本),该特性在默认情况下是禁用的,只适用于已发现的服务。
要向所有映射添加前缀,请设置zuul。值的前缀,如/api。默认情况下,在转发请求之前会从请求中删除代理前缀(用祖尔. stripprefix =false关闭此行为)。您还可以关闭从单个路由中剥离特定于服务的前缀,例如。
application.yml.
zuul:
routes:
users:
path: /myusers/**
stripPrefix: false
zuul.stripPrefix只适用于zuul.prefix中设置的前缀。它对给定路由路径中定义的前缀没有任何影响。在本例中,对“/myusers/101”的请求将被转发到“users”服务上的“/myusers/101”。
zuul.routes条目实际上绑定到ZuulProperties类型的对象。如果您查看该对象的属性,您将看到它还有一个“retryable”标志。
将该标志设置为“true”,以便Ribbon客户机自动重试失败的请求。(如果需要,可以使用Ribbon客户机配置修改重试操作的参数)。
默认情况下,X-Forwarded-Host头添加到转发的请求中。把它关掉,设置zuul.addProxyHeaders = false. 默认情况下,删除前缀路径,发送到后台的请求接收到一个标题"X-Forwarded-Prefix"(上面例子中的“/myusers”)。
使用@EnableZuulProxy的应用程序可以作为一个独立的服务器,如果您设置了一个默认路由("/"),例如 zuul.route.home: /将路由所有(即"/**")到"home"服务。
如果需要更细粒度的忽略,可以指定要忽略的特定模式。这些模式在路由定位过程的开始时进行评估,这意味着模式中应该包含前缀以保证匹配。忽略的模式跨越所有服务,并取代任何其他路由规范。
application.yml.
zuul:
ignoredPatterns: /**/admin/**
routes:
users: /myusers/**
这意味着所有诸如“/myusers/101”之类的调用都将在“users”服务上转发到“/101”。但是包括“/admin/”在内的调用将无法解决。
如果您需要保存路由的顺序,则需要使用YAML文件,因为使用属性文件将丢失顺序。例如:
application.yml.
zuul:
routes:
users:
path: /myusers/**
legacy:
path: /**
<