Ribbon是Netflix开源的一款用于客户端软负载均衡的工具软件。
Spring Cloud对Ribbon进行了一些封装以更好的使用Spring Boot的自动化配置理念。
首先,负载均衡分为硬件负载均衡和软件负载均衡两种,这里只说软件负载均衡。软件负载均衡中又分为两种,即服务端负载均衡和客户端负载均衡。无论是那种负载均衡,都是需要维护一个服务的清单,并通过心跳机制来定期清理那些故障的服务断点。服务端负载均衡和客户端负载均衡的却别在于其所维护的服务清单所存储的位置不同,一个在服务端一个在客户端。
在spring cloud ribbon中使用客户端负载均衡只需要完成以下两个步骤:
如上图所示,其实在之前实现的服务消费者项目中就已经使用了RestTemplate,与此同时也使用了@LoadBalanced注解修饰RestTemplate。也就是说在之前的项目中我们已经使用了spring cloud ribbon的负载均衡,并实现了一个简单的服务访问。下面就详细的说一下RestTemplate在服务调用时的用法。
重载的getForEntity函数
getForEntity(String url,Class responseType,Object… urlVariable);
这个方法有三个形参,第一个形参url就是请求的Url地址,第二个形参responseType为请求响应体body的包装类型,第三个形参urlVariable为url中的参数绑定。在HTTP中,get请求的请求参数是绑定在url后面的,比如http://url:port/application?param1=xxx。
使用方式如下:
@RequestMapping(value="/ribbon-consumer",method = RequestMethod.GET)
@ResponseBody
public String helloConsumer(){
ResponseEntity entity = restTemplate.getForEntity("http://eureka-service/hello?name={1}", String.class, "xg");
String body = entity.getBody();
return body;
}
其中{1}表示请求参数中的一个占位符,而第三个形参Object… urlVariable是一个可变参数。需要注意的是,请求参数的占位符和可变参数中的顺序要对应起来。
例如:
@RequestMapping(value="/ribbon-consumer",method = RequestMethod.GET)
@ResponseBody
public String helloConsumer(){
ResponseEntity<String> entity = restTemplate.getForEntity("http://eureka-service/hello?name={1}&sex={2}", String.class,new String[]{"xg","male"});
String body = entity.getBody();
return body;
}
getForEntity(String url,Class responseType,Map urlVariables);
该方法与上面方法唯一的不同在于第三个形参由一可变参数变成了一个Map,使用起来也很简单,url中参数名即为Map中的key,而value就是请求的实际参数。例如上面的代码可以改写为
@RequestMapping(value="/ribbon-consumer",method = RequestMethod.GET)
@ResponseBody
public String helloConsumer(){
Map<String,String> params = new HashMap<>();
params.put("name","xg");
params.put("sex","male");
ResponseEntity<String> entity = restTemplate.getForEntity("http://eureka-service/hello?name={name}&sex={sex}", String.class,params);
String body = entity.getBody();
return body;
}
getForObject(String url,Class responseType,Object… urlVariables);
该方法与上面的getForEntity(String url,Class responseType,Map urlVariables)方法类似,不同点在于该方法可以理解上getForEntity的进一步封装,它可以直接对body中的内容进行转换,这样方法返回的就直接是包装好的对象。第二个参数用于指定需要包装成的对象。
getForObject(String url,Class responseType,Map urlVariables);
与上面的类似
postForEntity(String url,Object request,Class responseType,Object… urlVariables);
postForEntity(String url,Object request,Class responseType,Map urlVariables);
postForBody(String url,Object request,Class responseType,Object… urlVariables);
postForBody(String url,Object request,Class responseType,Map urlVariables);
post请求与get请求的不同点在于第二个参数request,该参数可以为任何类型,如果request对象不是一个HttpEntity,那么他将被转换成一个HttpEntity对象。
HttpEntity详解