最近在使用spring cloud zuul進(jìn)行一些服務(wù)網(wǎng)關(guān)的搭建和改造,由于一些原因,所以沒有使用config server和eureka做統(tǒng)一的配置管理和服務(wù)發(fā)現(xiàn)注冊,而是直接在zuul server上配置了db進(jìn)行routes的配置,因此使用的是static routing的模式,即直接指定一個(gè)route的url而不是serviceId。而我們url指向的地址,是一個(gè)nginx地址,相當(dāng)于通過nginx來做的一個(gè)service的負(fù)載均衡。
但在實(shí)際使用過程中我們發(fā)現(xiàn)一些問題,當(dāng)下游服務(wù)返回的消息大小超過下游nginx設(shè)置的gzip閾值的時(shí)候,會觸發(fā)響應(yīng)報(bào)文的壓縮,而zuul所接收到的報(bào)文,竟然是沒有解壓縮的!如果這時(shí)候我們需要對響應(yīng)報(bào)文進(jìn)行一些解析甚至是加密處理的話,會發(fā)現(xiàn)我們拿到的報(bào)文是二進(jìn)制碼,無法進(jìn)行下一步操作。而我們知道在我們平時(shí)使用的一些HttpClient工具的時(shí)候,這些工具能夠自動(dòng)幫我們處理響應(yīng)的解壓。那zuul這一塊是怎么處理的呢?我們有什么辦法去配置自動(dòng)解壓呢?
首先我在github上找到了這個(gè)issue:
https://github.com/spring-cloud/spring-cloud-netflix/issues/2363
里面這一段話引起了我的注意:
納尼?RibbonRoutingFilter是自動(dòng)解壓的?SimpleHostRoutingFilter默認(rèn)不解壓?其實(shí)也想得通。你就把zuul當(dāng)做一個(gè)nginx嘛。但是我們本身的業(yè)務(wù)流程怎么辦呀?那我們就深入到代碼里面去看看這個(gè)disableContentCompression是怎么調(diào)用的。
在SimpleHostRoutingFilter中我們看到了創(chuàng)建HttpClient的過程,看到?jīng)]有調(diào)用我們要找的disableContentCompression方法。那我就放心了,這個(gè)方法肯定是在httpClientFactory中創(chuàng)建的,那我們再去找這個(gè)httpClientFactory在哪里創(chuàng)建的?這里可以告訴大家一個(gè)小技巧。先直接對這個(gè)httpClientFactory對應(yīng)的ApacheHttpClientFactory來find usage,如果發(fā)現(xiàn)不是很好找的話,可以先找ApacheHttpClientFactory這個(gè)接口的實(shí)現(xiàn),你spring容器要注入,總的有個(gè)實(shí)現(xiàn)吧。我們查找實(shí)現(xiàn),找到了這么個(gè)類:
金燦燦的disableContentCompression有木有啊。我們大致確定了這個(gè)類就是我們要找的factory,那這個(gè)類在哪里用到呢?我們對這個(gè)類find usage,就到了這里。
而這個(gè)configuration是被ZuulProxyAutoConfiguration所引入的,一切都聯(lián)系起來了
到這兒,我們知道了為什么SimpleHostRoutingFilter是默認(rèn)不執(zhí)行解壓的,那對于我們需要解壓的邏輯我們應(yīng)該怎么處理呢?不知道大家有沒有注意apacheHttpClientFactory這個(gè)方法上面,有個(gè)ConditionalOnMissingBean注解?有這個(gè)注解一切都好辦了,你只需要在你的scan path下加上一個(gè)configuration,并且定義自己的一個(gè)ApacheHttpClientFactory的bean方法就行了,代碼如下:
親測可用。
以上是目前使用到zuul的一個(gè)問題小結(jié),如果大家有什么問題歡迎留言和討論。