
Spring Cloud集群中用于内部通信的组件有服务管理组件Eureka、负载均衡组件Ribbon。不过如果是集群提供了Api或者WEB服务的话就需要与外部进行通信。这时候需要一个代理层作为集群的大门网关可以将集群的服务隐藏在后面而对于外部客户端来说只需关心网关的配置不许关系集群的内部结构。官方定义Zuul是在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。Zuul相当于是设备和Netflix流应用的Web网站后端所有请求的前门。即Zuul为微服务集群提供代理、过滤和路由等功能。一、Zuul的功能Zuul会把外部的请求过程分为不同阶段每个阶段提供一系列的过滤器,这些过滤器实现了以下功能1、身份验证和安全性对需要身份验证的资源进行过滤拒绝处理不符合身份认证的请求。2、观察和监控跟踪重要的数据为我们展示准确的请求状况3、动态路由将请求动态路由到不同的服务集群4、负载均衡设置每种请求的处理能力删除那些超出限制的请求5、静态响应处理提供静态的过滤器直接响应一些请求而不将它们转发到集群内部6、路由多样化除了将请求路由到Spring Cloud集群内部还可以将请求路由到其他服务二、过滤器运行机制当程序被EnableZuul修饰后Spring容器进行初始化时会将zuul的相关配置初始化包括Springboot中用于注册Servlet的ServletRegistrationBean而ZuulServlet的service方法用于执行各类过滤器。下图为http请求在ZuulServlet内的生命周期。ZuulServlet.service()接收到请求后首先执行pre阶段的过滤器执行routing阶段的过滤器最后执行post阶段的过滤器。routing阶段的过滤器将请求转发到源服务第三方的web服务或spring cloud的集群服务。如果pre或者routing阶段的过滤器时如果出现异常则执行error过滤器。而整个过程中Http请求、响应、状态等信息都会封装再一个RequestContext对象中。而过滤器的执行优先级由其序号大小决定的优先级顺序号越小有限度越高。三、路由配置zuul提供强大的路由功能其按照一定的规则进行请求转发。集中在routing阶段1、简单路由外部访问的所有请求都被转发到源服务上,使用SimpleHostRoutingFilter过滤器实现。其中path可以省略。url是以http或者https:开头的。zuul: routes: test: path: /test/163 url: http://www.163.com实现机制过滤器使用HttpClient进行转发。先把HttpServletRequest是相关数据转成HttpClient的请求实体HttpRequest再使用CloseableHttpClient进行转发。为了保证性能使用了HttpClient的线程池功能对目标主机的最大连接数默认200和初始连接数默认20可以进行修改。2、跳转路由外部访问网关的A地址会跳转到B地址上。这类路由使用SendForwardFilter 实现。url是以forward开头的。routes: sale: path: /test/** url: forward: /source/b实现机制调用RequestDispatcher的forward方法进行跳转。3、Ribbon路由当网关作为Eureka客户端注册到Eureka服务器时可以通过配置serviceid将请求转发到集群的服务中此类路由使用 RibbonRoutingFilter实现。zuul: routes: restTestRoute: path: /rest-tpl-sale/** serviceId: zuul-sale-service当路由配置不是简单路由格式也不是挑战路由格式那么就会默认使用Ribbon过滤器并将url作为serviceid。4、自定义路由规则如果内置的三种路由配置无法满足用户需求可以进行自定义路由规则。操作也非常简单只需要在自定义的配置类中创建一个PatternServiceRouteMapperConfiguration public class MyConfig { /** * 访问网关的 /xxxxx/**将会被路由到 zuul-xxxxx-service 服务进行处理 */ Bean public PatternServiceRouteMapper patternServiceRouteMapper() { return new PatternServiceRouteMapper( (zuul)-(?module.)-(service), ${module}/**); } }第一个参数是serviceid第二参数是path。例如访问test/**的请求都被路由到zuul-test-service上面去。5、忽略路由这种路由用于设计若干个服务不被路由的情景使用zuul.ignoredPatterns属性来配置。zuul: ignoredPatterns: /test/noRoute配置后除了/test/noroute的访问外其他/test路径的请求都被路由到zuul-test-service。四、集群上图是一个简单的Spring cloud集群。zuul作为网关服务提供方提供/service/{id}的查找服务服务调用者对外提供/consume/{id}服务并通过调用服务提供方服务实现逻辑。