🍃前言
在 《Spring Cloud】 使用Eureka实现服务注册与服务发现》 中我们在获取服务时的代码如下:
我们每次获取的都是第一个服务,当只有一个服务时,这样是没有问题的,但是当存在多个服务时,就会出现问题。
接下来我们创建多个服务,看一下问题效果。
🍀问题现象观察
我们所启动服务是 OrderService 调用 ProductService 服务,所以我们这里在多开几个 ProductService 服务,然后再使用 OrderService 进行调用。
我们再启动2个product-service实例,操作步骤如下:
- 选中要启动的服务, 右键选择 Copy Configuration…
- 在弹出的框中, 选择 Modify options
- 选中Add VM options
- 添加服务启动的端口号:
如此一个服务就添加好了,按照此步骤,我们可以再多添加两个。
此时我们将这五个服务都启动起来,访问 127.0.0.1:1010 观察服务是否注册成功
然后我们再多次访问 http://127.0.0.1:9998/order/1
观察后端日志
我们发现多次访问的都是一个端口号的服务,其他端口号的服务并没有被使用。
这肯定不是我们想要的结果, 我们启动多个实例, 是希望可以分担其他机器的负荷, 那么如何实现呢?
这时候我们有两种方法
- 使用轮询操作,一个一个调用其他服务
- 随机调用
通过这两种方法,请求就可均衡的分配在不同的实例,这就是负载均衡
下面是简单的一个轮询操作
@Slf4j
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
@Resource
private DiscoveryClient discoveryClient;
public OrderInfo selectAll(Integer userid) {
OrderInfo orderInfo = orderMapper.selectAll(userid);
//String url = "http://127.0.0.1:9999/product/" + orderInfo.getProductId();
List<ServiceInstance> instances = discoveryClient.getInstances("product-service");
//服务可能有多个, 获取第⼀个
System.out.println("instances" + instances.size());
EurekaServiceInstance instance = (EurekaServiceInstance)instances.get(0);
log.info(instance.getInstanceId());
//拼接url
String url = instance.getUri()+"/product/"+ orderInfo.getProductId();
ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
orderInfo.setProductInfo(productInfo);
return orderInfo;
}
🌴负载均衡
负载均衡(Load Balance,简称 LB) , 是高并发, ⾼可⽤系统必不可少的关键组件
当服务流量增⼤时, 通常会采用增加机器的⽅式进⾏扩容, 负载均衡就是⽤来在多个机器或者其他资源中, 按照⼀定的规则合理分配负载.
⼀个团队最开始只有⼀个⼈, 后来随着⼯作量的增加, 公司⼜招聘了⼏个⼈. 负载均衡就是: 如何把⼯作量均衡的分配到这⼏个⼈⾝上, 以提⾼整个团队的效率
🚩负载均衡的⼀些实现
上面只是简单的提了了一下负载均衡的两种方法,但是真实的业务场景会更加复杂. ⽐如根据机器的配置进⾏负载分配, 配置⾼的分配的流量⾼, 配置低的分配流量低等.
服务多机部署时, 开发⼈员都需要考虑负载均衡的实现, 所以也出现了⼀些负载均衡器, 来帮助我们实现负载均衡.
- 负载均衡分为服务端负载均衡和客户端负载均衡.
🎈服务端负载均衡
在服务端进⾏负载均衡的算法分配.⽐较有名的服务端负载均衡器是Nginx.
请求先到达Nginx负载均衡器, 然后通过负载均衡算法, 在多个服务器之间选择⼀个进⾏访问.
🎈客户端负载均衡
在客⼾端进⾏负载均衡的算法分配
把负载均衡的功能以库的⽅式集成到客⼾端,⽽不再是由⼀台指定的负载均衡设备集中提供。
⽐如Spring Cloud的Ribbon,请求发送到客⼾端,客⼾端从注册中⼼(⽐如Eureka)获取服务列表,在发送请求前通过负载均衡算法选择⼀个服务器,然后进⾏访问。
Ribbon是Spring Cloud早期的默认实现,由于不维护了,所以最新版本的Spring Cloud负载均衡集成的是Spring Cloud LoadBalancer(Spring Cloud官⽅维护)
🚩使用 Spring Cloud LoadBalancer 实现负载均衡
SpringCloud 从 2020.0.1 版本开始, 移除了Ribbon组件,使⽤Spring Cloud LoadBalancer 组件来代
替 Ribbon 实现客⼾端负载均衡
用Spring Cloud LoadBalancer 实现负载均衡分为以下两步
- 给 RestTemplate 这个Bean添加 @LoadBalanced 注解就可以
- 修改IP端⼝号为服务名称
这样两部操作后,再启动观察product-service的⽇志,就会发现请求被分配到这3个实例上了
🚩负载均衡策略
负载均衡策略是⼀种思想,⽆论是哪种负载均衡器,它们的负载均衡策略都是相似的。Spring Cloud LoadBalancer 仅⽀持两种负载均衡策略:轮询策略 和 随机策略
- 轮询(Round Robin):轮询策略是指服务器轮流处理⽤⼾的请求。这是⼀种实现最简单,也最常⽤的
策略。⽣活中也有类似的场景,⽐如学校轮流值⽇,或者轮流打扫卫⽣。 - 随机选择(Random):随机选择策略是指随机选择⼀个后端服务器来处理新的请求
我们也可以自定义负载均衡的策略,这里博主就不进行演示了,需要的小伙伴可以去官网进行查看 官网点我
⭕总结
关于《【SpringCloud】 实现负载均衡》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下!