一、問題分析
之前在用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);
}
}
然後重新啓動,查看請求頭。
修改成功。所以說,學會通過看源碼查問題,還是很重要的哈~