SpringCloud--组件超时配置

最近在使用spring cloud 搭建一个微服务项目,因为需要调用第三方接口,且延迟可能较高,

特意写了个测试接口测试30秒左右延迟能否正常处理,请求中途会在zuul的gate-service 中断于15秒左右,

并抛出如下异常

com.netflix.zuul.exception.ZuulException: Forwarding error
    ...
    ...
    ...

Caused by: com.netflix.hystrix.exception.HystrixRuntimeException: api-service timed-out and no fallback available.
    ...
    ...
    ...

修改了多次配置都未生效,于是就仔细研究了一下cloud中的各种组件的超时配置并整理如下

 

 


RestTemplate的超时

@Bean
@LoadBalanced
//不管是否有@LoadBalanced注解,都可以使用如下方式设置超时
public	RestTemplate restTemplate(){
     
	SimpleClientHttpRequestFactory simpleClientHttpRequestFactory = new SimpleClientHttpRequestFactory();
	simpleClientHttpRequestFactory.setConnectTimeout(1000);
	simpleClientHttpRequestFactory.setReadTimeout(1000);
	return new RestTemplate(simpleClientHttpRequestFactory);
}

Ribbon的超时

#全局设置

ribbon:
ReadTimeout: 40000 #单位ms
ConnectTimeout: 40000 #单位ms

#局部设置

#Ribbon所使用的虚拟主机名,

#一般和Eureka Server上注册的服务名称一致,

#即与spring.application.name一致

:
ribbon:
ReadTimeout: 40000 #单位ms
ConnectTimeout: 40000 #单位ms


Fegin的超时

1、Edgware之前版本,可实例化一个类型为feign.Request.Options的bean,

参考org.springframework.cloud.netflix.ribbon.FeignRibbonClientAutoConfiguration#feignRequestOptions中的写法

@Bean 
Request.Options feignOptions() { 
	return new Request.Options(/**connectTimeoutMillis**/1000, /** readTimeoutMillis **/1000); 
}
//超时时间设置,开启重试机制,默认为5次(包含首次请求)
package com.example.demo;
import feign.Request;
import feign.Retryer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignConfigure {
     
	public static int connectTimeOutMillis = 12000;//超时时间
     	public static int readTimeOutMillis = 12000;
     	@Bean
     	public Request.Options options() {
     
     		return new Request.Options(connectTimeOutMillis, readTimeOutMillis);
     	}
     	@Bean
     	public Retryer feignRetryer() {
     
		return new Retryer.Default();
     	}
}

2、Spring Cloud Edgware开始,可使用如下配置属性进行设置

feign:
  client:
    config:
      :	#使用@FeignClient注解的对应FeignClient接口名,如果写成default,则表示通用配置
        connectTimeout: 30000 # 连接超时设置,单位ms
        readTimeout: 30000  #读取超时设置,单位ms

一般feignClient都会跟随熔断器Hystrix一起使用,所以就需要同时配置下面Hystrix的超时设置


Hystrix的超时

hystrix:
  command:
    : #Hystrix Command一般情况下与一致,即实施远程调用的FeignClient名,如设置为default则表示通用设置
      execution:
        timeout:
          enabled: true #超时开关,默认开启,即true
        isolation:
          thread:
            timeoutInMilliseconds: 30000  #超时时间设置,单位ms

Zuul的超时

因为Zuul整合了Ribbon以及Hystrix,超时比较复杂,

分为以下两种情况

1、路由使用Ribbon及Hystrix

Zuul路由配置如下

zuul:
  routes:
    api-service:            	#给路由起的別名,可任意起名,一般与服务同名
      path: /gameapi/**     	#设置对应的路径,可以将请求地址由/api-service/**换成/gameapi/**来进行调用
      serviceId: api-service	#指定

此时,Zuul的超时与Ribbon、Hystrix相关,需要使用如下配置设置超时

hystrix:
  command:
    default:	#hystrix的通用超时配置
      execution:
        isolation:
          strategy: THREAD
          thread:
            timeoutInMilliseconds: 40000

    #和ribbon配合使用,必须单独配置指定路由,上面的default超时配置未能生效
    api-service:		#可在Hystrix Dashboard 上看到,大部分情况下与相同
      execution:
        isolation:
          strategy: THREAD
          thread:
            timeoutInMilliseconds: 40000

#全局配置ribbon超时
ribbon:
  ReadTimeout: 40000      #单位ms
  ConnectTimeout: 40000   #单位ms

#单独配置指定路由的ribbon超时
api-service:
  ribbon:
    ReadTimeout: 40000
    ConnectTimeout: 40000

代码解析
此种情况下,Zuul转发所使用的过滤器是 org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter
在这个过滤器中,整合了Hystrix以及Ribbon。

2、路由未使用Ribbon

Zuul路由配置如下

zuul:
  routes:
    api-service:			#给路由起的別名,可任意起名
      url: http://localhost:9002/	#指定的url
      path: /gameapi/**     		#url对应的路径,将/gameapi/**映射到http://localhost:9002/**

需要注意的是,
使用这种方式配置的路由不会作为HystrixCommand执行,
同时也不能使用Ribbon来负载均衡多个URL。
(题外话:如果希望不破坏Zuul的Hystrix、Ribbon特性,可以为Ribbon禁用Eureka )

此时的Zuul的超时只与如下两个配置相关

zuul:
  host:
    socket-timeout-millis: 40000
    connect-timeout-millis: 40000

代码解析
直接配置URL路由的方式,用不上Ribbon,也用不上Hystrix,
Zuul转发所使用的过滤器是org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter
在这个过滤器中,Zuul使用Apache HttpClient进行转发。

在现实场景中,有时候可能两种路由方式配合使用,因此,建议大家配置以上所有属性。


可参考链接加深理解

Spring Cloud组件那么多超时设置,如何理解和运用?

Zuul超时问题,微服务响应超时,zuul进行熔断

Feign的超时与重试设置(SpringCloud2.0)

Spring Cloud各组件超时总结

 

github上的议题

Read Timeout on Request #321

Setting up Ribbon's Connection timeout in microservice environment #3323

你可能感兴趣的:(JAVA,Spring)