一、ribbon简介
Ribbon是Netflix发布的负载均衡器,他是基于http和TCP的客户端负载均衡。ribbon中实现了一下负载均衡策略
其中RandomRule表示随机策略、RoundRobin表示轮询策略、WeightedResponseTimeRule表示加权策略、BestAvailableRule表示请求数最少策略等等。在spring cloud中Ribbon配合Eureka使用,通过负载均衡选择其中的一个实例进行请求调用。
二、Ribbon使用
1.添加依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> <version>1.3.5.RELEASE</version> </dependency>
在ribbon与Eureka配合使用时,不需要再额外导入ribbon jar包。
2. 定义RestTemplate
@Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); }
这样一个ribbon的调用对象restTemplate就定义好了,其中@LoadBalanced注解代表负载均衡。
当然这只是最基本的定义,其实我们可以进一步更加详细的去定义RestTemplate,具体如下
@Bean @LoadBalanced public RestTemplate customRestTemplate(){ HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(); //连接不够用的等待时间,不宜过长,必须设置,比如连接不够用时,时间过长将是灾难性的 httpRequestFactory.setConnectionRequestTimeout(3000); //设置连接超时时间 httpRequestFactory.setConnectTimeout(3000); //设置读超时时间,即请求处理超时时间 httpRequestFactory.setReadTimeout(3000); // 缓冲请求数据,默认值是true。通过POST或者PUT大量发送数据时,建议将此属性更改为false,以免耗尽内存。 // clientHttpRequestFactory.setBufferRequestBody(false); return new RestTemplate(httpRequestFactory); }当然还有一些其他参数,这里不再列出。
三、RestTemplate详解
1.get调用
查看RestTemplate源码可以看出,RestTemplate提供了以上几个方法用户get请求。
- ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)该方法提供了三个参数,url是指请求链接,responseType表示返回体中的泛型类型,uriVariables表示请求的参数,示例如下
String url = "http://user-system/user/getUserByUid?uid={1}"; ResponseEntity<String> entity = restTemplate.getForEntity(url, String.class, "1234566"); String body = entity.getBody();
- ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)此方法也提供了三个参数,前两个参数作用与上个相同,参数三是表示请求的参数,示例如下
String url = "http://user-system/user/getUserByUid?uid={uid}"; Map<String,String> map = new HashMap<>(); map.put("uid","1234566"); ResponseEntity<String> entity = restTemplate.getForEntity(url, String.class,map ); String body = entity.getBody();
- ResponseEntity<T> getForEntity(URI url, Class<T> responseType)该方法使用URI类来替换上述方法中的url和uriVariables两个参数,具体使用如下:
String url = "http://user-system/user/getUserByUid?uid={uid}"; UriComponents uriComponents = UriComponentsBuilder.fromUriString(url) .build() .expand("12344566") .encode(); URI uri = uriComponents.toUri(); ResponseEntity<String> forEntity = restTemplate.getForEntity(uri, String.class); String body = forEntity.getBody();
- getforObject方法是对getForEntity方法的进一步封装,他是直接接返回结果中的Body体直接取出来返回。
2.post请求
post请求与get请求区别不大,查看源码可以看出,post请求比get请求多出一个参数Object request,这个参数就是用来传递body体的内容的
示例如下:
String url = "http://IP:8080/demo/demoTest2"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.set("phone", "123456"); Map<String, Object> params = new HashMap<>(); params.put("name", "yyc"); params.put("email", "12306"); RestTemplate restTemplate = new RestTemplate(); HttpEntity httpEntity = new HttpEntity(params,headers); ResponseEntity<String> request = restTemplate.postForEntity(url, httpEntity,String.class);
另外还有put请求和delete请求,由于用到较少,这里不再详述
三、补充说明
上文提到,服务间调用依赖于eureka实现,那么如果eureka全部宕机了,怎么办?
这个问题,不用担心,因为eureka还提供了缓存机制,即使eureka服务全部死掉了,也可以从缓存中继续读取到客户端的数据信息