RestTemplate

依赖注入

``plain @Bean// 开启负载均衡@LoadBalancedRestTemplate restTemplate() { return new RestTemplate();} `

接下来便可以使用资源地址调用服务

`plain String url ="http://provider/getHi";String respStr = restTemplate.getForObject(url, String.class); `

get 请求处理

#### getForEntity

getForEntity方法的返回值是一个ResponseEntity-ResponseEntity是Spring对HTTP请求响应的封装-包括了几个重要的元素-如响应码、contentType、contentLength、响应消息体等。

`plain <200,Hi,[Content-Type:"text/plain;charset=UTF-8", Content-Length:"8", Date:"Fri, 10 Apr 2020 09:58:44 GMT", Keep-Alive:"timeout=60", Connection:"keep-alive"]> `

#### 返回一个Map

调用方

`plain String url ="http://provider/getMap"; ResponseEntity entity = restTemplate.getForEntity(url, Map.class); System.out.println("respStr: " + entity.getBody() ); `

生产方

`plain @GetMapping("/getMap")public Map getMap() { HashMap map = new HashMap<>(); map.put("name", "500"); return map; } `

#### 返回对象

调用方

`plain ResponseEntity entity = restTemplate.getForEntity(url, Person.class); System.out.println("respStr: " + ToStringBuilder.reflectionToString(entity.getBody() )); `

生产方

`plain @GetMapping("/getObj")public Person getObj() { Person person = new Person(); person.setId(100); person.setName("xiaoming"); return person; } `

Person类

`plain private int id;private String name; `

#### 传参调用

使用占位符

` String url ="http://provider/getObjParam?name={1}";

ResponseEntity entity = restTemplate.getForEntity(url, Person.class,"hehehe..."); `

使用map

`plain String url ="http://provider/getObjParam?name={name}"; Map map = Collections.singletonMap("name", " memeda");ResponseEntity entity = restTemplate.getForEntity(url, Person.class,map); `

#### 返回对象

`plain Person person = restTemplate.getForObject(url, Person.class,map); `

post 请求处理

调用方

`plain String url ="http://provider/postParam"; Map map = Collections.singletonMap("name", " memeda"); ResponseEntity entity = restTemplate.postForEntity(url, map, Person.class); `

生产方

`plain @PostMapping("/postParam")public Person postParam(@RequestBody String name) { System.out.println("name:" + name); Person person = new Person(); person.setId(100); person.setName("xiaoming" + name); return person; } `

postForLocation

调用方

`plain String url ="http://provider/postParam"; Map map = Collections.singletonMap("name", " memeda");URI location = restTemplate.postForLocation(url, map, Person.class);System.out.println(location); `

生产方

需要设置头信息-不然返回的是null

`plain public URI postParam(@RequestBody Person person,HttpServletResponse response) throws Exception {URI uri = new URI("https://www.baidu.com/s?wd="+person.getName());response.addHeader("Location", uri.toString()); `

exchange

可以自定义http请求的头信息-同时保护get和post方法

拦截器

需要实现ClientHttpRequestInterceptor接口

拦截器

`plain public class LoggingClientHttpRequestInterceptor implements ClientHttpRequestInterceptor { @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { System.out.println("拦截啦!!!"); System.out.println(request.getURI()); ClientHttpResponse response = execution.execute(request, body); System.out.println(response.getHeaders()); return response; } `

添加到resttemplate中

`plain @Bean@LoadBalancedRestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); restTemplate.getInterceptors().add(new LoggingClientHttpRequestInterceptor()); return restTemplate;} `

ribbon

两种负载均衡

​ 当系统面临大量的用户访问-负载过高的时候-通常会增加服务器数量来进行横向扩展(集群)-多个服务器的负载需要均衡-以免出现服务器负载不均衡-部分服务器负载较大-部分服务器负载较小的情况。通过负载均衡-使得集群中服务器的负载保持在稳定高效的状态-从而提高整个系统的处理能力。

`sh 软件负载均衡:nginx,lvs硬件负载均衡:F5我们只关注软件负载均衡-第一层可以用DNS-配置多个A记录-让DNS做第一层分发。第二层用比较流行的是反向代理-核心原理:代理根据一定规则-将http请求转发到服务器集群的单一服务器上。 `

软件负载均衡分为:服务端(集中式)-客户端。

服务端负载均衡:在客户端和服务端中间使用代理-nginx。

客户端负载均衡:根据自己的情况做负载。Ribbon就是。

客户端负载均衡和服务端负载均衡最大的区别在于 _服务端地址列表的存储位置-以及负载算法在哪里_

客户端负载均衡

在客户端负载均衡中-所有的客户端节点都有一份自己要访问的服务端地址列表-这些列表统统都是从服务注册中心获取的;

服务端负载均衡

在服务端负载均衡中-客户端节点只知道单一服务代理