【Java】微服务负载均衡算法实现

前言

本篇实现一下分布式中负载均衡的实现策略,以及负载均衡算法是如何实现的。

什么是负载均衡?

Java负载均衡是指在多台服务器之间分配负载,以提高服务器的性能和可用性。它通过将请求分发到多台服务器来减少单个服务器的压力,从而提高系统的性能和可用性。

算法实现

举个例子:在hcr-user服务中,存在三条集群实例。

每次请求都要请求不同的服务,那么就需要有一个全局的计数器来进行计数。

AtomicInteger是concurrent包下的一个原子类。

public class MyTest {

	private AtomicInteger count = new AtomicInteger(0);

	@Test
	public void test() {
		List<String> list = new LinkedList<>();
		list.add("服务A");
		list.add("服务B");
		list.add("服务C");

		//让原子计数器+1并 % 当前服务集合长度 = 当前请求执行集群的实例
        //返回实例下标
		int index = count.incrementAndGet() % list.size();
        //根据集合下标找到当前集群的实例
		String service = list.get(index);
		System.err.println(service);
	}
}

代码实现

1轮询

@Component
public class RoundLoadBalance implements LoadBalance {
    
    @Resource
    private DiscoveryClient client;
    
    //创建一个原子类的计数器
    private AtomicInteger atomicCount = new AtomicInteger(0);

    /**
     * 使用轮询的方式完成负载均衡算法实现
     *
     * @param serviceId 服务id
     * @return {@link ServiceInstance}
     */
    public ServiceInstance getInstances(String serviceId) {
        //获取到服务的集合(集群)
        List<ServiceInstance> list = client.getInstances(serviceId);
        if (list != null && list.size() > 0) {
            //将当前原子计数器 + 1(incrementAndGet方法相当于i++)% 服务集合的长度 = 本次调用服务
            int index = atomicCount.incrementAndGet() % list.size();
            return list.get(index);
        }
        return null;
    }
}

2随机

@Component
public class RandomLoadBalance implements LoadBalance {

    @Resource
    private DiscoveryClient client;

    /**
     * 实现随机算法完成负载均衡
     *
     * @param serviceId 服务id
     * @return {@link ServiceInstance}
     */
    public ServiceInstance getInstances(String serviceId) {
        List<ServiceInstance> list = client.getInstances(serviceId);
        if (list != null && list.size() > 0) {
            Random random = new Random();
            //随机数值范围:0-集合长度,例如集合为3,那么值的范围就是 0 1 2
            int index = random.nextInt(list.size());
            return list.get(index);
        }
        return null;
    }
}

3权重

@Component
public class WeightLoadBalance implements LoadBalance {
    @Resource
    private DiscoveryClient client;

    private AtomicInteger atomicCount = new AtomicInteger(0);

    /**
     * 使用权重算法实现负载均衡
     *
     * @param serviceId 服务id
     * @return {@link ServiceInstance}
     */
    public ServiceInstance getInstances(String serviceId) {
        //通过服务名称获取到服务集群实例
        List<ServiceInstance> list = client.getInstances(serviceId);
        if (list != null && list.size() > 0) {
            List<ServiceInstance> total = new LinkedList<ServiceInstance>();
            for (ServiceInstance instance : list) {
                //获取到nacos中服务配置的权重
                Double weight = Double.parseDouble(instance.getMetadata().get("nacos.weight"));
                for (int i = 0; i < weight; i++) {
                    //对权重的大小进行循环比对,将服务实例添加到新的集合中。
                    //权重越小,循环越少,集合中该服务就越少
                    //权重越大,循环越多,集合中该服务就越多
                    total.add(instance);
                }
            }
            //将新的集合与计数器进行计算,获取到服务下标
            int index = atomicCount.incrementAndGet() % total.size();
            return total.get(index);
        }
        return null;
    }
}

总结

这篇只是了解一下负载均衡的算法是如何实现的,在平常使用的话,feign里已经实现了负载均衡策略,所以不需要我们手动去撸代码实现。

你可能感兴趣的:(java,微服务,负载均衡)