Spring Cloud Ribbon 是一个基于http和tcp的客户端
负载均衡工具,它
不需要像服务注册中心那样
独立部署,它几乎存在于每一个Spring Cloud构建的微服务和基础设施中。
微服务之间的调用,API网关的请求转发等内容实际上是通过Ribbon来实现的。
客户端负载均衡
客户端负载均衡中,所有客户端节点都维护着自己要访问的服务端清单,而这些服务端的清单来自于服务注册中心。
客户端负载均衡于服务器端负载均衡的不同在于:服务清单所存储的位置。比如nginx的清单,明显就不存储在客户端上。
微服务架构中,客户端负载均衡调用非常的简单:
- 服务提供者只需要启动多个服务实例并注册到服务注册中心(或者注册中心集群)。
- 服务消费者只需要调用被
@LoadBalanced
注解修饰过的RestTemplate来实现面向服务的接口调用即可。
RestTemplate详解
Restemplate对象会使用Ribbon自动化配置,同时通过配置@LoadBalanced开启客户端负载均衡。
下面介绍RestTemplate几种不同请求类型和参数类型的服务调用实现。
GET请求:
在RestTemplate中,对GET请求可以通过如下两个方法调用实现。
getForEntity
函数。该方法返回的是ResponseEntity,该对象是Spring对Http请求信息相应的封装(比如HttpStatus(也就是404、500等))。
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables){}
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables){}
public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType){}
ResponseEntity.java
public HttpStatus getStatusCode(){}
public int getStatusCodeValue(){}
public boolean equals(@Nullable Object other) {}
public String toString() {}
public static BodyBuilder status(HttpStatus status) {}
public static BodyBuilder ok() {}
public static <T> ResponseEntity<T> ok(T body) {}
public static BodyBuilder created(URI location) {}
HttpStatus.java
public enum HttpStatus {
public boolean is1xxInformational() {}
public boolean is2xxSuccessful() {}
public boolean is3xxRedirection() {}
public boolean is4xxClientError() {}
public boolean is5xxServerError() {}
public boolean isError() {}
}
BodyBuilder.java
public interface BodyBuilder extends HeadersBuilder<BodyBuilder> {
//设置正文的长度,以字节为单位,由Content-Length标头
BodyBuilder contentLength(long contentLength);
//设置body的MediaType 类型
BodyBuilder contentType(MediaType contentType);
//设置响应实体的主体并返回它。
<T> ResponseEntity<T> body(@Nullable T body);
}
可以看出来,ResponseEntity包含了HttpStatus和BodyBuilder的这些信息,这更方便我们处理response原生的东西。
RestTemplate restTemplate=new RestTemplate();
ResponseEntity<String> responseEntity=restTemplate.getForEntity(uri,String.class);
String body=responseEntity.getBody();
如果返回的是User对象类型:
RestTemplate restTemplate=new RestTemplate();
ResponseEntity<User> responseEntity=restTemplate.getForEntity(uri,User.class);
User body=responseEntity.getBody();
getForObject
函数。该方法可以理解为对getForEntity的进一步封装。比如:
RestTemplate restTemplate=new RestTemplate();
String result=restTemplate.getForObject(uri,String.class);
当返回的body是一个User对象时,可以直接这样实现:
RestTemplate restTemplate=new RestTemplate();
User result=restTemplate.getForObject(uri,User.class);
Post请求
postForEntity
函数和postForObject
函数,这两种和上面介绍的get请求的类似不做赘述,直接看代码:
RestTemplate restTemplate =new RestTemplate();
User user=new User("didi",20);
String postResult=restTemplate.postForObject("http://user-service/user",user,String.class);
post还有postForLocation
函数,该方法实现了以Post请求提交资源,并返回新资源的URI。
RestTemplate restTemplate =new RestTemplate();
User user=new User("didi",20);
URI responseURI=restTemplate.postForLocation("http://user-service/user",user);
put请求
delete请求
不做赘述。