概述
序
ribbon的超时设置,只能按转发的serviceId来分的,无法像nginx那样直接在每个转发的链接里头设置超时时间。这里hack一下,实现url基本的ribbon超时时间设置。具体的思路就是重写RibbonApacheHttpRequest的toRequest方法,然后进行设置。
CustomRibbonApacheHttpRequest
package com.sunlord.zuul.configuration.ribbon;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.entity.BasicHttpEntity;
import org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpRequest;
import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext;
import java.util.Iterator;
import java.util.List;
import static org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer.Runner;
@Slf4j
public class CustomRibbonApacheHttpRequest extends RibbonApacheHttpRequest {
public CustomRibbonApacheHttpRequest(RibbonCommandContext context) {
super(context);
}
@Override
public HttpUriRequest toRequest(RequestConfig requestConfig) {
RequestBuilder builder = RequestBuilder.create(this.context.getMethod());
builder.setUri(this.uri);
Iterator var3 = this.context.getHeaders().keySet().iterator();
String name;
List values;
Iterator var6;
String value;
while(var3.hasNext()) {
name = (String)var3.next();
values = (List)this.context.getHeaders().get(name);
var6 = values.iterator();
while(var6.hasNext()) {
value = (String)var6.next();
builder.addHeader(name, value);
}
}
var3 = this.context.getParams().keySet().iterator();
while(var3.hasNext()) {
name = (String)var3.next();
values = (List)this.context.getParams().get(name);
var6 = values.iterator();
while(var6.hasNext()) {
value = (String)var6.next();
builder.addParameter(name, value);
}
}
if (this.context.getRequestEntity() != null) {
BasicHttpEntity entity = new BasicHttpEntity();
entity.setContent(this.context.getRequestEntity());
Long contentLength = this.context.getContentLength();
if (!"GET".equals(this.context.getMethod()) || contentLength != null && contentLength >= 0L) {
if (contentLength != null) {
entity.setContentLength(contentLength);
}
} else {
entity.setContentLength(0L);
}
builder.setEntity(entity);
}
Runner.customize(this.context.getRequestCustomizers(), builder);
//todo 这里处理个性的timeout信息
if(uri.getPath().equals("/cust/qryMyCustList4Page")){
log.info("requestConfig:{}", requestConfig);
RequestConfig.Builder configBuilder = RequestConfig.copy(requestConfig);
configBuilder.setConnectionRequestTimeout(20*1000);
configBuilder.setConnectTimeout(20*1000);
configBuilder.setSocketTimeout(20*1000);
builder.setConfig(configBuilder.build());
log.info("builder config:{}", builder.getConfig());
}else{
builder.setConfig(requestConfig);
}
log.info("builder:{}", builder);
return builder.build();
}
}
CustomHttpClientRibbonCommand
package com.sunlord.zuul.configuration.ribbon;
import org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpRequest;
import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient;
import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommand;
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, FallbackProvider zuulFallbackProvider) {
super(commandKey, client, context, zuulProperties, zuulFallbackProvider);
}
@Override
protected RibbonApacheHttpRequest createRequest() throws Exception {
RibbonApacheHttpRequest ribbonApacheHttpRequest = new CustomRibbonApacheHttpRequest(this.context);
return ribbonApacheHttpRequest;
}
}
CustomHttpClientRibbonCommandFactory
package com.sunlord.zuul.configuration.ribbon;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient;
import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommand;
import org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactory;
import java.util.Set;
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<FallbackProvider> fallbackProviders) {
super(clientFactory, zuulProperties, fallbackProviders);
this.clientFactory = clientFactory;
this.zuulProperties = zuulProperties;
}
@Override
public HttpClientRibbonCommand create(RibbonCommandContext context) {
FallbackProvider 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);
}
}
配置
package com.sunlord.zuul.configuration.ribbon;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import java.util.Collections;
import java.util.Set;
@Configuration
public class ConfigBean {
@Autowired(required = false)
private Set<FallbackProvider> zuulFallbackProviders = Collections.emptySet();
@Bean
@ConditionalOnMissingBean
public RibbonCommandFactory<?> ribbonCommandFactory(
SpringClientFactory clientFactory, ZuulProperties zuulProperties) {
return new CustomHttpClientRibbonCommandFactory(clientFactory, zuulProperties, zuulFallbackProviders);
}
}
网关的超时层级
zuul
zuul.host.socket-timeout-millis= 20000
zuul.host.connect-timeout-millis= 20000
ribbon
ribbon.ReadTimeout= 10000
ribbon.ConnectTimeout= 10000
ribbon.MaxAutoRetries=0
ribbon.MaxAutoRetriesNextServer=0
ribbon.OkToRetryOnAllOperations= false
hystrix
hystrix.command.default.execution.timeout.enabled=true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=20000
小结
走网关的话,有三层的超时时间,一个是zuul的,一个是ribbon的,还有一个是hystrix的。hystrix的超时设置,AbstractRibbonCommand这个类没有暴露设置hystrix的Setter方法出来,所以无法通过继承的方式来扩展。因此要自定义ribbon超时的话,需要这个超时时间是小于hystrix的,不然就提前被hystrix超时了,无法起到效果。
最后
以上就是美好学姐为你收集整理的ribbon设置url级别的超时时间的全部内容,希望文章能够帮你解决ribbon设置url级别的超时时间所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复