本文原創地址,
我的博客
:https://jsbintask.cn/2019/03/28/springcloud/springcloud-zuul-process/(食用效果最佳),轉載請註明出處!
前言
最近公司最新架構確定使用微服務之後,經過討論,最終還是選用了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的過程如下:
http依然先進入DispatchServlet,接着調用ZuulController,再接着調用ZuulServlet。這中間經過不少反射處理,可能這也是性能低的一個原因。不太明白爲什麼不直接進入ZuulServlet。
源碼走讀
進入了ZuulServlet後,調用service方法,這個時候就開始調用各個類型的ZuulFilter了,它主要做了如下事情。
- 初始化RequestContext,其實就是一個
ThreadLocal
,將httpServlet,httResponse放入其中,方便後面自定義的ZuulFilter可以獲取。 - 調用
pre filter
。 - 調用
route filter
。 - 調用
post filter
。
注意點:再調用各個filter的過程中如果出現異常,都會調用error filter
。
接着我們查看pre filter是如何調用的:
也就是說,現在上面的流程圖變成了這樣:
這樣,我們的思路就很清晰了,從請求進入,到zuul的調用完整過程都已經整理了出來,接下來我們只要開始自定義filter處理我們的業務邏輯即可。
總結
本章我們從技術選型出發,比較了zuul和gateway的優缺點。最後通過閱讀源碼的方式整理了Zuul處理請求的整個過程。
下一章:如何自定義Zuul Filter以及所遇到坑!
關注我,這裏只有乾貨!