【SpringCloud】Zuul在何种情况下使用Hystrix

首先,引入spring-cloud-starter-zuul之后会间接引入:

【SpringCloud】Zuul在何种情况下使用Hystrix


hystrix依赖已经引入,那么何种情况下使用hystrix呢?

Zuul的自动配置类ZuulServerAutoConfiguration和ZuulProxyAutoConfiguration中总共会向Spring容器注入3个Zuul的RouteFilter,分别是

SimpleHostRoutingFilter

简单路由,通过HttpClient向预定的URL发送请求

生效条件:

RequestContext.getCurrentContext().getRouteHost() != null
​ && RequestContext.getCurrentContext().sendZuulResponse()

1、RequestContext中的routeHost不为空,routeHost就是URL,即使用URL直连

2、RequestContext中的sendZuulResponse为true,即是否将response发送给客户端,默认为true

RibbonRoutingFilter

使用Ribbon、Hystrix和可插入的http客户端发送请求

生效条件:

(RequestContext.getRouteHost() == null && RequestContext.get(SERVICE_ID_KEY) != null
​ && RequestContext.sendZuulResponse())

1、RequestContext中的routeHost为空,即URL为空

2、RequestContext中的serviceId不为空

3、RequestContext中的sendZuulResponse为true,即是否将response发送给客户端,默认为true

SendForwardFilter

forward到本地URL

生效条件:

RequestContext.containsKey(FORWARD_TO_KEY)
​ && !RequestContext.getBoolean(SEND_FORWARD_FILTER_RAN, false)

1、RequestContext中包含FORWARD_TO_KEY,即URL使用 forward: 映射

2、RequestContext中SEND_FORWARD_FILTER_RAN为false,SEND_FORWARD_FILTER_RAN意为“send forward是否运行过了”,在SendForwardFilter#run()时会ctx.set(SEND_FORWARD_FILTER_RAN, true)

综上所述,在使用serviceId映射的方法路由转发的时候,会使用Ribbon+Hystrix


而哪种路由配置方式是“URL映射”,哪种配置方式又是“serviceId映射”呢?

Zuul有一个前置过滤器PreDecorationFilter用于通过RouteLocator路由定位器决定在何时以何种方式路由转发

RouteLocator是用于通过请求地址匹配到Route路由的,之后PreDecorationFilter再通过Route信息设置RequestContext上下文,决定后续使用哪个RouteFilter做路由转发

所以就引出以下问题:

什么是Route

RouteLocator路由定位器如何根据请求路径匹配路由

匹配到路由后,PreDecorationFilter如何设置RequestContext请求上下文


什么是Route

我总共见到两个和Route相关的类

ZuulProperties.ZuulRoute,用于和zuul配置文件关联,保存相关信息

org.springframework.cloud.netflix.zuul.filters.Route, RouteLocator找到的路由信息就是这个类,用于路由转发

public static class ZuulRoute { private String id; //ZuulRoute的id private String path; //路由的pattern,如 /foo/** private String serviceId; //要映射到此路由的服务id private String url; //要映射到路由的完整物理URL private boolean stripPrefix = true; //用于确定在转发之前是否应剥离此路由前缀的标志位 private Boolean retryable; //此路由是否可以重试,通常重试需要serviceId和ribbon private Set<String> sensitiveHeaders = new LinkedHashSet(); //不会传递给下游请求的敏感标头列表 private boolean customSensitiveHeaders = false; //是否自定义了敏感头列表 } public class Route { private String id; private String fullPath; private String path; private String location; //可能是 url 或 serviceId private String prefix; private Boolean retryable; private Set<String> sensitiveHeaders = new LinkedHashSet<>(); private boolean customSensitiveHeaders; }

可以看到org.springframework.cloud.netflix.zuul.filters.Route和ZuulProperties.ZuulRoute基本一致,只是Route用于路由转发定位的属性location根据不同的情况,可能是一个具体的URL,可能是一个serviceId


RouteLocator路由定位器如何根据请求路径匹配路由

Zuul在自动配置加载时注入了2个RouteLocator

CompositeRouteLocator: 组合的RouteLocator,在getMatchingRoute()时会依次调用其它的RouteLocator,先找到先返回;CompositeRouteLocator的routeLocators集合中只有DiscoveryClientRouteLocator

DiscoveryClientRouteLocator: 可以将静态的、已配置的路由与来自DiscoveryClient服务发现的路由组合在一起,来自DiscoveryClient的路由优先;SimpleRouteLocator的子类(SimpleRouteLocator 基于加载到ZuulProperties中的配置定位Route路由信息)

其中CompositeRouteLocator是 @Primary 的,它是组合多个RouteLocator的Locator,其getMatchingRoute()方法会分别调用其它所有RouteLocator的getMatchingRoute()方法,通过请求路径匹配路由信息,只要匹配到了就马上返回

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zysdwy.html