Spring Cloud Zuul閘道器修改為短連線方法

語言: CN / TW / HK

一起養成寫作習慣!這是我參與「掘金日新計劃 · 4 月更文挑戰」的第15天,[點選檢視活動詳情]

一、問題分析

之前在用zuul閘道器的時候,請求幾次然後連線就斷開了。原因是因為http1.1之後,預設走的都是connection=keep-alive 長連線。但沒有心跳維持,顧1分鐘斷開一次。但RestFul一般都是走短連線就行了。因此想著只要修改頭部connection屬性就行了.

就是在過濾器中修改Zuul的RequestContext ctx物件

//設定請求為短連線 ctx.addZuulRequestHeader("connection", "close");

再次請求之後發現

納尼,怎麼還是長連線。那麼說明可能是我的設定沒有生效或者被覆蓋掉了。遇到問題,除了度娘,跟著原始碼走一遭也是最好的方式。花了大半天時間,終於讓我找到原因了。

原因是代理類ProxyRequestHelper裡面有段邏輯。

public boolean isIncludedHeader(String headerName) { String name = headerName.toLowerCase(); RequestContext ctx = RequestContext.getCurrentContext(); if (ctx.containsKey(IGNORED_HEADERS)) { Object object = ctx.get(IGNORED_HEADERS); if (object instanceof Collection && ((Collection<?>) object).contains(name)) { return false; } } switch (name) { case "host": if(addHostHeader) { return true; } case "connection": case "content-length": case "server": case "transfer-encoding": case "x-application-context": return false; default: return true; } }

如果頭部存在"connection": "content-length": "server": "transfer-encoding": "x-application-context"這些頭的話都被跳過。不會被設定成功。應該是zuul自己的一個機制把。

二、解決方式

那麼問題找到了,該怎麼修改呢?那麼只能自定義路由了。繼承並重寫這個類。

1、實現自定義路由配置CustomZuulConfig

``` @Component public class CustomZuulConfig {

@Autowired
ZuulProperties zuulProperties;

@Value("${servletPath}")
private String servletPath;

@Bean
public CustomRouteLocator routeLocator() {
    CustomRouteLocator routeLocator = new CustomRouteLocator(servletPath, this.zuulProperties);
    return routeLocator;
}

} ```

2、實現自定義請求代理工具類 重寫isIncludedHeader方法。

public class CustomRequestHelper extends ProxyRequestHelper { @Override public boolean isIncludedHeader(String headerName) { String name = headerName.toLowerCase(); RequestContext ctx = RequestContext.getCurrentContext(); if (ctx.containsKey(IGNORED_HEADERS)) { Object object = ctx.get(IGNORED_HEADERS); if (object instanceof Collection && ((Collection<?>)object).contains(name)) { return false; } } switch (name) { case "content-length": case "host": case "server": case "transfer-encoding": case "x-application-context": return false; default: return true; } } }

3、重寫實現代理配置類

``` @Configuration @EnableZuulProxy public class CustomZuulProxyConfig extends ZuulProxyAutoConfiguration {

@Bean
@Override
public SimpleHostRoutingFilter simpleHostRoutingFilter(ProxyRequestHelper helper, ZuulProperties zuulProperties,
        ApacheHttpClientConnectionManagerFactory connectionManagerFactory,
        ApacheHttpClientFactory httpClientFactory) {
    CustomRequestHelper customRequestHelper = new CustomRequestHelper();
    return new SimpleHostRoutingFilter(customRequestHelper, zuulProperties, connectionManagerFactory,
            httpClientFactory);
}

} ```

然後重新啟動,檢視請求頭。

修改成功。所以說,學會通過看原始碼查問題,還是很重要的哈~