数据人与超自然意识 发表于 2025-3-26 06:12:41

【微服务架构】本地负载均衡的实现(基于权重算法)

媒介

负载均衡



[*]概念:一种将网络流量或业务请求均匀分配到多个服务器或服务实例上的技术,旨在提高体系的可用性、性能和可伸缩性。
[*]作用:

[*]提高性能:通过将请求分散到多个实例上,克制单个实例因请求过多而过载,从而提高体系的整体处置惩罚能力。
[*]增强可用性:当某一实例发生故障时,负载均衡器可以自动将流量重定向到其他康健的实例,确保服务仍然可用。
[*]实现可伸缩性:可以根据体系的负载环境,动态地添加或删除服务实例,以适应业务需求的变化。

[*]实现方式

[*]服务器端负载均衡:SpringCloud的LoadBalancer、Netflix的Ribbon
[*]客户端负载均衡:本地负载均衡器【可基于特定算法手写】
[*]中间层负载均衡:Nginx

负载均衡器



[*]概念:是一种软件或硬件设备,用于在多个服务器或服务实例之间分发网络流量或业务请求。
常见负载均衡算法【策略】



[*]随机算法

[*]随机选取集群中的一台服务器访问。
[*]随着客户端调用服务端的次数增多,其现实结果越来越靠近于平均分配调用量到后端的每一台服务器。

[*]轮询算法【默认】

[*]按顺序向每个服务实例发送请求,实用于体系中的节点处置惩罚能力雷同的环境。

[*]权重算法

[*]给设置高、负载低的机器设置更高的权重,让其处置惩罚更多的请求;
[*]而设置低、负载高的机器,给其分配较低的权重,低落其体系负载。

通俗明确



[*]在微服务架构中,为保证项目的高可用性【如故障转移】和可拓展性【如动态服务注册】,通常需要对特定服务举行集群;
[*]而调用服务者[斲丧者]通过RPC长途调用目的服务[生产者]的接口时则存在:"详细应该调用集群中的哪个服务?"的问题;
[*]此时需要通过负载均衡实现详细服务的调用[目的服务实例的筛选];
简单概述

负载均衡 = 负载均衡器 + 负载均衡算法【策略】 —》 按特定策略从服务集群中挑选一个服务实例【服务器】调用。
实践(以轮询算法为例)

package com.xiaohan.loadbalance;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
* @program: SpringCloud_Demo
* @description: 权重算法实现
* @author: 韩小豪
* @create: 2025-01-18 16:09
**/

/**
* 当集群中两个服务的权重设置如下时:
* serviceInstances = 192.168.2.139:8080    -->    weight=2
* serviceInstances = 192.168.2.139:8081    -->    weight=1
* --
* 基本思想:
* 1.从nacos服务注册中心端获取到两个服务的权重后,创建一个新的服务列表
* 2.因为第一个服务的权重为2,因此新的服务列表中应存入两个该服务
* [
* 192.168.2.139:8080,
* 192.168.2.139:8080,
* 192.168.2.139:8081
* ]
* 3.当需要访问该目标服务时,从新的服务列表中通过轮询的策略分配可用服务实例,具体表现为:
*第1次调用: 1 % 3 = 1   
*第2次调用: 2 % 3 = 2   
*第3次调用: 3 % 3 = 0   
*--
*第4次调用: 4 % 3 = 1   
*第5次调用: 5 % 3 = 2   
*第6次调用: 6 % 3 = 0   
*/
@Component
public class WeightLoadBalance implements LoadBalance {

        @Autowired
        private DiscoveryClient discoveryClient;

        //计数器:记录当前为第几次访问目标服务接口
        private AtomicInteger count = new AtomicInteger(0);

        @Override
        public ServiceInstance getInstance(String serviceId) {
                //获取所有服务实例
                List<ServiceInstance> serviceInstances = discoveryClient.getInstances(serviceId);
                //判空
                if(serviceInstances == null || serviceInstances.isEmpty())
                {
                        return null;
                }

                //新的服务列表
                ArrayList<ServiceInstance> newInstances = new ArrayList<>();

                //遍历服务列表,通过每个服务的权重往新的服务列表中添加
                for( ServiceInstance serviceInstance : serviceInstances){
                        //获取每个服务实例的权重【Double类型,一般设置为整数】
                        double weight = Double.parseDouble(serviceInstance.getMetadata().get("nacos.weight"));

                        //往新的服务列表中添加对应权重数的服务实例
                        for(int i = 0;i < weight;i++){
                                newInstances.add(serviceInstance);
                        }
                }

                //对新的服务列表采取轮询的策略分配可用服务实例
                int index = count.getAndIncrement() % newInstances.size(); //getAndIncrement返回旧值后+1、incrementAndGet返回+1后的新值
                //返回目标服务实例
                return newInstances.get(index);
        }
}

结语



[*]相识原理和详细实现才利于更好利用【明确 > 会用】
[*]基于随机和轮询算法的实现见首页其他文章

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【微服务架构】本地负载均衡的实现(基于权重算法)