1. 概述

微服务网关
前置门户入口,请求通过网关进行路由,定位到具体的服务节点上。它本身也是一个微服务,也会在注册中心进行服务注册与发现。Zuul网关不是必要的,一般在微服务数量较多(多于10)推荐使用,对服务的管理有严格的要求时候推荐使用,微服务权限要求严格的时候推荐使用。
统一入口 起到外部和内部隔离的作用,保障了后台服务的安全性。
鉴权校验 识别每个请求的权限,拒绝不符合要求的请求。
路由动态 动态的将请求路由到不同的后端集群中。
解耦 减少客户端与服务端的耦合,服务独立发展,通过网关层来做映射。
`
依赖**`

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-zuul</artifactId>
  4. </dependency>
  5. <!-- zuul网关的重试机制,不是使用ribbon内置的重试机制是借助spring-retry组件实现的重试开启zuul网关重试机制需要增加下述依赖-->
  6. <dependency>
  7. <groupId>org.springframework.retry</groupId>
  8. <artifactId>spring-retry</artifactId>
  9. </dependency>

2. 配置

2.1. 网关启动器

@EnableZuulProxy
网关配置方式:默认、URL、服务名称、排除 | 忽略、前缀。
网关配置没有优劣好坏,在不同的情况下选择合适的配置方案。
Zuul网关底层使用Ribbon实现请求的路由,内置Hystrix,可选择性提供网关fallback逻辑,使用zuul时候,不推荐Feign作为application client端的开发实现。Feign是对Ribbon的再封装,使用Feign本身提高通讯消耗,降低通讯效率,只在服务相互调用时候使用Feign简化代码开发;Ribbon + RestTemplate开发比例更高。

2.2. 过滤器

Zuul 提供过滤器定义,过滤代理请求,提供额外功能逻辑,权限验证、日志记录等。继承 ZuulFilter 提供4个抽象方法:filterType,filterOrder,shouldFilter,run。
**filterType()**
方法返回数据 String 代表当前过滤器类型,pre route post error
pre (前置过滤)在请求被路由前执行,处理身份认证,日志记录等。
route (路由后过滤)在路由执行后,服务调用前被调用。
post (后置过滤) routeerror 执行后被调用,用于收集服务信息,统计服务性能指标等,也可以对response结果做特殊处理。
error (异常过滤)任意 过滤器 发生异常或 服务调用 无结果反馈的时候执行的过滤逻辑。
filterOrder()
方法返回数据 int 用于为同filterType的多个过滤器定制执行顺序,返回值越小,执行顺序越优先。
shouldFilter()
方法返回数据 boolean 代表当前filter是否生效。
**run()**

具体的过滤执行逻辑。如 pre 过滤器,可以通过对请求的验证来决定是否将请求路由到服务上,如 post 过滤器,可以对服务响应结果做加工处理。
image.jpeg

3. 容错 / 降级 / 限流

Hystrix
Spring cloud zuul启动器中包含了 Hystrix 相关依赖,在Zuul网关工程中,默认是提供了Hystrix Dashboard服务监控数据的(hystrix.stream),但是不会提供监控面板的界面展示。


FallbackProvider<br />
Edgware 版本之前,提供接口 ZuulFallbackProvider 用于实现 fallback 处理。
Edgware 版本开始,提供 ZuulFallbackProvider 子接口 FallbackProvider 提供 fallback 处理。Zuul的 fallback 容错处理逻辑,只针对timeout 异常处理,当请求被 Zuul 路由后,只要服务有返回(包括异常),都不会触发Zuul的fallback容错逻辑。对于 Zuul网关来说,做请求路由分发的时候,结果由远程服务运算的。那么远程服务反馈了异常信息,Zuul网关不会处理异常,因为无法确定这个错误是否是应用真实想要反馈给客户端的。


依赖

<dependency>
    <groupId>com.marcosbarbero.cloud</groupId>
    <artifactId>spring-cloud-zuul-ratelimit</artifactId>
    <version>1.3.4.RELEASE</version>
</dependency>

**全局配置** 对代理的所有服务提供限流保护。

# 开启限流保护
zuul.ratelimit.enabled=true
# 60s内请求超过3次,服务端就抛出异常,60s后可以恢复正常请求
zuul.ratelimit.default-policy.limit=3
zuul.ratelimit.default-policy.refresh-interval=60
# 针对IP进行限流,不影响其他IP
zuul.ratelimit.default-policy.type=origin

**局部配置** 针对配置的服务提供限流保护。

# 开启限流保护
zuul.ratelimit.enabled=true
# hystrix-application-client服务60s内请求超过3次,服务抛出异常
zuul.ratelimit.policies.hystrix-application-client.limit=3
zuul.ratelimit.policies.hystrix-application-client.refresh-interval=60
# 针对IP限流。
zuul.ratelimit.policies.hystrix-application-client.type=origin

image.jpeg

4. 调优

网关两层超时调优。Hystrix内部使用线程池隔离机制提供请求路由实现,其默认的超时时长为1000毫秒。ribbon底层默认超时时长为5000毫秒。如果Hystrix超时,直接返回超时异常。如果ribbon超时,同时Hystrix未超时,ribbon会自动进行服务集群轮询重试,直到Hystrix超时为止。如果Hystrix超时时长小于ribbon超时时长,ribbon不会进行服务集群轮询重试。
  那么在zuul中可配置的超时时长就有两个位置:Hystrix和ribbon。具体配置如下:

# 开启zuul网关重试
zuul.retryable=true
# hystrix超时时间设置
# 线程池隔离,默认超时时间1000ms
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=8000
# ribbon超时时间设置:建议设置比Hystrix小
# 请求连接的超时时间: 默认5000ms
ribbon.ConnectTimeout=5000
# 请求处理的超时时间: 默认5000ms
ribbon.ReadTimeout=5000
# 重试次数:MaxAutoRetries表示访问服务集群下原节点(同路径访问)
MaxAutoRetriesNextServer表示访问服务集群下其余节点(换台服务器)
ribbon.MaxAutoRetries=1
ribbon.MaxAutoRetriesNextServer=1
# 开启重试
ribbon.OkToRetryOnAllOperations=true