Coup de Grace

Api网关 Zuul源码解读 Spring cloud

挖个坑,最近需要自建一个网关系统,顺手读一下下面这两位的源码.

Spring Cloud更新频繁得很,版本号是根据字母排序确定稳定性的.

我在这里看所有项目的更新进度.

目前的话

git chekcout v[tab]到你喜欢的版本.


絮絮叨叨

网关干嘛的:

基于zuul可以实现什么:

猜测实现:


Spring-Cloud-Netflix-Core实现

本文是接着上篇来进行食用的.

阅读本篇需要懂起码的Spring Boot auto-configure原理.起码翻一翻:

随着版本的更迭,处理请求的一些配置慢慢外移到了server配置上,具体可以看org.springframework.boot.autoconfigure.web.ServerProperties

另外要吐槽一下日志相关,boot是slf4j,cloud是CommonsLog,幸亏有jcl-over-slf4j桥接..

@EnableZuulProxy与@EnableZuulServer

启用一个zuul服务实在太简单,配合eureka的情况一个反代网关只需要几行代码就搭建完成了.

我们先从不带reverse proxy功能的网关看起.

org.springframework.cloud.netflix.zuul.ZuulConfiguration

从这份java config中可以拿到Simple模式下所有bean.

zuulFeature

告知actuator监控当前模式:Simple/Discovery

ZuulProperties

配置文件内容

zuul.ignoredServices
zuul.routes

zuul:
  ignored-services:
  routes:

其中routes对应着内部类定义ZuulRoute.

RouteLocator

解析ZuulProperties来获取路由表,命中路由表等等内容.

内部悄然把配置中ZuulRoute转化成自己抽象的Route.

获取server.*下的servletPrefix就不表了.

ZuulController

通过继承ServletWrappingController接管了上文定义的ZuulServlet.

ZuulHandlerMapping

响应器模式,其实目前就是把所有路径的请求导入到ZuulController上.

另外的功效是当觉察RouteLocator路由表变更,则更新自己dirty状态,重新注册所有Route到ZuulController.

ZuulRefreshListener

另外就是些ZuulFilter子类,我们后续逐个来说.

可以看到Simple模式下并没有什么内容,主要就是:


org.springframework.cloud.netflix.zuul.ZuulProxyConfiguration

现在切换到Discovery模式.

继承了上文的ZuulConfiguration,新增了服务与实例等概念,如下:

DiscoveryClientRouteLocator

DiscoveryClient肩负着从Eureka中获取服务列表,获取对应实例的功能.由于是Eureka中的功能,我们按下不表.

Eureka!文明6啊.

而后将path与上文的ZuulRoute通过DiscoveryClientRouteLocator.locateRoutes()的对应在一起.

具体过程大概是这样的:

  1. 将上文SimpleRouteLocator中解析出来的Route列表灌入内部的LinkedHashMap
  2. 抽取Route自带的serviceId,将其作为key,形成一个staticServices的map
  3. 遍历DiscoveryClient拿到的serviceId列表,匹配正则形式定义的serviceId并将对应的ZuulRoute与之对应
  4. 调整LinkedHashMap内路由顺序,将/**挪到最后
  5. 微调map内容,将key值加上/或者自定义prefix

zuulFeature

依然是将Zuul标识为Discovery模式.

httpclient

读取下列配置autoconfig一些Ribbon客户端来使用:

用处就是客户端负载均衡咯.

ZuulDiscoveryRefreshListener

依然是注册了这么个ApplicationEvent来触发上文中的dirty状态.


遗漏

org.springframework.cloud.netflix.zuul.filters.Route

Spring Cloud 的抽象,看看就好.

就是上文RouteLocator潜移默化转换的部分.

org.springframework.cloud.netflix.zuul.ZuulFilterInitializer

实现ServletContextListener,servlet内容来自tomcat惊了我…

实现了生命周期相关,不过目前还没有用到.还在开发中.


filter部分见下一篇.