我们在项目中使用Spring云。我们有几个微服务,每个服务都有自己的.yml文件。
以下属性仅在zuul服务器
中hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
ribbon:
ConnectTimeout: 3000
ReadTimeout: 60000
测试1:
帐户服务:
这项服务是我打电话来测试超时的,我通过zuul调用请求,即使用端口8006。
@RequestMapping(value = "/accountholders/{cardHolderId}/accounts", produces = "application/json; charset=utf-8", method = RequestMethod.GET)
@ResponseBody
public AllAccountsVO getAccounts(@PathVariable("cardHolderId") final String cardHolderId,
@RequestHeader("userContextId") final String userContextId,
@RequestParam final MultiValueMap<String, String> allRequestParams, final HttpServletRequest request) {
return iAccountService.getCardHolderAccountsInfo(cardHolderId, userContextId, request, allRequestParams,
ApplicationConstants.ACCOUNTHOLDER);
}
上面的服务使用Spring RestTemplate在内部调用下面的服务。 我开始通过在关联服务中添加如下所示的5000毫秒的休眠时间进行测试,并向帐户服务(getAccounts调用)发出请求。
协会服务:
@RequestMapping(value = "/internal/userassociationstatus", produces = "application/json; charset=utf-8", consumes = "application/json", method = RequestMethod.GET)
@ResponseBody
public UserAssociationStatusVO getUserAssociationStatus(@RequestParam final Map<String, String> allRequestParams) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return iUserAssociationsService.getUserAssociationStatus(allRequestParams);
}
以下是我在关联服务
中遇到的错误org.apache.catalina.connector.ClientAbortException: java.io.IOException: An established connection was aborted by the software in your host machine
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:393) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:426) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:342) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
以下是我在帐户服务
中遇到的错误org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://USERASSOCIATIONS-V1/user/v1/internal/userassociationstatus?cardholderid=123&usercontextid=222&role=ACCOUNT": com.sun.jersey.api.client.ClientHandlerException: java.net.SocketTimeoutException: Read timed out; nested exception is java.io.IOException: com.sun.jersey.api.client.ClientHandlerException: java.net.SocketTimeoutException: Read timed out
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:607) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:475) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
如果我将睡眠时间保持为4500,则会给出响应,但如果是&gt; = 4800则会抛出上述异常。我认为这与Ribbon Timeouts无关,而是与其他相关。在某一点之后出现上述异常的任何具体原因。
测试2
然后我尝试直接在帐户服务中保持75000毫秒的睡眠时间,并删除睡眠时间关联服务。
@RequestMapping(value = "/accountholders/{cardHolderId}/accounts", produces = "application/json; charset=utf-8", method = RequestMethod.GET)
@ResponseBody
public AllAccountsVO getAccounts(@PathVariable("cardHolderId") final String cardHolderId,
@RequestHeader("userContextId") final String userContextId,
@RequestParam final MultiValueMap<String, String> allRequestParams, final HttpServletRequest request) {
try {
Thread.sleep(75000);
} catch (InterruptedException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
}
return iAccountService.getCardHolderAccountsInfo(cardHolderId, userContextId, request, allRequestParams,
ApplicationConstants.ACCOUNTHOLDER);
}
在这种情况下,我得到了#34;例外&#34;:&#34; com.netflix.zuul.exception.ZuulException&#34;,
在我的APIGateway(Zuul应用程序)日志中,我看到以下错误。
com.netflix.zuul.exception.ZuulException: Forwarding error
at org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter.forward(RibbonRoutingFilter.java:134) ~[spring-cloud-netflix-core-1.1.0.M5.jar:1.1.0.M5]
at org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter.run(RibbonRoutingFilter.java:76) ~[spring-cloud-netflix-core-1.1.0.M5.jar:1.1.0.M5]
at com.netflix.zuul.ZuulFilter.runFilter(ZuulFilter.java:112) ~[zuul-core-1.1.0.jar:1.1.0]
at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:197) ~[zuul-core-1.1.0.jar:1.1.0]
Caused by: com.netflix.hystrix.exception.HystrixRuntimeException: useraccounts-v1RibbonCommand timed-out and no fallback available.
at com.netflix.hystrix.AbstractCommand$16.call(AbstractCommand.java:806) ~[hystrix-core-1.4.23.jar:1.4.23]
at com.netflix.hystrix.AbstractCommand$16.call(AbstractCommand.java:790) ~[hystrix-core-1.4.23.jar:1.4.23]
at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$1.onError(OperatorOnErrorResumeNextViaFunction.java:99) ~[rxjava-1.0.14.jar:1.0.14]
at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:70) ~[rxjava-1.0.14.jar:1.0.14]
我认为这与Ribbon ConnectTimeout或ReadTimeout无关。此错误是由于属性&#34; execution.isolation.thread.timeoutInMilliseconds:60000&#34; 。我还将此属性减少到10000毫秒以测试行为,并且如果睡眠时间更长(例如:12000)则得到相同的异常。
我想了解Ribbon ConnectTimeout和Read-timeout vs Hystrix超时以及如何在我的应用程序中测试功能区超时。另外,如果我想为不同的微服务提供不同的超时,我是否将这些属性保存在各自的.yml文件中?有什么想法吗?
我正在尝试创建一个供我的团队使用的文档,以便开发人员可以轻松了解这些超时选项如何在Spring云中运行。
(这是一个冗长的描述,但为了更清楚,我必须详细写)
答案 0 :(得分:1)
功能区中的connectTimeout
和readTimeout
传递给底层HTTP客户端。它们适用于HTTP连接(一旦建立连接,就不应用HTTP请求)。我不确定你为什么需要像这样测试它,但是对于健康的服务器来说会很难。例如,对于connectTimeout
,您需要一个可以接受TCP连接但不能完成HTTP层连接的连接。对于readTimeout
,您需要一个建立连接,但不发送任何数据(根本)。