最近看spring cloud zuul的原理,记录下。
参考了同事的时序图:
但是细细看了源码还有controller层,springboot 通过@EnableZuulProxy注解开启Spring Cloud集成的Zuul,将会加载ZuulProxyConfiguration配置类。在ZuulProxyConfiguration中会把Spring Cloud预定义的一些Filter注册到Zuul。同时将ZuulServlet包装成ZuulController,也就是controller层托管给ZuulServlet,通过注册ZuulHandlerMapping将ZuulController引入到Spring MVC。具体源码如下
zuulServlet 里面有成员变量zuulRunner,它是通过构造函数形成的单例,在容器启动的时候初始化了这个类的init函数,然后初始化了zuulRunner的init函数,这个里面初始化了是否使用bufferrequest等信息,这个zuulRunner里面调用了 各种filter
pre 类型:
ServletDetectionFilter:判断是dispatchServlet还是zuulServlet的zuul,对所有request生效Servlet30WrapperFilter:zuul默认的wrapper拿不到正确的HttpServletRequest,对所有request生效FormBodyWrapperFilter:效果大概可以这么形容,无论如何都将上下文中ZuulRequestHeaders的content-type设置成了带文件类型+boundary的形式.具体过程是:获取上下文中HttpServletRequest判断类型,使用FormBodyRequestWrapper封装旧的HttpServletRequestWrapper封装过程中重新构造contentData,拆出请求内可能存在的多个文件.将上一步拆开的文件headers平铺到spring抽象的HttpEntity中在wrapper中抽出contentType.
PreDecorationFilter:
1、抽取上下文中requestURI转换为Route,并获取完整点对点服务地址(location)
2、照顾配置中zuul.customSensitiveHeaders相关,将其置入ProxyRequestHelper,其实也是操作RequestContent的ignoreHeaders中
3、补充retryable属性即是服务失败重试次数
4、判断location是http(s)或者forward.to
前者则添加X-Zuul-Service头,后者则添加forward.to头
如果这个location是服务地址的话则加上X-Zuul-ServiceId头
补充其他头信息:X-Forwarded-Host/X-Forwarded-Port/X-Forwarded-Prefix/X-Forwarded-For/Host
route类型: