ribbon的超時設置,只能按轉發的serviceId來分的,沒法像nginx那樣直接在每一個轉發的連接裏頭設置超時時間。這裏hack一下,實現url基本的ribbon超時時間設置。具體的思路就是重寫RibbonApacheHttpRequest的toRequest方法,而後進行設置。nginx
public class CustomRibbonApacheHttpRequest extends RibbonApacheHttpRequest { public CustomRibbonApacheHttpRequest(RibbonCommandContext context) { super(context); } @Override public HttpUriRequest toRequest(RequestConfig requestConfig) { final RequestBuilder builder = RequestBuilder.create(this.context.getMethod()); builder.setUri(this.uri); for (final String name : this.context.getHeaders().keySet()) { final List<String> values = this.context.getHeaders().get(name); for (final String value : values) { builder.addHeader(name, value); } } for (final String name : this.context.getParams().keySet()) { final List<String> values = this.context.getParams().get(name); for (final String value : values) { builder.addParameter(name, value); } } if (this.context.getRequestEntity() != null) { final BasicHttpEntity entity; entity = new BasicHttpEntity(); entity.setContent(this.context.getRequestEntity()); // if the entity contentLength isn't set, transfer-encoding will be set // to chunked in org.apache.http.protocol.RequestContent. See gh-1042 if (this.context.getContentLength() != null) { entity.setContentLength(this.context.getContentLength()); } else if ("GET".equals(this.context.getMethod())) { entity.setContentLength(0); } builder.setEntity(entity); } customize(this.context.getRequestCustomizers(), builder); //todo 這裏處理個性的timeout信息 if(uri.getPath().equals("/review/timeout")){ RequestConfig.Builder configBuilder = RequestConfig.copy(builder.getConfig()); configBuilder.setConnectionRequestTimeout(30*1000); configBuilder.setConnectTimeout(30*1000); configBuilder.setSocketTimeout(30*1000); builder.setConfig(configBuilder.build()); }else{ builder.setConfig(requestConfig); } return builder.build(); } }
public class CustomHttpClientRibbonCommand extends HttpClientRibbonCommand { public CustomHttpClientRibbonCommand(String commandKey, RibbonLoadBalancingHttpClient client, RibbonCommandContext context, ZuulProperties zuulProperties) { super(commandKey, client, context, zuulProperties); } public CustomHttpClientRibbonCommand(String commandKey, RibbonLoadBalancingHttpClient client, RibbonCommandContext context, ZuulProperties zuulProperties, ZuulFallbackProvider zuulFallbackProvider) { super(commandKey, client, context, zuulProperties, zuulFallbackProvider); } @Override protected RibbonApacheHttpRequest createRequest() throws Exception { RibbonApacheHttpRequest ribbonApacheHttpRequest = new CustomRibbonApacheHttpRequest(this.context); return ribbonApacheHttpRequest; } }
public class CustomHttpClientRibbonCommandFactory extends HttpClientRibbonCommandFactory{ private final SpringClientFactory clientFactory; private final ZuulProperties zuulProperties; public CustomHttpClientRibbonCommandFactory(SpringClientFactory clientFactory, ZuulProperties zuulProperties) { super(clientFactory, zuulProperties); this.clientFactory = clientFactory; this.zuulProperties = zuulProperties; } public CustomHttpClientRibbonCommandFactory(SpringClientFactory clientFactory, ZuulProperties zuulProperties, Set<ZuulFallbackProvider> fallbackProviders) { super(clientFactory, zuulProperties, fallbackProviders); this.clientFactory = clientFactory; this.zuulProperties = zuulProperties; } @Override public HttpClientRibbonCommand create(RibbonCommandContext context) { ZuulFallbackProvider zuulFallbackProvider = getFallbackProvider(context.getServiceId()); final String serviceId = context.getServiceId(); final RibbonLoadBalancingHttpClient client = this.clientFactory.getClient( serviceId, RibbonLoadBalancingHttpClient.class); client.setLoadBalancer(this.clientFactory.getLoadBalancer(serviceId)); return new CustomHttpClientRibbonCommand(serviceId, client, context, zuulProperties, zuulFallbackProvider); } }
@Autowired(required = false) private Set<ZuulFallbackProvider> zuulFallbackProviders = Collections.emptySet(); @Bean @ConditionalOnMissingBean public RibbonCommandFactory<?> ribbonCommandFactory( SpringClientFactory clientFactory, ZuulProperties zuulProperties) { return new CustomHttpClientRibbonCommandFactory(clientFactory, zuulProperties, zuulFallbackProviders); }
zuul: max: host: connections: 500 host: socket-timeout-millis: 60000 connect-timeout-millis: 60000
ribbon: ReadTimeout: 10000 ConnectTimeout: 10000 MaxAutoRetries: 0 MaxAutoRetriesNextServer: 1 eureka: enabled: true
hystrix: command: default: execution: timeout: enabled: true isolation: thread: timeoutInMilliseconds: 60000
走網關的話,有三層的超時時間,一個是zuul的,一個是ribbon的,還有一個是hystrix的。hystrix的超時設置,AbstractRibbonCommand這個類沒有暴露設置hystrix的Setter方法出來,因此沒法經過繼承的方式來擴展。所以要自定義ribbon超時的話,須要這個超時時間是小於hystrix的,否則就提早被hystrix超時了,沒法起到效果。apache