【SpringCloud】3.0 负载均衡,常见的负载均衡方案

什么是负载均衡(Load Balance)

分配访问具体哪个服务节点,就是负载均衡

原理是将数据流量分摊到多个服务器执行,减轻每台服务器的压力,从而提高了数据的吞吐量

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

通过硬件来进行解决,常见的硬件有NetScaler、F5、Radware和Array等商用的负载均衡器,但比较昂贵的

通过软件来进行解决,常见的软件有LVS、Nginx等,它们是基于Linux系统并且开源的负载均衡策略

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

  • 1.服务端负载均衡
    请求发起后 由负载均衡再决定分发到哪个服务节点
  • 2.客户端负载均衡
    谁请求谁决定访问哪个服务节点

常见的负载均衡策略(看组件的支持情况)

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

AlibabaCloud集成Ribbon实现负载均衡

什么是Ribbon

Ribbon是一个客户端负载均衡工具,通过Spring Cloud封装,可以轻松和AlibabaCloud整合

用法: 加了@LoadBalanced注解,就有负载均衡的功能。

修改online-edu-order-service/src/main/java/org/online_edu/OrderApplication.java

@SpringBootApplication()
@MapperScan("org.online_edu.dao")
@EnableDiscoveryClient
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

测试验证(客户端负载均衡)

2个实体类增加一个测试字段:
Video.java和VideoOrder.java

    //测试
    private String serveInfo;

    public String getServeInfo() {
        return serveInfo;
    }

    public void setServeInfo(String serveInfo) {
        this.serveInfo = serveInfo;
    }

修改VideoController.java

@RestController
@RequestMapping("api/v1/video")
public class VideoController {
    @Autowired
    private VideoService videoService;


    @RequestMapping("/find_by_id")
    public Video findById(@RequestParam(name = "videoId") int videoId, HttpServletRequest request) {
        Video video = videoService.findById(videoId);
        // 拿到服务端的id+端口
        video.setServeInfo(request.getServerName() + ":" + request.getServerPort());
        return video;
    }
}

修改VideoOrderController.java

@RestController
@RequestMapping("/api/v1/video_order")
public class VideoOrderController {

    /**
     * 服务对象
     */
    @Autowired
    private VideoOrderService videoOrderService;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 可以拉到注册服务的列表
     */
    @Autowired
    private DiscoveryClient discoveryClient;

    @RequestMapping("save")
    public Object save(@RequestParam(name = "videoId") int videoId) {
//        Video video = restTemplate.getForObject(
//                "http://localhost:9000/api/v1/video/find_by_id?videoId=" + videoId, Video.class);
        // 传入在nacos注册的服务名
//        List<ServiceInstance> list = discoveryClient.getInstances("online-edu-video-service");
//        ServiceInstance serviceInstance = list.get(0);
//
//
//        Video video = restTemplate.getForObject(
//                "http://" + serviceInstance.getHost() +":"+serviceInstance.getPort()+ "/api/v1/video/find_by_id?videoId=" + videoId, Video.class);


        Video video = restTemplate.getForObject(
                "http://online-edu-video-service/api/v1/video/find_by_id?videoId=" + videoId, Video.class);
        VideoOrder videoOrder = new VideoOrder();
        if (video != null) {
            videoOrder.setServeInfo(video.getServeInfo());
            videoOrder.setVideoId(video.getId());
            videoOrder.setVideoTitle(video.getTitle());
            videoOrder.setCreateTime(new Date());
        }
        return videoOrder;
    }

}

运行2个online-edu-video-service服务(idea右上角 ,进入编辑详情可以copy)


image.png

然后重新调用接口

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

+

image.png

ribbon服务间调用负载均衡源码分析

idea搜索类的快捷键是 ctrl+N
@LoadBalanced

1)首先从注册中心获取provider的列表
2)通过一定的策略选择其中一个节点
3)再返回给restTemplate调用

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

策略类 命名 描述
RoundRobinRule 线性轮询策略 按照顺序选择server,简单轮询服务列表来选择服务器。它是Ribbon默认的负载均衡规则。
AvailabilityFilteringRule 可用过滤策略 过滤掉一直失败并被标记为circuit tripped的server,过滤掉那些高并发链接的server(active connections超过配置的阈值)。

