我们项目springcloud feign+ribbon+consul+zuul,正常的点击访问没有问题,
当进行jemeter压力测试的时候,一旦并发上去,访问此时超过100多万以后,就会出现以下错误:
Caused by: feign.RetryableException: Read timed out executing POST http://。。。。
at feign.FeignException.errorExecuting(FeignException.java:132) ~[feign-core-10.2.3.jar!/:na]
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:113) ~[feign-core-10.2.3.jar!/:na]
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78) ~[feign-core-10.2.3.jar!/:na]
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) ~[feign-core-10.2.3.jar!/:na]
at com.sun.proxy.$Proxy144.foreignExchange(Unknown Source) ~[na:na]
at sun.reflect.GeneratedMethodAccessor87.invoke(Unknown Source) ~[na:na]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
... 60 common frames omitted
Caused by: java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method) ~[na:1.8.0_11]
at java.net.SocketInputStream.read(SocketInputStream.java:150) ~[na:1.8.0_11]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_11]
at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_11]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) ~[spring-webmvc-5.1.9.R
经过网络查询排查给的方案是配ribbon的超时时间:
#hystrix的超时时间
hystrix:
command:
default:
execution:
timeout:
enabled: true
isolation:
thread:
timeoutInMilliseconds: 30000
#ribbon的超时时间
ribbon:
ReadTimeout: 30000
ConnectTimeout: 30000
于是按照这个方法做了修改,但是没有效果。
最后再排查的时候发现Caused by: java.net.SocketTimeoutException: Read timed out的原因是由于http访问的SocketTimeout没有配,所以就想办法把sockeTimeout的参数配上具体如下:
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(30000) //从连接池中获取连接的超时时间//与服务器连接超时时间:httpclient会创建一个异步线程用以创建socket连接,此处设置该socket的连接超时时间.setConnectTimeout(30000)
.setSocketTimeout(30000) //socket读数据超时时间:从服务器获取响应数据的超时时间.build();HttpClient httpClient = HttpClientBuilder.create()
.setMaxConnTotal(500) //连接池中最大连接数/*** 分配给同一个route(路由)最大的并发连接数。* route:运行环境机器 到 目标机器的一条线路。* 举例来说,我们使用HttpClient的实现来分别请求 www.baidu.com 的资源和 www.bing.com 的资源那么他就会产生两个route。*/.setDefaultRequestConfig(requestConfig)
.build();HttpComponentsClientHttpRequestFactory httpRequestFactory = newHttpComponentsClientHttpRequestFactory();httpRequestFactory.setReadTimeout(60000);httpRequestFactory.setConnectTimeout(60000);httpRequestFactory.setHttpClient(httpClient);
然后再跑测试,次问题就解决了;
最后看了下异常信息, Read timed out executing POST 的原因是由于下边的Caused by: java.net.SocketTimeoutException: Read timed out导致的,所以只要把下边的socket的超时问题解决,上边的timeout问题也就会解决。