LoadBalanced的RestTemplate用法 #
开发中,偶尔会碰到以下的情况
某个web应用提供的某个http接口,刚好满足了我的需求,我需要调用它
它是个web服务,所以它没有提供RPC接口
,我不能像调用Remote接口一样调用它
而直接通过写死ip:port
的方式来调用,显然也是不行的( 容器重新发布后ip会变化 )
这时候,你可能会选择通过 http://{域名}/{path}
的方式来调用。
这种方式的确是可行的,但是我们生产环境的机器一般都是在同一个内网的,通过域名的方式调用,是从外网兜了一圈,经过网关,再访问到web
这样肯定会增加耗时以及资源消耗
这时候你可能会问,那么有没有一种方式可以通过内网访问,客户端又不用关心服务端的ip呢?
显然答案是肯定的。
通过调研发现,通过 @LoadBalanced
注解的 RestTemplate
的Bean,可以作为 Load Balancer Client
来使用
下面提供demo:
服务端 #
// 服务端提供的需要被调用的接口 服务端应用名称为:duiba-test-web
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("/testLoadBalanced")
public String testLoadBalanced() {
return "loadBalanced invoke success!";
}
}
客户端 #
// 配置类
@Configuration
public class RestTemplateConfiguration {
// 具有 Load Balancer Client 特性的 RestTemplate
@LoadBalanced
@Bean
public RestTemplate loadBalancedRestTemplate(HttpClient httpClient) {
return this.getRestTemplate(httpClient);
}
// 普通的 RestTemplate
@Bean
public RestTemplate restTemplate(HttpClient httpClient) {
return this.getRestTemplate(httpClient);
}
private RestTemplate getRestTemplate(HttpClient httpClient) {
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectionRequestTimeout(3000);
httpRequestFactory.setConnectTimeout(3000);
httpRequestFactory.setReadTimeout(15000);
httpRequestFactory.setHttpClient(httpClient);
return new RestTemplate(httpRequestFactory);
}
}
// 客户端控制器
@RequestMapping("/testLoadBalanced")
@RestController
public class TestLoadBalancedController {
@Resource
private RestTemplate loadBalancedRestTemplate;
@GetMapping("/test")
public String test() {
return loadBalancedRestTemplate.getForObject("http://duiba-test-web/test/testLoadBalanced", String.class);
}
}
以上代码,跑通后,通过访问客户端的 /testLoadBalanced/test
接口,可以成功调用服务端,并且得到 【loadBalanced invoke success!】 的输出结果
在明确了使用方式后,还需要注意:
1、通过 @LoadBalanced
注解的 RestTemplate
的Bean (loadBalancedRestTemplate) 只能发起 http://{appName}/{path}
的请求,不能发 http://{ip:port}/{path}
或者 http://{域名}/{path}
的请求
所以如果要发起后两种方式的请求,需要再创建一个【普通的 RestTemplate Bean (如Demo中所示)】
2、涉及到的客户端和服务端,都是需要注册到eureka的(某些未注册到eureka的前端应用,不支持这样的调用)
上面仅提供一个简单的使用方式,如果需要了解一些其他事项,可以访问 Spring Cloud 官方文档