Gateway中使用RestTemplate调用Gateway地址ReadTimeOut

1. 问题描述

在Gateway网关编写通用GlobalFilter的功能,需要在网关中调用后端服务的鉴权接口,就直接用RestTemplate调用了网关的地址,再由网关路由到后端服务,再本地测试没有问题,当上到开发,测试环境时,服务地址经常报RestTemplate请求接口ReadTimeOut的错误,而且网关就卡住了。

2. 问题排查

2.1 有问题的写法

再网关中直接调用网关的地址

1
2
3
4
5
6
7
8
9
10
11
@Component
public class XxxFilter implements GlobalFilter, Ordered {

@Resource
private RestTemplate customRestTemplate;

private void fun() {
// authUrl为网关的地址
String forObject = customRestTemplate.getForObject(String.format(CHECK_TOKEN_URL, authUrl, token), String.class);
}
}

2.2 修改后的写法

既然已经在网关的代码里了,就不需要再去请求网关的外部地址,直接通过负载均衡类提供的方法获取一个内部地址,然后直接调用这个内部地址就可以了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Component
public class XxxFilter implements GlobalFilter, Ordered {

@Resource
private RestTemplate customRestTemplate;
@Resource
private LoadBalancerClient loadBalancerClient;

private void fun() {
// 通过loadBalancerClient来获取一个内部地址
ServiceInstance auth = loadBalancerClient.choose("auth");
if (auth != null) {
String authUrl = auth.getUri().toString();
String forObject = customRestTemplate.getForObject(String.format(CHECK_TOKEN_URL, authUrl, token), String.class);
}
}
}