序
zuul的SimpleHostRoutingFilter主要用来转发不走eureka的proxy,里头是使用httpclient来转发请求的,但是有时候我们需要改动相关httpclient的配置,这个时候,就需要修改SimpleHostRoutingFilter了,这里讲一下如何扩展SimpleHostRoutingFilter。
自定义SimpleHostRoutingFilter
比如把httpclient的CookieSpec设置为default,比如把SSLContext升级为TLSv1.2
public class CustomHostRoutingFilter extends SimpleHostRoutingFilter{
private static final Logger LOGGER = LoggerFactory.getLogger(CustomHostRoutingFilter.class);
@Value("${zuul.host.socket-timeout-millis}")
int SOCKET_TIMEOUT;
@Value("${zuul.host.connect-timeout-millis}")
int CONNECTION_TIMEOUT;
private ZuulProperties.Host hostProperties;
private boolean sslHostnameValidationEnabled;
private PoolingHttpClientConnectionManager connectionManager;
public CustomHostRoutingFilter(ProxyRequestHelper helper, ZuulProperties properties) {
super(helper, properties);
this.sslHostnameValidationEnabled = properties.isSslHostnameValidationEnabled();
this.hostProperties = properties.getHost();
LOGGER.error("CustomHostRoutingFilter init");
}
@Override
protected CloseableHttpClient newClient() {
final RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(SOCKET_TIMEOUT)
.setConnectTimeout(CONNECTION_TIMEOUT)
// 这里改为default
.setCookieSpec(CookieSpecs.DEFAULT).build();
HttpClientBuilder httpClientBuilder = HttpClients.custom();
if (!this.sslHostnameValidationEnabled) {
httpClientBuilder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
}
return httpClientBuilder.setConnectionManager(newConnectionManager())
.disableContentCompression()
.useSystemProperties().setDefaultRequestConfig(requestConfig)
.setRetryHandler(new DefaultHttpRequestRetryHandler(0, false))
.setRedirectStrategy(new RedirectStrategy() {
@Override
public boolean isRedirected(HttpRequest request,
HttpResponse response, HttpContext context)
throws ProtocolException {
return false;
}
@Override
public HttpUriRequest getRedirect(HttpRequest request,
HttpResponse response, HttpContext context)
throws ProtocolException {
return null;
}
}).build();
}
@Override
protected PoolingHttpClientConnectionManager newConnectionManager() {
try {
// 这里改为TLS
final SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, new TrustManager[] { new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates,
String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates,
String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
} }, new SecureRandom());
RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder
.<ConnectionSocketFactory> create()
.register(HTTP_SCHEME, PlainConnectionSocketFactory.INSTANCE);
if (this.sslHostnameValidationEnabled) {
registryBuilder.register(HTTPS_SCHEME,
new SSLConnectionSocketFactory(sslContext));
}
else {
registryBuilder.register(HTTPS_SCHEME, new SSLConnectionSocketFactory(
sslContext, NoopHostnameVerifier.INSTANCE));
}
final Registry<ConnectionSocketFactory> registry = registryBuilder.build();
this.connectionManager = new PoolingHttpClientConnectionManager(registry, null, null, null,
hostProperties.getTimeToLive(), hostProperties.getTimeUnit());
this.connectionManager
.setMaxTotal(this.hostProperties.getMaxTotalConnections());
this.connectionManager.setDefaultMaxPerRoute(
this.hostProperties.getMaxPerRouteConnections());
return this.connectionManager;
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
配置自定义的filter
@Configuration
@EnableZuulProxy
public class CustomZuulProxyConfig extends ZuulProxyConfiguration{
@Bean
@Override
public SimpleHostRoutingFilter simpleHostRoutingFilter(ProxyRequestHelper helper,
ZuulProperties zuulProperties) {
return new CustomHostRoutingFilter(helper, zuulProperties);
}
}
这样就大功告成了