Ribbon是一个基于Http和Tcp的客户端负载均衡工具,它可以让我们轻松地将面向服务的REST请求模板请求自动转换成客户端负载均衡的服务调用。
这里依然采用这一节的代码。这是链接Ribbon实例的简单应用(provider+consumer),上节中已经做了ribbon的使用,本节只介绍ribbon的一些api的使用。
在consumer端需要添加ribbon依赖。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
客户端负载均衡中,所有客户端节点都维护着自己要访问的服务端清单,而这些服务端的清单都来自服务注册中心,比如Eureka服务端。同服务端负载均衡的架构类似,在客户端负载均衡中也需要心跳去维护服务端清单的健康性,只是这个步骤需要与服务注册中心配合完成。
通过Spring Cloud Ribbon的封装,我们在微服务架构中使用客户端负载均衡调用非常简单,只需要如下两步:
- 服务提供者只需要启动多个服务实例并注册到一个注册中心或是多个相关联的服务注册中心;
- 服务消费者直接通过调用被@LoadBalanced注解修饰过的RestTemplate来实现面向服务的接口调用。
一 @RestTemplate注解使用
在Ribbon实例的简单应用中使用了@LoadBalanced注解(这个注解是开启负载均衡)配置的RestTemplate,实现了简单的服务访问。
1 Get请求
在RestTemplate中,对Get请求的方式有两种方法可以调用。
第一种是getForEntity函数。该方法返回的是ResponseEntity,该对象是Spring对HTTP请求响应的封装,其中存储了HTTP的几个重要元素,比如HTTP请求状态码的枚举对象HttpStatus。
getForEntity函数有三种实现:
<1>ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)。
- url:为请求地址;
- responseType:为请求响应体body的包装类型;
- uriVariables:为url中的参数绑定。
@Test
public void contextLoads() {
ResponseEntity<String> entity = restTemplate.getForEntity("http://user-service/user?name={1}", String.class,"paul");
String body = entity.getBody();
}
<2> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
- url:为请求地址;
- responseType:为请求响应体body的包装类型;
- uriVariables:为url中的参数绑定,为Map类型。
@Test
public void contextLoads1() {
Map<String,String> map = new HashMap<>();
map.put("name", "paul");
ResponseEntity<String> entity = restTemplate.getForEntity("http://user-service/user?name={name}", String.class,map);
String body = entity.getBody();
}
<3> ResponseEntity<T> getForEntity(URI url, Class<T> responseType)
通过uri对象构造请求地址和参数。
@Test
public void contextLoads2() {
UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://user-service/user?name={name}")
.build().expand("paul").encode();
URI uri = uriComponents.toUri();
ResponseEntity<String> entity = restTemplate.getForEntity(uri, String.class);
String body = entity.getBody();
}
第二种是getForObject()函数,它可以理解为对getForEntity的进一步封装,它通过HttpMessageConverterExtractor对HTTP的请求响应体body内容进行对象转换,实现请求直接返回包装好的对象内容。
当不需要关注请求响应除body外的其他内容时,该函数就非常好用,可以少一个从Response中获取body的步骤。它的实现与getForEntity()函数相似。
- getForObject(String url, Class<T> responseType, Object... uriVariables);
- getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables);
- getForObject(URI url, Class<T> responseType)
2 POST请求
POST请求的方法实现有三种。
- ResponseEntity<T> postForEntity();
- T postForObject();
- URI postForLocation();
<1> ResponseEntity<T> postForEntity()
- ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables);
- ResponseEntity<T> postForEntity(String url, @Nullable Object request,Class<T> responseType, Map<String, ?> uriVariables);
- ResponseEntity<T> postForEntity(URI url, @Nullable Object request, Class<T> responseType)。
参数说明:
- url:请求地址;
- request:是要上传的参数,即服务提供者接受的参数;
- responseType:为请求响应体body的包装类型;
- uriVariables:url地址中的参数绑定。
- url:通过URI绑定请求地址和参数。
@Test
public void contextLoads4() {
ResponseEntity<String> entity = restTemplate.postForEntity("http://user-service/user", new User("paul",30), String.class);
String body = entity.getBody();
}
@Test
public void contextLoads5() {
ResponseEntity<String> entity = restTemplate.postForEntity("http://user-service/user?name={name}",null ,String.class, "paul");
String body = entity.getBody();
}
<2> postForObject
- T postForObject(URI url, @Nullable Object request, Class<T> responseType);
- T postForObject(String url, @Nullable Object request, Class<T> responseType,Map<String, ?> uriVariables);
- T postForObject(String url, @Nullable Object request, Class<T> responseType,Object... uriVariables)。
它和postForEntity实现类似。
<3> postForLocation
- URI postForLocation(String url, @Nullable Object request, Object... uriVariables);
- URI postForLocation(String url, @Nullable Object request, Map<String, ?> uriVariables);
- URI postForLocation(URI url, @Nullable Object request)。
postForLocation也是提交新资源,提交成功之后,返回新资源的URI,postForLocation的参数和前面两种的参数基本一致,只不过该方法的返回值为Uri,这个只需要服务提供者返回一个Uri即可,该Uri表示新资源的位置。
3 PUT请求
- void put(String url, @Nullable Object request, Object... uriVariables);
- put(String url, @Nullable Object request, Map<String, ?> uriVariables);
- void put(URI url, @Nullable Object request)。
4 DELETE请求
- void delete(String url, Object... uriVariables);
- void delete(String url, Map<String, ?> uriVariables);
- void delete(URI url)。