链接: 知乎 https://zhuanlan.zhihu.com/p/26494607 简单实例
知乎 https://zhuanlan.zhihu.com/p/28376627 源码介绍
github https://github.com/Netflix/zuul/wiki
spring社区 http://projects.spring.io/spring-cloud/spring-cloud.html#_router_and_filter_zuul
csdn http://blog.csdn.net/liuchuanhong1/article/details/62236793 filter讲解
zuul主要可以用来路由转发,也可以用来过滤请求。搭配Eureka的发现可以轻松实现转发功能,继承ZuulFilter类可以自定义过滤算法。(例子见第一条链接)
zuul的负载均衡通过Ribbon实现,proxy通过Eureka和Ribbon定位一个服务的instance并转发请求。 所有的请求通过hystrix command执行
zuul:
ignoredServices: '*'
routes:
users: /myusers/**
通过上面的配置来忽略服务,但是如果一个服务id符合ignore pattern,同时又明确配置在转发表中,他将不会被忽略。
上述配置中,users的服务不会被忽略。/myusers开头的请求会被转发到users服务,例如:/myusers/101会首先被转发到users,再访问/101
zuul:
routes:
users:
path: /myusers/**
serviceId: users_service
上述配置是细粒度更高的配置方式
/myusers会被转发到users_service服务。 转发后的具体请求前缀可以配置,例如设置stripPrefix=false的话,请求的url不变。
还可以配置ignorepattern, 转发请求的前缀,人工配置转发服务地址等...人工配置url不能实现负载均衡,需要结合ribbon
zuul适用的一个场景是,处理老旧的接口。将这些陈旧的接口转发到新的接口处理,转发由zuul实现。
zuul.SendResponseFilter.post.disable=true
可以通过上述方式禁用一个filter。 Filter通过继承ZuulFilter实现,然后可以作为一个Bean添加到容器中启动。可以添加多个Filter
源码分析:
@EnableZuulProxy注解引入了@EnableCircuitBreaker和@EnableDiscoveryClient两个注解
同同时引入了ZuulProxyConfiguration配置类,继承自ZuulConfiguration类
该配置类首先引入了DiscoveryClient和RibbonCommandFactoryConfiguration用来发现client并负载均衡。
还注入了许多Filters的Bean
ZuulConfiguration是Zuul的核心类,他在缺失Servlet的情况下会注入一个ZuulServlet,同时也注入了许多Filters。
他还注入了初始化类ZuulFilterInitializer,该类用来将所有的Filter注册到FilterRegistry(会生成一个FilterRegistry和一个FilterLoader的实例)
FilterRegistry通过一个ConcurrentHashMap管理所有的Filter,并由FilterFileManager所持有的FiilterLoader调用。所以Filter实际上是由FilterFileManager中的一个方法轮询的去加载过滤器的。注册的过程是由FileLoader发起的,FilterRegistry只负责记录,不会主动去询问注册
ZuulServlet是一个类似于DispacherServlet的类,起到控制器的作用。
接收到请求后,调动init方法初始化生成RequestContext
然后调用preRoute,route和postRoute方法,每个方法中会调用这个阶段所有的Filter并执行(通过FilterLoader调用Filter)。
当一个程序启动后,首先程序会加载Configuration中的Bean,包括自己实现的Bean。
所有的Filter Bean会被注册到Registry上,这一步通过FilterLoader/FilterFileManager 实现。
一个请求到达后,首先Servlet进行拦截,并生成RequestContext。
进一步调用各个阶段的Filter进行处理,其中route阶段的filter负责 路由 + 过滤。