现象:
网关服务调用业务服务检查健康状态,如果业务服务异常会等60s后才会超时,大量请求阻塞,导致网关服务不能正常响应。
image.png
排查日志:
requestid:8614012eb9d342ae83c4a8c0eb7203c1

选择服务节点5100-->服务不可用-->选择服务节点5101

判断服务可用性耗时60s,查看相关代码

@Override
public boolean isServerAvailable(Server server) {
    boolean isAvailable = false;
    // target 链接目标feign,并指定访问域名
    QuillFeignClient client = FeignClientUtil.getFeignClient(QuillFeignClient.class,
            "http://" + server.getId());
    try {
        String resp = client.getHealthInfo();
        if (resp != null) {
            JSONObject obj = JSONObject.parseObject(resp);
            if ("up".equals(obj.getString("status"))) {
                isAvailable = true;
            }
        }
    } catch (Exception e) {
        logger.info("服务不可用:" + server);
    }
    return isAvailable;
}

/**
 * 统一的 feign 接口实现类获取逻辑
 */
public static final <T> T getFeignClient(Class<T> clazz, String url) {
    T feignClient = Feign.builder()
            // 默认 http
            .client(new Client.Default(null, null))
            //3s超时,1次重试
            .retryer(new Retryer.Default(3000, 3000, 1))
            .target(clazz, url);
    return feignClient;
}

new Client.Default 默认options构造器
image.png82e97738-934c-4d18-a6a3-1ba61b4fedee.png
readTimeout默认耗时60s

调整超时时间:

/**
 * 统一的 feign 接口实现类获取逻辑
 */
public static final <T> T getFeignClient(Class<T> clazz, String url) {
    T feignClient = Feign.builder().options(new Request.Options(2L, TimeUnit.SECONDS, 2L, TimeUnit.SECONDS, true))
            // 默认 http
            .client(new Client.Default(null, null))
            .target(clazz, url);
    return feignClient;
}

connectTimeout: 2s ; readTimeout: 2s
去除重试逻辑,异常时客户端正常失败重试即可。

验证readTime,单元测试
调用方:

@Test
void getFeignClient() {
    QuillFeignClient client = FeignClientUtil.getFeignClient(QuillFeignClient.class,"http://localhost:8084");
    System.out.println(JSON.toJSONString(client.test()));
}

被调用方:

@ApiOperation("test")
@GetMapping("/test")
public RtData test(){
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return ResponseBuilder.success("666");
}

结果:

feign.RetryableException: Read timed out executing GET http://localhost:8084/api/test

at feign.FeignException.errorExecuting(FeignException.java:249)

可以验证参数配置生效