spring cloud 服务网关ZUUL
路由是微服务架构中不可或缺的一部分。比如,/ 可能需要映射到你的web应用, /api/users 映射到用户服务, /api/shop 映射到商城服务. Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器。
可以通过Zuul实现下列业务:
- 认证和安全
- 测试监控
- 动态路由
- 限流
- 静态响应处理
反向代理
在Spring Boot main函数上通过注解 @EnableZuulProxy 来开启. 根据请求URL匹配,Ribbon从
注册中心Eureka
获取服务ID做负载均衡,请求都在Hystrix
的command中执行。
路由规则可以在配置文件中指定,可以像nginx一样根据URL正则匹配请求。 示例 application.yml
zuul:
routes:
users:
path: /users/**
serviceId: users_service
这个意味着HTTP请求"/users"开头的URL,会被转发到"users_service"服务. 路由必须配置一个可以被指定为ant风格表达式的"path", /users/*
只能匹配一个层级, 但/users/**
可以匹配多级。后端的配置既可以是"serviceId"(对于服务发现中的服务而言), 也可以是"url"(对于物理地址)
zuul:
ignoredPatterns: /**/admin/**
routes:
users: /users/**
“/users/101"的请求会跳转到"users"服务的”/101", 但包含"/admin/“的请求将不被处理.
动态绑定 可以通过regexmapper提供serviceId和routes之间的绑定. 它使用正则表达式组来从serviceId提取变量, 然后注入到路由表达式中。示例: ApplicationConfiguration.java
@Bean
public PatternServiceRouteMapper serviceRouteMapper() {
return new PatternServiceRouteMapper(
"(?<name>^.+)-(?<version>v.+$)",
"${version}/${name}");
}
这个意思是说"users-v1"将会匹配路由”/v1/users/",任何正则表达式都可以, 但是所有组必须存在于servicePattern和routePattern之中. 如果servicePattern不匹配服务ID,则使用默认行为,这个功能默认是关闭的,并且仅适用于服务注册的服务。
前缀
如果api中有前缀如/v2/user/, /api/user/**,可以设置zuul.prefix,通过zuul.stripPrefix=false
关闭。
REST API 动态获取和修改: 如果你使用 @EnableZuulProxy 同时引入了Spring Boot Actuator, 你将默认增加一个endpoint, 提供http服务的 /routes. 一个GET请求将返回路由匹配列表. 一个POST请求将强制刷新已存在的路由。
Cookies和敏感HTTP头
X-Forwarded-Host
默认在跳转是自动添加,可以通过zuul.addProxyHeaders = false
关闭。
如果希望某些HTTP HEADER不泄露到下游服务,可以配置为敏感头。
zuul:
routes:
users:
path: /myusers/**
sensitiveHeaders: Cookie,Set-Cookie,Authorization
url: https://downstream
可以这样对不同服务设置不同敏感头,也可以设置全局默认敏感头:zuul.sensitiveHeaders =
窒息模式和本地跳转
旧接口迁移到新接口的过程,可以如下,把一部分接口用老接口,一部分迁移的方式。有点像rewrite。
zuul:
routes:
first:
path: /first/**
url: http://first.example.com
second:
path: /second/**
url: forward:/second
third:
path: /third/**
url: forward:/3rd
legacy:
path: /**
url: http://legacy.example.com
通过Zuul上传文件
如果使用 @EnableZuulProxy , 可以使用代理路径上传文件, 对于小文件可以正常使用即可, 对于大文件,还有可选路径”/zuul/,通过它绕过Spring DispatcherServlet (避免处理multipart). 比如对于 zuul.routes.customers=/customers/*
,使用 /zuul/customers/*
去上传大文件. Servlet路径通过 zuul.servletPath 指定. 如果使用Ribbon负载均衡器的代理路由, 在 处理非常大的文件时, 仍然需要提高超时配置。
application.yml
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
ribbon:
ConnectTimeout: 3000
ReadTimeout: 60000
注意: 对于大文件的上传流, 你应该在请求中使用块编码. (有些浏览器默认不这么做). 比如在命令行中:
$ curl -v -H "Transfer-Encoding: chunked" \
-F "file=@mylarge.iso" localhost:9999/zuul/simple/file