对以下两种服务器进行忽略:
(1)在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为“短路”状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。
(2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上限,可以由客户端的..ActiveConnectionsLimit属性进行配置。
WeightedResponseTimeRule 响应时间加权重策略 根据server的响应时间分配权重,以响应时间作为权重,响应时间越短的服务器被选中的概率越大,综合了各种因素,比如:网络,磁盘,io等,都直接影响响应时间
ZoneAvoidanceRule 区域权重策略 综合判断server所在区域的性能,和server的可用性,轮询选择server
BestAvailableRule 最空闲策略 忽略那些短路的服务器,并选择并发数较低的服务器。
RandomRule 随机策略 随机选择server
RetryRule 重试策略 当选择server不成功,短期内尝试选择一个可用的server

怎么配置

通过定义IRule实现可以修改负载均衡规则,有两种方式:

(这种方式是作用于全局的,在order服务访问任何一个微服务,都是随机的)

1.代码方式:在order-service中的OrderApplication类中,定义一个新的IRule:

  @Bean
  public IRule randomRule() {
    return new RandomRule();
  }

2.配置文件方式:在online-edu-order-service的application.yml文件中,添加新的配置也可以修改规则:

这种方式会先指定服务名称,再去指定负载均衡的规则,所以这种配置是针对某个微服务而言的。

online-edu-order-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule # 负
载均衡规则 

服务器性能有差异时用WeightedResponseTimeRule,没有则默认即可。

demo(客户端负载均衡)

因为我的服务总是报java.net.UnknownHostException: online-edu-video-servicec错误。

image.png

最后百度的原因是

因为Spring Cloud 2020版本以后,默认移除了对Netflix的依赖,其中就包括Ribbon,官方默认推荐使用Spring Cloud Loadbalancer 正式替换Ribbon,并成为了Spring Cloud负载均衡器的唯一实现,因此要在原有依赖的基础上添加 下面的Loadbalancer依赖。

按照且感谢 春.生——https://blog.csdn.net/Funny54?type=blog 的博客指导,增加依赖(父项目引入依赖和版本,子项目引入依赖)

            <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-loadbalancer -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-loadbalancer</artifactId>
                <version>4.1.4</version>
            </dependency>

online-edu-order-service/src/main/resources/application.yml

增加依赖:


image.png

online-edu-order-service/src/main/java/org/online_edu/controller/VideoOrderController.java

@RestController
@RequestMapping("/api/v1/video_order")
public class VideoOrderController {

    /**
     * 服务对象
     */
    @Autowired
    private VideoOrderService videoOrderService;

    @Autowired
    private RestTemplate restTemplate;

//    /**
//     * 可以拉到注册服务的列表
//     */
//    @Autowired
//    private DiscoveryClient discoveryClient;

    @RequestMapping("save")
    public Object save(@RequestParam(name = "videoId") int videoId) {
//        Video video = restTemplate.getForObject(
//                "http://localhost:9000/api/v1/video/find_by_id?videoId=" + videoId, Video.class);
        // 传入在nacos注册的服务名
//        List<ServiceInstance> list = discoveryClient.getInstances("online-edu-video-service");
//        ServiceInstance serviceInstance = list.get(0);
////
////
//        Video video = restTemplate.getForObject(
//                "http://" + serviceInstance.getHost() +":"+serviceInstance.getPort()+ "/api/v1/video/find_by_id?videoId=" + videoId, Video.class);

        Video video = restTemplate.getForObject(
                "http://online-edu-video-service/api/v1/video/find_by_id?videoId=" + videoId, Video.class);
        VideoOrder videoOrder = new VideoOrder();
        if (video != null) {
            videoOrder.setServeInfo(video.getServeInfo());
            videoOrder.setVideoId(video.getId());
            videoOrder.setVideoTitle(video.getTitle());
            videoOrder.setCreateTime(new Date());
        }
        return videoOrder;
    }

}

image.png

这里online-edu-video-service起3个服务。
image.png

我这里用的Apipost软件。

发起多次请求,可以看到再访问到video服务分布式节点。

image.png

image.png

image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容