前言
最近公司最新架构确定使用微服务之后, 经过讨论, 最终还是选用了 SpringCloud 的体系. 我负责网关, 鉴权服务的研发. 记录下这段时间新接触的知识.
网关技术选型
springcloud 选用了最新的稳定版本 Greenwich, 所以对于网关来说, 有两种框架选择: SpringCloud Gateway, Zuul, 经过调研我最终选用了 Zuul, 原因如下:
目前项目在一个快速迭代的过程中, Zuul 相比于 Gateway 来说更加稳定.
Gateway 文档还有待完善, 我在调查的过程中, 发现官网文档甚至代码还留有很多 TODO, 这不是一个大坑吗! Gateway 文档
Gateway 相对 Zuul 来说显得难以使用, Gateway 使用 Spring5 开发, 基于函数, 响应式编程, 可能对于刚接触 Reactive 的人来说阅读源码有一定难度.
虽然 Zuul 在性能上来说不如 Gateway, 但对于我们的业务来说这点时间消耗显得不那么重要.
- Proxy Avg Latency Avg Req/Sec/Thread
- gateway 6.61ms 3.24k
- linkered 7.62ms 2.82k
- zuul 12.56ms 2.09k
- none 2.09ms 11.77k
Zuul 工作原理
使用 Zuul 的关键在于自定义 Filter, 当然这个 Filter 不是 Servlet 对应的 Filter, 并且不同类型的 Filter 使用相同的配置却有不同的效果. 秉着知其所以然的精神, 把整个 Zuul 处理过程的源码 debug 了一遍;
入口
Zuul 处理请求的入口是一个 Servlet:ZuulServlet,SpringCloud 也提供另外的处理入口, 一个 Servlet Filter: ZuulServletFilter, 修改配置文件 zuul.use-filter=true 即可. 它进入 ZuulServlet 的过程如下:
Zuul
http 依然先进入 DispatchServlet, 接着调用 ZuulController, 再接着调用 ZuulServlet. 这中间经过不少反射处理, 可能这也是性能低的一个原因. 不太明白为什么不直接进入 ZuulServlet.
源码走读
Zuul
进入了 ZuulServlet 后, 调用 service 方法, 这个时候就开始调用各个类型的 ZuulFilter 了, 它主要做了如下事情.
初始化 RequestContext, 其实就是一个 ThreadLocal, 将 httpServlet,httResponse 放入其中, 方便后面自定义的 ZuulFilter 可以获取.
调用 pre filter.
调用 route filter.
调用 post filter.
注意点: 再调用各个 filter 的过程中如果出现异常, 都会调用 error filter.
接着我们查看 pre filter 是如何调用的:
Zuul
Zuul
Zuul
Zuul
也就是说, 现在上面的流程图变成了这样:
Zuul
这样, 我们的思路就很清晰了, 从请求进入, 到 zuul 的调用完整过程都已经整理了出来, 接下来我们只要开始自定义 filter 处理我们的业务逻辑即可.
总结
本章我们从技术选型出发, 比较了 zuul 和 gateway 的优缺点. 最后通过阅读源码的方式整理了 Zuul 处理请求的整个过程.
下一章: 如何自定义 Zuul Filter 以及所遇到坑!
关注我, 这里只有干货!
来源: http://www.jianshu.com/p/9f967ad2490a