由于最近在使用Spring Cloud的Zuul网关的过程中,发现超时的可能性很多,出于性能的调优,所有想通过测试,了解一些参数的作用。在文章最后贴上推荐方案。
先看一个问题:
execution.isolation.thread.timeoutInMilliseconds
到达当前时间后,会触发熔断,调用fallback方法,如果不存在fallback方法,会报错误
1 | { |
结果:
1 | com.netflix.zuul.exception.ZuulException: Forwarding error |
说明:下面zuul是网关配置,service是网关代理下的一个服务
Case1
zuul,延时3s
1 | ribbon: |
service,延时2s
第一次访问的时候
1 | com.netflix.zuul.exception.ZuulException: Forwarding error |
第二次访问的时候
1 | com.netflix.zuul.exception.ZuulException: Forwarding error |
Case2
zuul,延时3s
1 | ribbon: |
service,延时2s
1 | com.netflix.zuul.exception.ZuulException: Forwarding error |
Case3
zuul,延时3s
1 | ribbon: |
service,延时0.5s
正常
Case4
zuul,延时3s
1 | ribbon: |
service,延时2s
1 | hystrix: |
1 | com.netflix.zuul.exception.ZuulException: Forwarding error |
结论:
- hystrix超时时间在配置文件中配置时无效的
1 | hystrix: |
- hystrix默认超时时间四1s,如果服务执行时间超过1s就会进行熔断,如果没有fallback,就会导致TIMEOUT错误
Case5
zuul,延时3s
1 | ribbon: |
service,延时0.5s
正常
Case6
zuul,延时3s
1 | ribbon: |
service,延时0.5s
1 | com.netflix.zuul.exception.ZuulException: Forwarding error |
Case7
zuul,延时3s
1 | ribbon: |
service,延时0.5s
正常
结论:
- ribbon.readtimeout超时会导致
SocketTimeoutException: Read timed out
问题。
Case8
zuul,延时3s
1 | ribbon: |
service,延时0.5s
正常
结论:socket-timeout-millis对请求时间没有影响
Case9
zuul,延时3s
1 | hystrix: |
service,延时0.5s
正常
Case10
zuul,延时3s
1 | hystrix: |
service,延时0.5s
1 | com.netflix.zuul.exception.ZuulException: Forwarding error |
结论:
- Hystrix的超时时间是对次节点的请求时间的进行熔断
zuul,延时3s
service,延时0.5s
1 | Caused by: com.netflix.hystrix.exception.HystrixRuntimeException: hystrix-example could not be queued for execution and no fallback available. |
总结:
- Hystrix的超时配置是服务调用其他服务时候,有效,对服务自身是没有作用。e.g. A->B,是对A请求B这个请求有效,对访问A本身的请求是没有作用的。
- 网关在启动初期,会存在不稳定,甚至存在马上熔断的可能,但在之后,会恢复正常水平。
com.netflix.client.ClientException: Load balancer does not have available server for client: hystrix-example
是服务启动还没完全,或者,如果使用了ribbon.eureka.eabled=false
也会出现这个问题。- 服务启动时候,推荐网关最后启动
推荐使用方案:
1 | zuul: |
注意说明:
timeout-in-milliseconds
这样编写是不会生效的,需要改为timeoutInMilliseconds
,起初认为是Spring的BUG,之后,发现由于default是一个key,是一个Map类型,依照源码中使用的是timeoutInMilliseconds
,所以必须timeoutInMilliseconds
。
拓展学习:
http://www.spring4all.com/article/351
http://m635674608.iteye.com/blog/2389666
http://tietang.wang/2016/02/25/hystrix/Hystrix%E5%8F%82%E6%95%B0%E8%AF%A6%E8%A7%A3/
https://github.com/spring-cloud/spring-cloud-netflix/issues/327