上篇文章介绍了Spring Cloud Zuul
基本的使用方法,但其实Zuul还有更多的应用场景,比如:鉴权、流量转发、请求统计等等,这些功能都可以使用Zuul来实现。
Zuul过滤器
Filter是Zuul的核心,用来实现对外服务的控制。Filter的生命周期有4个,分别是PRE
、ROUTING
、POST
、ERROR
。
Zuul大部分功能都是通过过滤器来实现的,这些过滤器类型对应于请求的典型生命周期。
PRE
: 这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。ROUTING
:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。POST
:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。ERROR
:在其他阶段发生错误时执行该过滤器。 除了默认的过滤器类型,Zuul还允许我们创建自定义的过滤器类型。例如,我们可以定制一种STATIC类型的过滤器,直接在Zuul中生成响应,而不将请求转发到后端的微服务。
应用场景:
- token校验/安全认证
- 动态修改请求参数,比如:终端发过来的数据,出于安全要求,可能是经过加密处理的,需要在网关层进行参数解密,再传递到后面的服务;再比如:用户传过来的token值,需要转换成userId/userName这些信息,再传递到背后的微服务。
- 灰度发布(Gated Launch/Gray Release):将请求(根据参数内容+业务规则),将其转向到特定的灰度机器上。Spring Cloud MicroService中有一个metadata-map(元数据)设置,可以很好的满足这类需求。
熔断处理
当我们的后端服务出现异常的时候,我们不希望将异常抛出给最外层,期望服务可以自动进行一降级。Zuul给我们提供了这样的支持。当某个服务出现异常时,直接返回我们预设的信息。
我们通过自定义的fallback
方法,并且将其指定给某个route
来实现该route
访问出问题的熔断处理。主要实现FallbackProvider
接口来实现,FallbackProvider
默认有两个方法,一个用来指明熔断拦截哪个服务,一个定制返回内容。
@Component
public class RouteFallback implements FallbackProvider {
@Override
public String getRoute() {
return "*";
}
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.OK;
}
@Override
public int getRawStatusCode() throws IOException {
return 200;
}
@Override
public String getStatusText() throws IOException {
return "OK";
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream(JSONObject.toJSONString(ResponseGenerator.error(ErrorCodeEnum.CUSTOM_ERROR.getCode(), "服务不可用")).getBytes());
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
};
}
}
getRoute()
:*
表示所有的服务
限流
限制请求的频率,比如验证码接口可以限制1分钟内只能请求3次。
代码实现:
1、导入依赖
<dependency>
<groupId>com.marcosbarbero.cloud</groupId>
<artifactId>spring-cloud-zuul-ratelimit</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
- 注意版本问题,网上很多例子是
1.3.2
,由于我的Spring Boot
版本是2.0.3
,所以需要使用2.2.3
版本。
2、修改配置问题
zuul.ratelimit.enabled=true
zuul.ratelimit.repository=consul # 用来存储统计信息,可以是redis
zuul.ratelimit.policy-list.pay-server[0].limit=3 # 单位时间内允许访问的次数
zuul.ratelimit.policy-list.pay-server[0].refresh-interval=60 # 单位时间设置
zuul.ratelimit.policy-list.pay-server[0].type=origin # 对IP进行限流
default-policy
可选 - 针对所有的路由配置的策略,除非特别配置了policy-list
policy-list
对特定的服务id进行限流policy-list.pay-server[0]
需要加上下标,不然会报错
3、启动服务和网关,请求多次后会返回There was an unexpected error (type=Too Many Requests, status=429).
,到consul页面,可以看到Key/Value
里有值。