Ribbon负载规则更换

1.负载均衡使用在客户端的。

2.默认的是负载均衡是轮询,其实还有好多个,都实现的是IRULE接口,这个是负载均衡的核心接口,这个接口的实现类如下图:

 

 3.实现定制的负载均衡跟restTemlate一样,也是需要做一个配置类,但是这个配置类的位置不能再main程序的包及其子包下面,因为这样会被扫描到。

 

 

4.主启动上加上@RibbonClient注解

@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = myRibbon.class)

5.测试:

第一次:

 

 第二次:

 

模仿写一个自定义的负载均衡算法:

思想:访问的服务实例下标=访问的次数%机器总量

1.注销@loadBance注解,和主类上的@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = myRibbon.class)

2.在主类的同级包下创建接口和实现类:

接口:

public interface myloadBalance {
ServiceInstance instance(List<ServiceInstance> list);
}

实现类:
@Component
public class mylb implements myloadBalance {

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));
return next;
}
@Override
public ServiceInstance instance(List<ServiceInstance> list) {
int index = getAndIncrement() % list.size();
return list.get(index);
}
}

通过CAS算法来获取每次访问的实例:

  CAS原理:

compareAndSet(期望值,修改值),当一个线程获取值后,这个期间可能有其他线程修改了这个值,然后那这个值与主存中的值比较,相同就可以替换,不同重新获取然后比较替换。

controller:

@Resource
private mylb mylb;
@Resource
private EurekaDiscoveryClient discoveryClient;

 

@RequestMapping("/consumer/loadBalanceTest")
@ResponseBody
public ResultObject loadBalanceTest(Payment model){
//获取实例下的所有微服务
List<ServiceInstance> l2 = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
ServiceInstance service = mylb.instance(l2);
URI uri = service.getUri();
return restTemplate.postForObject(uri+"/payment/printPort",model,ResultObject.class);
}

在服务提供者8001和8002下加上如下代码进行测试:

@PostMapping("/printPort")
@ResponseBody
public ResultObject pringtPort(){
return ReturnResult.success(port);
}

在8001,8002服务中加入这个来测试自写的负载均衡,打印一下yml文件中配置的端口号。

 

 

 
posted @ 2020-04-30 17:50  ~笑春风~  阅读(203)  评论(0)    收藏  举报