Ribbon使用笔记和问题

15 篇文章 1 订阅
  1. 老的客户端是用服务端依赖swagger-codegen-maven-plugin在打包的时候自动生成的,服务接口调用本质上是用的restTemplate
  2. 切换为微服务以后,只需要在restTemplate上面加一个@LoadBalanced注解即可根据服务名调用

遇到的问题

1.provider并发不足,会进入熔断短路状态:Hystrix circuit short-circuited and is OPEN
consumer会一直重试,可能会让provider奔溃,所以consumer应该在provider返回熔断错误以后一段时间内不再调用provider,等provider恢复以后再调用
处理方案:我的consumer业务场景是MQ消费消息做离线任务处理,在自定义RestTemplate的errorHandler中识别出provider出现500错误以后休眠30秒
也可以在LoadBalancerInterceptor拦截器中处理,也可以自己重写调用方法并加上HystrixCommand熔断方法

2.MQ消费是多线程消费,在程序启动的时候经常出现nested exception is java.net.UnknownHostException
原因:推测是因为Ribbon进行客户端负载均衡的Client并不是在服务启动的时候就初始化好的,而是在调用的时候才会去创建相应的Client
解决方案:ribbon有一个eager-load配置项,启用以后可以在实例化类以后提前创建好client

ribbon:
  ReadTimeout: 60000
  ConnectTimeout: 10000
  MaxAutoRetries: 0
  MaxAutoRetriesNextServer: 1
  OkToRetryOnAllOperations: true
  ServerListRefreshInterval: 3000 #刷新服务列表的时间
  eureka:
    enabled: true
  restclient:
    enabled: true
  http:
    client:
      enabled: true
  # 懒加载,启动时创建
  eager-load:
    clients: data-service
    enabled: true
 @Autowired
    @Qualifier("loadBalanced")
    @LoadBalanced
    private RestTemplate loadBalanced;

    public @Bean
    ApiClient apiClient() throws Exception {
        ApiClient c = new ApiClient(apiClientRestTemplate());
        c.setBasePath(basePath);
        return c;
    }


    private RestTemplate apiClientRestTemplate() {
        ResponseErrorHandler errorHandler = apiClientErrorHandler();
        loadBalanced.setErrorHandler(errorHandler);
        return loadBalanced;
    }

    private ResponseErrorHandler apiClientErrorHandler() {
        return new ResponseErrorHandler() {

            @Override
            public boolean hasError(ClientHttpResponse response) throws IOException {
                // return !response.getStatusCode().is2xxSuccessful();
                HttpStatus status = response.getStatusCode();
                return status.is4xxClientError() || status.is5xxServerError();
            }

            @Override
            public void handleError(ClientHttpResponse response) throws IOException {
                try (InputStream in = response.getBody()) {
                    String errorStr = IOUtils.toString(in);
                    log.error(errorStr);
                    // 系统异常,阻塞休眠30秒, 可以写入到配置文件
                    if(response.getStatusCode().is5xxServerError()){
                        try {
                            TimeUnit.SECONDS.sleep(30);
                        } catch (InterruptedException e) {
                            log.error("", e);
                        }
                    }
                } catch (Exception e) {
                    log.error("{}", e);
                }
                throw new RuntimeException("系统繁忙,请稍后再试");
            }
        };
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值