什么是负载均衡(Load Balance)

  1. 当访问的服务具有多个实例时,需要根据某种“均衡”的策略决定请求发往哪个节点,这就是所谓的负载均衡,
  2. 原理是将数据流量分摊到多个服务器执行,减轻每台服务器的压力,从而提高了数据的吞吐量。
  3. 比如:订单服务部署了3个节点,在访问订单服务时,访问哪一个节点是根据负载均衡策略来决定的。

软硬件角度负载均衡的种类

  • 通过硬件来进行解决,常见的硬件有NetScaler、F5、Radware和Array等商用的负载均衡器,但比较昂贵的
  • 通过软件来进行解决,常见的软件有LVS、Nginx等,它们是基于Linux系统并且开源的负载均衡策略

从端的角度负载均衡有两种

  • 服务端负载均衡:请求到视频服务的负载均衡,来决定访问哪个视频服务节点
  • 客户端负载均衡:在订单服务做负载均衡,来决定调用视频服务的哪个节点

image-20200908114732828.png
常见的负载均衡策略(看组件的支持情况)

  • 节点轮询
    • 简介:每个请求按顺序分配到不同的后端服务器
  • weight 权重配置
    • 简介:weight和访问比率成正比,数字越大,分配得到的流量越高
  • 固定分发
    • 简介:根据请求按访问ip的hash结果分配,这样每个用户就可以固定访问一个后端服务器
  • 随机选择、最短响应时间等等

什么是Ribbon

Ribbon是springcloud下的客户端负载均衡器,消费者在通过服务别名调用服务时,需要通过Ribbon做负载均衡获取实际的服务调用地址,然后通过httpclient的方式进行本地RPC远程调用。

订单服务增加负载均衡

添加注解@LoadBalanced

  1. @EnableDiscoveryClient
  2. @SpringBootApplication
  3. public class OrderApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(OrderApplication.class, args);
  6. }
  7. //注入RestTemplate时加入@LoadBalanced注解,代表RestTemplate具有负载均衡的功能
  8. @Bean
  9. @LoadBalanced
  10. public RestTemplate getRestTemplate(){
  11. return new RestTemplate();
  12. }
  13. }

在common公共服务的Video.java实体类中添加一个字段,用于测试负载均衡
image.png

  1. //测试使用 - 服务信息
  2. private String serverInfo;
  3. public String getServerInfo() { return serverInfo; }
  4. public void setServerInfo(String serverInfo) { this.serverInfo = serverInfo; }

修改VideoController,记录请求信息

  1. //只加了一行控制台打印
  2. @GetMapping("/find_by_id")
  3. public Object findById(int videoId, HttpServletRequest request){
  4. System.out.println("视频服务:" + request.getServerName() + ":" + request.getServerPort());
  5. return videoService.findById(videoId);
  6. }

启动3个视频服务,启动时记得修改端口,9000,9001,9002
idea软件1个项目启动多个实例,需要设置,设置后启动3个视频服务:
image.png
image.png

修改订单服务Controller

  1. //将之前通过DiscoveryClient获取服务IP和端口的方式更改为服务名称的方式
  2. @GetMapping("/save")
  3. public Object save(int videoId){
  4. //拼接URL,将IP和端口改为视频服务的名称
  5. String url = "http://class-video-service/api/v1/video/find_by_id?videoId=" + videoId;
  6. //网络请求
  7. Video video = restTemplate.getForObject(url, Video.class);
  8. VideoOrder videoOrder = new VideoOrder();
  9. videoOrder.setVideoId(videoId);
  10. videoOrder.setVideoTitle(video.getTitle());
  11. videoOrder.setCreateTime(video.getCreateTime());
  12. return videoOrder;
  13. }

启动1个订单服务,启动后查看Nacos控制台
image.png

访问订单服务接口测试,多访问几次后查看视频服务的控制台是否实现负载均衡调用(默认轮询的方式调用)**

  1. http://localhost:8000/api/v1/video_order/save?videoId=40

自定义Ribbon负载均衡策略

Ribbon支持的负载均衡策略介绍

策略类 命名 描述
RandomRule 随机策略 随机选择server
RoundRobinRule 轮询策略 按照顺序选择server(默认)
RetryRule 重试策略 当选择server不成功,短期内尝试选择一个可用的server
AvailabilityFilteringRule 可用过滤策略 过滤掉一直失败并被标记为circuit tripped的server,过滤掉那些高并发链接的server(active connections超过配置的阈值)
WeightedResponseTimeRule 响应时间加权重策略 根据server的响应时间分配权重,以响应时间作为权重,响应时间越短的服务器被选中的概率越大,综合了各种因素,比如:网络,磁盘,io等,都直接影响响应时间
ZoneAvoidanceRule 区域权重策略 综合判断server所在区域的性能,和server的可用性,轮询选择server

订单服务增加配置,调用视频服务采用随机策略
image.png

  1. class-video-service:
  2. ribbon:
  3. NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

策略选择:

  1. 如果每个机器配置一样,则建议不修改策略 (推荐)
  2. 如果部分机器配置强,则可以改为 WeightedResponseTimeRule