Spring cloud之客户端负载均衡 Ribbon
通常说的负载均衡是指将一个请求均匀地分摊到不同的节点单元上执行,负载均和分为硬件负载均衡和软件负载均衡:
Ribbon 是 Netflix 发布的开源项目,主要功能是提供客户端的软件负载均衡算法,是一个基于 HTTP 和 TCP 的客户端负载均衡工具。Spring Cloud 对 Ribbon 做了二次封装,可以让我们使用 RestTemplate 的服务请求,自动转换成客户端负载均衡的服务调用。
Ribbon 支持多种负载均衡算法,还支持自定义的负载均衡算法。
Ribbon 只是一个工具类框架,比较小巧,Spring Cloud 对它封装后使用也非常方便,它不像服务注册中心、配置中心、API 网关那样需要独立部署,Ribbon只需要在代码直接使用即可。
在 Spring Cloud 中,Ribbon 主要与 RestTemplate 对象配合起来使用,Ribbon会自动化配置 RestTemplate 对象,通过@LoadBalanced 开启 RestTemplate对象调用时的负载均衡。
Ribbon 实现客户端负载均衡
@Configuration
public class SpringConfig {
/**
* ribbon负载均衡,默认是轮询
* @return
*/
@LoadBalanced //开启负载均衡,默认是RoundRobinRule(轮询)
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
Ribbon 负载均衡策略
Ribbon 的负载均衡策略是由 IRule 接口定义, 该接口由如下实现:
随机策略 | 描述 |
---|---|
RandomRule | 随机 |
RoundRobinRule | 轮询 |
AvailabilityFilteringRule | 根据平均响应时间计算所有服务的权重,响应时间越快服务权重就越大被选中的概率即越高,如果服务刚启动时统计信息不足,则使用 RoundRobinRule 策略,待统计信息足够会切换到该 WeightedResponseTimeRule 策略; |
RetryRule | 先按照 RoundRobinRule 策略分发,如果分发到的服务不能访问,则在指定时间内进行重试,分发其他可用的服务; |
BestAvailableRule | 先过滤掉由于多次访问故障的服务,然后选择一个并发量最小的服务; |
ZoneAvoidanceRule | 综合判断服务节点所在区域的性能和服务节点的可用性,来决定选择哪个服务; |
@Configuration
public class SpringConfig {
/**
* ribbon负载均衡,默认是轮询
* @return
*/
@LoadBalanced //开启负载均衡,默认是RoundRobinRule(轮询)
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
@Bean //添加@Bean注解 就是覆盖上面@LoadBalanced负载均衡模式
public IRule iRule(){
//随机负载均衡模式
return new RandomRule();
//RetyRule先按照轮询策略分发,如果分发的服务不能访问,则在指定时间进行重试分发其他可用服务
return new RetryRule();
}
}
个人练习的时候,使用了默认的RandomRule随机策略和RoundRobinRule 轮询策略以及RetryRule先按照轮询策略分发,如果分发的服务不能访问,则在指定时间进行重试分发其他可用服务(RetryRule使用这个策略需要关闭Eureka的自我保护)。
Rest 请求模板类解读
我们从服务消费端去调用服务提供者的服务的时候,使用了一个及其方便的对象即是RestTemplate,同时我们还通过配置@LoadBalanced 注解开启客户端负载均衡。在日常操作中,基于 Rest 的方式通常是四种情况,它们分表是:
GET 请求 –查询数据
/**
* 两种传参方式,一种数组 一种map
* @return
*/
@RequestMapping("/getUser")
public User getUser(){
String[] str = {"1001","张三","北京"};
Map<String,String> map = new ConcurrentHashMap<>();
map.put("id","1002");
map.put("name","李四");
map.put("address","伤害");
//getForEntity的方法,返回userResponseEntity (数组str或者map作为参数传递)
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://01SPRINGCLOUDPROVIDER/getProviderSpringCloud", String.class);
ResponseEntity<User> userResponseEntity = restTemplate.getForEntity("http://01SPRINGCLOUDPROVIDER/getProviderSpringCloudUser?id={1}&name={2}&address={3}", User.class,str);
ResponseEntity<User>userResponseEntity2 = restTemplate.getForEntity("http://01SPRINGCLOUDPROVIDER/getProviderSpringCloudUser?id={id}&name={name}&address={address}", User.class,map);
//根据getForEntity().getBody();获取返回的user对象参数
User user1 = restTemplate.getForEntity("http://01SPRINGCLOUDPROVIDER/getProviderSpringCloudUser?id={id}&name={name}&address={address}", User.class,map).getBody();
String body = restTemplate.getForEntity("http://01springcloudprovider/getProviderSpringCloud", String.class).getBody();
//getForObject方法,直接返回对象或者字符串
User user2 = restTemplate.getForObject("http://01SPRINGCLOUDPROVIDER/getProviderSpringCloudUser?id={id}&name={name}&address={address}", User.class,map);
String str= restTemplate.getForObject("http://01SPRINGCLOUDPROVIDER/getProviderSpringCloud", String.class);
return user;
}
ResponseEntity是 Spring 对HTTP 请求响应的封装,包括了几个重要的元素,比如响应码、contentType、contentLength、响应消息体等;
POST 请求 –添加数据
/**
* POST请求,有参数,返回User -addUser方法
* @return
*/
@RequestMapping("/addUser")
public User addUser(){
//要传的表单信息,参数数据(很坑人的),用普通HashMap包装参数,传不过去
MultiValueMap<String, Object> paramMap=new LinkedMultiValueMap<String, Object>();
dataMap.add("id","1003");
dataMap.add("name","王五");
dataMap.add("address","广州");
//调用postForEntity
ResponseEntity<User> userResponseEntity = restTemplate.postForEntity("http://01SPRINGCLOUDPROVIDER/addProviderSpringCloudUser", dataMap, User.class);
//调用postForObject
User user = restTemplate.postForObject("http://01SPRINGCLOUDPROVIDER/addProviderSpringCloudUser", paramMap, User.class);
User user = userResponseEntity.getBody();
return user;
}
PUT 请求 – 修改数据
/**
* PUT请求,有参数,无返回值
* @return
*/
@RequestMapping("/web/updateUser")
public String updateUser(){
//要传的表单信息,参数数据(很坑人的),用普通HashMap包装参数,传不过去
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
paramMap.add("id",3002);
paramMap.add("name","wx");
paramMap.add("phone","300220022002");
restTemplate.put("http://01SPRINGCLOUDPROVIDER/putProviderSpringCloudUser",paramMap);
return "success updateUser";
}
DELETE 请求 –删除数据
/**
* DELETE请求,有参数,无返回值
* @return
*/
@RequestMapping("/web/deleteUser")
public String deleteUser(){
//定义数组
String[] userArry = {"101","zhangsan","18821611262"};
//定义map
Map<String, Object> paramMap = new ConcurrentHashMap<>();
paramMap.put("id",102);
paramMap.put("name","lisi");
paramMap.put("phone","18821611262");
restTemplate.delete(serviceName + "/service/deleteUser?id={0}&name={1}&phone={2}",userArry);
restTemplate.delete(serviceName + "/service/deleteUser?id={id}&name={name}&phone={phone}",paramMap);
return "success deleteUser";
}
以上就是Ribbon客户端负载均衡和RestTemplate 配合ribbon使用!!!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/77254.html