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
使用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就是。
客户端负载均衡和服务端负载均衡最大的区别在于 _服务端地址列表的存储位置-以及负载算法在哪里_。
客户端负载均衡
在客户端负载均衡中-所有的客户端节点都有一份自己要访问的服务端地址列表-这些列表统统都是从服务注册中心获取的;
服务端负载均衡
在服务端负载均衡中-客户端节点只知道单一服务代理