Netflix / ribbon

Ribbon is a Inter Process Communication (remote procedure calls) library with built in software load balancers. The primary usage model involves REST calls with various serialization scheme support.
Apache License 2.0
4.58k stars 1.24k forks source link

ribbon 如何基于url配置特定的接口的超时时间 #474

Closed RonaldFletcher closed 8 months ago

RonaldFletcher commented 3 years ago

ribbon的超时设置,只能按转发的serviceId来分的,无法像nginx那样直接在每个转发的链接里头设置超时时间。

2775468731 commented 3 years ago

Ribbon is client load balancing

Anthony-byte commented 3 years ago

可以考虑通过拦截器,对请求进行定制 可以参考下: @Slf4j public class RestTempleteCustomizeInterceptor implements ClientHttpRequestInterceptor {

private Integer ribbonConnectTimeout;

private Integer ribbonReadTimeout;

Map<String, String> cache = new ConcurrentHashMap<String, String>();

public RestTempleteCustomizeInterceptor(Integer ribbonConnectTimeout, Integer ribbonReadTimeout) {
    this.ribbonConnectTimeout = ribbonConnectTimeout;
    this.ribbonReadTimeout = ribbonReadTimeout;
}

@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        String serviceId = request.getURI().getHost();
        restructRIbbonTimeOutConfig(request, serviceId,ribbonConnectTimeout,ribbonReadTimeout);
    Field clientFactoryField = null;
    Field dynamicPropertiesF = null;
    if(cache.containsKey(serviceId)){
        log.info("=================has cached===========");
        return execution.execute(request, body);
    }
    try {
        Field field = request.getClass().getDeclaredField("requestFactory");
        ReflectionUtils.makeAccessible(field);
        RibbonClientHttpRequestFactory RibbonClientHttpRequestFactory = (RibbonClientHttpRequestFactory)field.get(request);
        clientFactoryField = RibbonClientHttpRequestFactory.getClass().getDeclaredField("clientFactory");
        ReflectionUtils.makeAccessible(clientFactoryField);
        long start = System.currentTimeMillis();
        SpringClientFactory springClientFactory = (SpringClientFactory)clientFactoryField.get(RibbonClientHttpRequestFactory);
        DefaultClientConfigImpl iClientConfig =  (DefaultClientConfigImpl)springClientFactory.getClientConfig(serviceId);
        long end = System.currentTimeMillis();
        log.info("==========use:{}",end - start);
        dynamicPropertiesF =  iClientConfig.getClass().getDeclaredField("dynamicProperties");
        ReflectionUtils.makeAccessible(dynamicPropertiesF);
        Map<String, DynamicStringProperty> propertyMap =  (Map<String, DynamicStringProperty>)dynamicPropertiesF.get(iClientConfig);
        propertyMap.put(CommonClientConfigKey.ConnectTimeout.key(),new DynamicStringProperty(CommonClientConfigKey.ConnectTimeout.key(),connectTimeOut == null ? null:connectTimeOut.toString()));
        propertyMap.put(CommonClientConfigKey.ReadTimeout.key(),new DynamicStringProperty(CommonClientConfigKey.ReadTimeout.key(),readTimeOut == null ? null:readTimeOut.toString()));
        propertyMap.put(CommonClientConfigKey.OkToRetryOnAllOperations.key(),new DynamicStringProperty(CommonClientConfigKey.OkToRetryOnAllOperations.key(),"true"));
        propertyMap.put(CommonClientConfigKey.MaxAutoRetries.key(),new DynamicStringProperty(CommonClientConfigKey.MaxAutoRetries.key(),"1"));
        propertyMap.put(CommonClientConfigKey.MaxAutoRetriesNextServer.key(),new DynamicStringProperty(CommonClientConfigKey.MaxAutoRetriesNextServer.key(),"1"));
        cache.put(serviceId,serviceId);
    } catch (Exception e) {
        log.error("RestTempleteCustomizeInterceptor intercept error:{},serviceId:{}",e,serviceId);
    }
    return execution.execute(request, body);
}

}

RonaldFletcher commented 3 years ago

收到,非常的感谢,我研究下2021年3月26日 下午2:58,Anthony-byte @.***> 写道:以考虑通过拦截器,对请求进行定制

wangyouxiu commented 1 year ago

收到,非常的感谢,我研究下2021年3月26日 下午2:58,Anthony-byte @.***> 写道:以考虑通过拦截器,对请求进行定制 你好,请问你解决这个问题了吗