Updating from RC1 to RELEASE has broken our client configuration, specifically timeouts.
Here's the relevant bit of @RibbonClient configuration:
@Bean
public RestClient ribbonRestClient(IClientConfig config, ILoadBalancer loadBalancer, HttpClient httpClient) {
RestClient client = new RestClient(loadBalancer, config);
client.setJerseyClient(new ApacheHttpClient4(new ApacheHttpClient4Handler(httpClient, null, false)));
return client;
}
The input HttpClient has been configured with (among other things) an appropriate SSLContext and connectionRequest/connect/socket timeouts of 1500/15000/15000.
I am testing with a server (in python) that accepts connections but then does nothing with them.
In Brixton.RC1, a request via a @LoadBalanced RestTemplate throws a SocketTimeoutException, and execution passes through RestClient#execute(HttpRequest, IClientConfig).
execute:527, RestClient {com.netflix.niws.client.http}
executeInternal:86, RibbonHttpRequest {org.springframework.cloud.netflix.ribbon}
execute:53, AbstractClientHttpRequest {org.springframework.http.client}
execute:93, InterceptingClientHttpRequest$InterceptingRequestExecution {org.springframework.http.client}
intercept:65, MetricsClientHttpRequestInterceptor {org.springframework.cloud.netflix.metrics}
execute:85, InterceptingClientHttpRequest$InterceptingRequestExecution {org.springframework.http.client}
executeInternal:69, InterceptingClientHttpRequest {org.springframework.http.client}
executeInternal:48, AbstractBufferingClientHttpRequest {org.springframework.http.client}
execute:53, AbstractClientHttpRequest {org.springframework.http.client}
doExecute:596, RestTemplate {org.springframework.web.client}
execute:572, RestTemplate {org.springframework.web.client}
exchange:523, RestTemplate {org.springframework.web.client}
In Brixton.RELEASE, an identical request hangs forever down in SocketInputStream, and execution does not pass through RestClient at all.
socketRead0:-1, SocketInputStream {java.net}
socketRead:116, SocketInputStream {java.net}
read:170, SocketInputStream {java.net}
read:141, SocketInputStream {java.net}
readFully:465, InputRecord {sun.security.ssl}
read:503, InputRecord {sun.security.ssl}
readRecord:973, SSLSocketImpl {sun.security.ssl}
performInitialHandshake:1375, SSLSocketImpl {sun.security.ssl}
startHandshake:1403, SSLSocketImpl {sun.security.ssl}
startHandshake:1387, SSLSocketImpl {sun.security.ssl}
afterConnect:559, HttpsClient {sun.net.www.protocol.https}
connect:185, AbstractDelegateHttpsURLConnection {sun.net.www.protocol.https}
connect:153, HttpsURLConnectionImpl {sun.net.www.protocol.https}
executeInternal:80, SimpleBufferingClientHttpRequest {org.springframework.http.client}
executeInternal:48, AbstractBufferingClientHttpRequest {org.springframework.http.client}
execute:53, AbstractClientHttpRequest {org.springframework.http.client}
execute:93, InterceptingClientHttpRequest$InterceptingRequestExecution {org.springframework.http.client}
apply:54, LoadBalancerInterceptor$1 {org.springframework.cloud.client.loadbalancer}
apply:1, LoadBalancerInterceptor$1 {org.springframework.cloud.client.loadbalancer}
execute:89, RibbonLoadBalancerClient {org.springframework.cloud.netflix.ribbon}
intercept:46, LoadBalancerInterceptor {org.springframework.cloud.client.loadbalancer}
execute:85, InterceptingClientHttpRequest$InterceptingRequestExecution {org.springframework.http.client}
intercept:65, MetricsClientHttpRequestInterceptor {org.springframework.cloud.netflix.metrics}
execute:85, InterceptingClientHttpRequest$InterceptingRequestExecution {org.springframework.http.client}
executeInternal:69, InterceptingClientHttpRequest {org.springframework.http.client}
executeInternal:48, AbstractBufferingClientHttpRequest {org.springframework.http.client}
execute:53, AbstractClientHttpRequest {org.springframework.http.client}
doExecute:596, RestTemplate {org.springframework.web.client}
execute:572, RestTemplate {org.springframework.web.client}
exchange:523, RestTemplate {org.springframework.web.client}
What changed, and how do we fix it?
Comment From: OrangeDog
Behaviour in RC2 is the same as RELEASE, but I didn't notice before due to #986.
Comment From: OrangeDog
OK, it appears it now just uses what the annotated RestTemplate is configured with, which is good I guess.
There's no reason I can see to ever override the RestClient now?
Perhaps RibbonClientConfiguration should make that clear?
A better changelog (and one that's easier to find) would help in future for highlighting breaking changes too.
@Bean @LoadBalanced
public RestTemplate restTemplate(HttpClient httpClient) {
return new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient));
}
Comment From: dsyer
I'm not sure I understand the problem enough to document it. Would you like to suggest something?
Comment From: OrangeDog
The "problem" is that @LoadBalanced RestTemplates no longer override the template's client with the load balancer's RestClient.
It seems like a very good change, but it was a very breaking change.
Comment From: spencergibb
By default we no longer use ribbon's RestClient by default. It's old and is missing functionality like patch.
Comment From: OrangeDog
@spencergibb that's great, but I missed the memo on this breaking change, and RibbonClientConfiguration is still constructing one.
Comment From: OlgaMaciaszek
This module has entered maintenance mode. This means that the Spring Cloud team will no longer be adding new features to the module. We will fix blocker bugs and security issues, and we will also consider and review small pull requests from the community.