Zuul是Spring Cloud技術(shù)棧里對(duì)外網(wǎng)關(guān)的實(shí)現(xiàn)。
所有的服務(wù)從這里對(duì)外暴露,鑒權(quán)、加密、壓縮、緩存等等等等,各類(lèi)需求可以在這里一次編碼、徹底解決,方便極了。
但是這里又是所有服務(wù)的入口,一夫當(dāng)關(guān)、萬(wàn)夫莫開(kāi),丁點(diǎn)錯(cuò)誤會(huì)被無(wú)限放大,需要慎之又慎。
昨天小踩了一下,發(fā)現(xiàn)了幾個(gè)小坑,先記下來(lái),待時(shí)機(jī)成熟時(shí)在一塊兒總結(jié)。
1. 不要對(duì)response直接操作??!
response的輸出流不是你想寫(xiě)就能寫(xiě),想讀就能讀。
可以看下HttpServletResponse的各種實(shí)現(xiàn),也是通過(guò)各種wrapper,通過(guò)包裝器模式來(lái)感知獲取流數(shù)據(jù)的,斷然不是想讀就讀想寫(xiě)就寫(xiě)。
作為Zuul中的filter,想操作response的多了,有一個(gè)亂來(lái)的,其他人就啥都不要干了。
所以,第一軍規(guī):不要直接操作 response。
寫(xiě)出這樣的代碼,你已經(jīng)在犯錯(cuò)的邊緣了:
HttpServletResponse response = RequestContext.getCurrentContext().getResponse();
正確的姿勢(shì)是這樣的,通過(guò)RequestContext操作:
RequestContext ctx = RequestContext.getCurrentContext();
ctx.setResponseStatusCode(RESPONSE_STATUS_CODE_304);
ctx.setResponseGZipped(true);
ctx.setResponseBody(sb.toString());
2. ZuulFilter的順序
Zuul的設(shè)計(jì)可視化太差了,通過(guò)每個(gè)Filter的fitlerOrder返回,如下:
public int filterOrder() {
? ? ? return 0;
}
沒(méi)有一個(gè)統(tǒng)一的地方,可以看到所有的filter的順序,只有調(diào)試時(shí)才能知道,不人性。
正確的姿勢(shì),放在同一個(gè)Class里:
@Bean
public XxxFilter xxxFilter(){? ?return new XxxFilter().setPreOrder(1);? ?}
@Bean
public XxxFilter xxxFilter(){? ?return new XxxFilter().setPreOrder(2);? ?}
@Bean
public XxxFilter xxxFilter(){? ?return new XxxFilter().setPostOrder(1);? ?}
@Bean
public XxxFilter xxxFilter(){? ?return new XxxFilter().setPostOrder(2);? ?}
@Bean
public XxxFilter xxxFilter(){? ?return new XxxFilter().setPostOrder(3);? ?}
暫時(shí)這些。