spring cloud zuul使用記錄(1) SimpleHostRoutingFilter GZIP問題
最近在使用spring cloud zuul進行一些服務閘道器的搭建和改造,由於一些原因,所以沒有使用config server和eureka做統一的配置管理和服務發現註冊,而是直接在zuul server上配置了db進行routes的配置,因此使用的是static routing的模式,即直接指定一個route的url而不是serviceId。而我們url指向的地址,是一個nginx地址,相當於通過nginx來做的一個service的負載均衡。
但在實際使用過程中我們發現一些問題,當下遊服務返回的訊息大小超過下游nginx設定的gzip閾值的時候,會觸發響應報文的壓縮,而zuul所接收到的報文,竟然是沒有解壓縮的!如果這時候我們需要對響應報文進行一些解析甚至是加密處理的話,會發現我們拿到的報文是二進位制碼,無法進行下一步操作。而我們知道在我們平時使用的一些HttpClient工具的時候,這些工具能夠自動幫我們處理響應的解壓。那zuul這一塊是怎麼處理的呢?我們有什麼辦法去配置自動解壓呢?
首先我在github上找到了這個issue:
https://github.com/spring-cloud/spring-cloud-netflix/issues/2363
裡面這一段話引起了我的注意:

github issue轉載
納尼?RibbonRoutingFilter是自動解壓的?SimpleHostRoutingFilter預設不解壓?其實也想得通。你就把zuul當做一個nginx嘛。但是我們本身的業務流程怎麼辦呀?那我們就深入到程式碼裡面去看看這個disableContentCompression是怎麼呼叫的。

SimpleHostRoutingFilter建立HttpClient
在SimpleHostRoutingFilter中我們看到了建立HttpClient的過程,看到沒有呼叫我們要找的disableContentCompression方法。那我就放心了,這個方法肯定是在httpClientFactory中建立的,那我們再去找這個httpClientFactory在哪裡建立的?這裡可以告訴大家一個小技巧。先直接對這個httpClientFactory對應的ApacheHttpClientFactory來find usage,如果發現不是很好找的話,可以先找ApacheHttpClientFactory這個介面的實現,你spring容器要注入,總的有個實現吧。我們查詢實現,找到了這麼個類:

DefaultApacheHttpClientFactory實現
金燦燦的disableContentCompression有木有啊。我們大致確定了這個類就是我們要找的factory,那這個類在哪裡用到呢?我們對這個類find usage,就到了這裡。

預設httpClientFactory configuration
而這個configuration是被ZuulProxyAutoConfiguration所引入的,一切都聯絡起來了

zuul配置引入
到這兒,我們知道了為什麼SimpleHostRoutingFilter是預設不執行解壓的,那對於我們需要解壓的邏輯我們應該怎麼處理呢?不知道大家有沒有注意apacheHttpClientFactory這個方法上面,有個ConditionalOnMissingBean註解?有這個註解一切都好辦了,你只需要在你的scan path下加上一個configuration,並且定義自己的一個ApacheHttpClientFactory的bean方法就行了,程式碼如下:

自定義解壓HttpClientFactory
親測可用。
以上是目前使用到zuul的一個問題小結,如果大家有什麼問題歡迎留言和討論。