1.Eureka
1)Eureka服务治理体系支持跨平台
2)三个核心概念:服务注册中心、服务提供者以及服务消费者
3)服务续约:注册完服务之后,服务提供者会维护一个心跳来不停的告诉Eureka Server:“我还在运行”以防止Eureka Server将该服务实例从服务列表中剔除,这个动作称之为服务续约,和服务续约相关的属性有两个,如下:
eureka.instance.lease-expiration-duration-in-seconds=90
eureka.instance.lease-renewal-interval-in-seconds=30
2.客户端负载均衡,服务端负载均衡
1)目的:是我们处理高并发、缓解网络压力和进行服务端扩容的重要手段之一
2)区别:在于服务清单所存储的位置,所有的客户端节点都有一份自己要访问的服务端清单,这些清单统统都是从Eureka服务注册中心获取的
3)服务端负载均衡:硬件负载均衡,还有一种是软件负载均衡,都会维护一个可用的服务端清单,然后通过心跳机制来删除故障的服务端节点以保证清单中都是可以正常访问的服务端节点
4)客户端负载均衡:上一篇关于springcloud服务的生产与消费中使用的就是客户端负载均衡,开启@LoadBalanced
注解即可实现springcloud客户端负载均衡
3.RestTemplate中几种常见的请求方式
这个类的功能很强大
1)Get请求
i).getForEntity:返回值是一个ResponseEntity<T>
,ResponseEntity<T>
是Spring对HTTP请求响应的封装,包括了几个重要的元素,如响应码、contentType、contentLength、响应消息体等
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@RequestMapping("/gethello") public String getHello() { ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class); String body = responseEntity.getBody(); HttpStatus statusCode = responseEntity.getStatusCode(); int statusCodeValue = responseEntity.getStatusCodeValue(); HttpHeaders headers = responseEntity.getHeaders(); StringBuffer result = new StringBuffer(); result.append("responseEntity.getBody():").append(body).append("<hr>") .append("responseEntity.getStatusCode():").append(statusCode).append("<hr>") .append("responseEntity.getStatusCodeValue():").append(statusCodeValue).append("<hr>") .append("responseEntity.getHeaders():").append(headers).append("<hr>"); return result.toString(); }
调用服务端接口需要传递参数,编写方式
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@RequestMapping("/sayhello") public String sayHello() { ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/sayhello?name={1}", String.class, "张三"); return responseEntity.getBody(); } @RequestMapping("/sayhello2") public String sayHello2() { Map<String, String> map = new HashMap<>(); map.put("name", "李四"); ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/sayhello?name={name}", String.class, map); return responseEntity.getBody(); }
ii)getForObject:是对getForEntity函数的进一步封装,如果你只关注返回的消息体的内容,对其他信息都不关注,此时可以使用getForObject
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@RequestMapping("/book2") public Book book2() { Book book = restTemplate.getForObject("http://HELLO-SERVICE/getbook1", Book.class); return book; }
2)Post请求
i)postForEntiy:与getForEntity方法差不多
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@RequestMapping("/book3") public Book book3() { Book book = new Book(); book.setName("红楼梦"); ResponseEntity<Book> responseEntity = restTemplate.postForEntity("http://HELLO-SERVICE/getbook2", book, Book.class); return responseEntity.getBody(); }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@RequestMapping(value = "/getbook2", method = RequestMethod.POST) public Book book2(@RequestBody Book book) { System.out.println(book.getName()); book.setPrice(33); book.setAuthor("曹雪芹"); book.setPublisher("人民文学出版社"); return book; }
ii)postForObject:如果你只关注,返回的消息体,可以直接使用postForObject。用法和getForObject一致
iii)postForLocation:postForLocation的参数和前面两种的参数基本一致,只不过该方法的返回值为Uri,这个只需要服务提供者返回一个Uri即可,该Uri表示新资源的位置
3)Put请求
put方法没有返回值,和post差不多
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@RequestMapping("/put") public void put() { Book book = new Book(); book.setName("红楼梦"); restTemplate.put("http://HELLO-SERVICE/getbook3/{1}", book, 99); }
4)Delete请求
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@RequestMapping("/delete") public void delete() { restTemplate.delete("http://HELLO-SERVICE/getbook4/{1}", 100); }
5)如何具备负载能力
添加@LoadBalanced注解后具备负载能力
实现流程:RestTemplate发起一个请求,这个请求被LoadBalancerInterceptor给拦截了,拦截后将请求的地址中的服务逻辑名转为具体的服务地址,然后继续执行请求