Spring Cloud Zuul 精进

接着上一篇继续讲Zuul,上一篇搭建了Zuul的环境简单说明了怎么使用,本篇查缺补漏将一些常用的配置贴出来。文末我们会一起分析一下Zuul的源码,升华一下本篇的格调!

忽略所有微服务或某些微服务

默认情况下,只要引入了zuul后,就会自动一个默认的路由配置,但有些时候我们可能不想要默认的路由配置规则,想自己进行定义,忽略所有微服务:(后面写 * ):

zuul: ignored-services: "*"

忽略某些微服务:(直接写微服务的名字=>可以理解为spring.application.name的值,多个以都好分隔)

zuul: ignored-services: product-provider,product-consumer-8201

忽略所有为服务,只路由指定的微服务

zuul: # 排除所有的服务,只由指定的服务进行路由 ignored-services: "*" routes: eureka-client: path: /client1/** serviceId: eureka-client

通过path和url访问到具体的某台机器上

有时候我们测试的时候需要访问到具体的某台机器上,而不希望负载均衡到别的机器上或者需要访问到第三方的某台机器上:

zuul: routes: product-provider: path: /product/** url: :8202/

注意:

product-provider 这个值可以随便写,即使是一个不存在的值;

这种方式访问不会作为 HystrixCommand 来进行访问;

url 里面也不可以写多个url

敏感头的传递(比如Cookie等)全局设置和某个微服务设置

有些时候我们微服务上游可能想传递一些请求头到下游的服务,比如Token、Cookie等值,默认情况下,zuul 不会将 Cookie,Set-Cookie,Authorization 这三个头传递到下游服务,如果需要传递,就需要忽略这些敏感头。

zuul: #所有服务路径前统一加上前缀 prefix: /api # 排除某些路由, 支持正则表达式 ignored-patterns: - /**/modify/pwd # 排除服务 ignored-services: user-center routes: eureka-client: path: /client1/** serviceId: eureka-client sensitiveHeaders: #当前这个路由的header为空 sensitiveHeaders: Cookie,Set-cookie #全局路由都带这些header Zuul 源码浅析

开启Zuul很简单,在启动类上添加Zuul 开启注解:

@EnableZuulProxy /** * Sets up a Zuul server endpoint and installs some reverse proxy filters in it, so it can * forward requests to backend servers. The backends can be registered manually through * configuration or via DiscoveryClient. * * @see EnableZuulServer for how to get a Zuul server without any proxying * * @author Spencer Gibb * @author Dave Syer * @author Biju Kunjummen */ @EnableCircuitBreaker @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Import(ZuulProxyMarkerConfiguration.class) public @interface EnableZuulProxy { }

上面的注释上有一句话:EnableZuulServer 是不使用代理功能来获取Zuul server。开启Zuul 网关有两种方式:

@EnableZuulServer : 普通网关,只支持基本的route与filter;

@EnableZuulProxy :配合上服务发现与熔断开关,是 EnableZuulServer 的增强版,具有反向代理功能。

简单来说,@EnableZuulProxy可理解为@EnableZuulServer的增强版,当Zuul与Eureka、Ribbon等组件配合使用时,我们使用@EnableZuulProxy。

接着看 EnableZuulProxy,在类头引用了ZuulProxyMarkerConfiguration,ZuulProxyAutoConfiguration 的作用是开启 ZuulProxyAutoConfiguration的标记。

ZuulProxyAutoConfiguration 继承了 ZuulServerAutoConfiguration,是 ZuulServerAutoConfiguration 的超集。该类注入了DiscoveryClient、RibbonCommandFactoryConfiguration用作负载均衡相关的。注入了一些列的filters,比如PreDecorationFilter、RibbonRoutingFilter、SimpleHostRoutingFilter。

ZuulServerAutoConfiguration更为重要:

@Configuration @EnableConfigurationProperties({ ZuulProperties.class }) @ConditionalOnClass({ZuulServlet.class, ZuulServletFilter.class}) @ConditionalOnBean(ZuulServerMarkerConfiguration.Marker.class) // Make sure to get the ServerProperties from the same place as a normal web app would // FIXME @Import(ServerPropertiesAutoConfiguration.class) public class ZuulServerAutoConfiguration { @Autowired protected ZuulProperties zuulProperties; @Autowired protected ServerProperties server; @Autowired(required = false) private ErrorController errorController; private Map<String, CorsConfiguration> corsConfigurations; @Autowired(required = false) private List<WebMvcConfigurer> configurers = emptyList(); @Bean public HasFeatures zuulFeature() { return HasFeatures.namedFeature("Zuul (Simple)", ZuulServerAutoConfiguration.class); } @Bean @Primary public CompositeRouteLocator primaryRouteLocator( Collection<RouteLocator> routeLocators) { return new CompositeRouteLocator(routeLocators); } /** * 路由定位器 * */ @Bean @ConditionalOnMissingBean(SimpleRouteLocator.class) public SimpleRouteLocator simpleRouteLocator() { return new SimpleRouteLocator(this.server.getServlet().getContextPath(), this.zuulProperties); } /** * Zuul创建的一个Controller,用于将请求交由ZuulServlet处理 * */ @Bean public ZuulController zuulController() { return new ZuulController(); } /** * 会添加到SpringMvc的HandlerMapping链中, *只有选择了ZuulHandlerMapping的请求才能出发到Zuul的后续流程 * */ @Bean public ZuulHandlerMapping zuulHandlerMapping(RouteLocator routes) { ZuulHandlerMapping mapping = new ZuulHandlerMapping(routes, zuulController()); mapping.setErrorController(this.errorController); mapping.setCorsConfigurations(getCorsConfigurations()); return mapping; } /** * ZuulServlet是整个流程的核心 * * */ @Bean @ConditionalOnMissingBean(name = "zuulServlet") @ConditionalOnProperty(name = "zuul.use-filter", havingValue = "false", matchIfMissing = true) public ServletRegistrationBean zuulServlet() { ServletRegistrationBean<ZuulServlet> servlet = new ServletRegistrationBean<>(new ZuulServlet(), this.zuulProperties.getServletPattern()); // The whole point of exposing this servlet is to provide a route that doesn't // buffer requests. servlet.addInitParameter("buffer-requests", "false"); return servlet; } ...... ...... ...... }

在 ZuulServerAutoConfiguration 中定义了几个核心对象:

ZuulController:所有 路由的默认Controller;

ZuulHandlerMapping:Zuul 路由Mapping映射器;

ZuulServlet:继承自HttpServlet,过滤逻辑从这里始,到这里终。

ZuulServlet是整个流程的核心,大致的请求过程如下:

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

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