手写Ribbon负载均衡算法

5 篇文章 0 订阅
3 篇文章 0 订阅

一、Ribbon有哪些自带的负载均衡算法

在这里插入图片描述
默认出厂设置用的是轮询算法,就是每个服务列表按顺序依次访问;

二、怎么替换默认的负载均衡算法

首先注意一点,算法配置文件不能处于@ComponentScan注解所在的包及其子包下,原因就不说了,自己百度去。
所以第一步,新建一个包com.xiexiaoyu.ribbon,然后新建一个配置类

@Configuration
public class MySelfRule
{
    @Bean
    public IRule myRule()
    {
        return new RandomRule();//定义为随机
    }
}

然后在主启动类上加入注解

//访问CLOUD-PAYMENT-SERVICE服务时采用MySelfRule类中定义的负载均衡算法
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration=MySelfRule.class)

over,这样就把这个客户 端的负载均衡算法换成了随机访问算法

三、手写负载均衡算法

1、ApplicationContextBean去掉注解@LoadBalance

ApplicationContextConfig用于返回一个RestTemplate实例,用于rest接口调用。

@Configuration
public class ApplicationContextConfig
{
    @Bean
    //@LoadBalanced
    public RestTemplate getRestTemplate()
    {
        return new RestTemplate();
    }
}

2、手写一个LoadBalance接口

1)LoadBalancer接口声明返回从一组微服务中返回其中一个

public interface LoadBalancer
{
    ServiceInstance instances(List<ServiceInstance> serviceInstances);
}

2)MyLB实现类实现LoadBalancer接口

@Component
public class MyLB implements LoadBalancer
{

    private AtomicInteger atomicInteger = new AtomicInteger(0);

    public final int getAndIncrement()
    {
        int current;
        int next;
		
		//自旋锁确定微服务索引
        do {
            current = this.atomicInteger.get();
            next = current >= 2147483647 ? 0 : current + 1;
        }while(!this.atomicInteger.compareAndSet(current,next));
        System.out.println("*****第几次访问,次数next: "+next);
        return next;
    }

    //负载均衡算法:rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标  ,每次服务重启动后rest接口计数从1开始。
    @Override
    public ServiceInstance instances(List<ServiceInstance> serviceInstances)
    {
        int index = getAndIncrement() % serviceInstances.size();

        return serviceInstances.get(index);
    }
}

3)Controller层调用负载均衡算法
微服务8001,注册成CLOUD-PAYMENT-SERVICE:

@RestController
@Slf4j
public class PaymentController
{
	//server.port=8001 写在配置文件的,这里不单独列出了,不是本文重点
    @Value("${server.port}")
    private String serverPort;
    
    @GetMapping(value = "/payment/lb")
    public String getPaymentLB()
    {
        return serverPort;
    }
}

微服务8002,注册成CLOUD-PAYMENT-SERVICE:

@RestController
@Slf4j
public class PaymentController
{
	//server.port=8002 写在配置文件的,这里不单独列出了,不是本文重点
    @Value("${server.port}")
    private String serverPort;
    
    @GetMapping(value = "/payment/lb")
    public String getPaymentLB()
    {
        return serverPort;
    }
}

服务消费者:

@RestController
@Slf4j
public class OrderController
{
	//微服务名称
    public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";

    @Resource
    private RestTemplate restTemplate;
    @Resource
    private LoadBalancer loadBalancer;
    @Resource
    private DiscoveryClient discoveryClient;

    @GetMapping(value = "/consumer/payment/lb")
    public String getPaymentLB()
    {
    	//获取服务列表
        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");

        if(instances == null || instances.size() <= 0)
        {
            return null;
        }
		//通过自定义的负载均衡算法确定调用哪个微服务
        ServiceInstance serviceInstance = loadBalancer.instances(instances);
        URI uri = serviceInstance.getUri();

        return restTemplate.getForObject(uri+"/payment/lb",String.class);
    }
}

完活!有兴趣的可以自己实现IRule接口,然后配置负载均衡实现类为自己定义的IRule实现类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值