先把配置类中注入RestTemplate方法上的@LoadBalancer注解注释掉,保证等下是自己写的负载算法生效。
新建一个LoadBalancer接口
package com.atguigu.springcloud.lb;
import org.springframework.cloud.client.ServiceInstance;
import java.util.List;
/**
* <p>
* 获取当前服务实例
* </P>
*
* @author Kk
* @since 2022/4/8 19:54
*/
public interface LoadBalancer {
/*
将所有的服务实例集合传进来,根据轮询算法计算出来的下标获取对应服务器
*/
ServiceInstance instance(List<ServiceInstance> serviceInstances);
}
实现类
package com.atguigu.springcloud.lb.impl;
import com.atguigu.springcloud.lb.LoadBalancer;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* <p>
* LoadBalancer实现类
* </P>
*
* @author Kk
* @since 2022/4/8 19:58
*/
@Component
public class MyLB implements LoadBalancer {
private AtomicInteger atomicInteger = new AtomicInteger(0);
/*
获取每一次请求是第几次,就是为了得到rest接口第几次请求数
*/
private final int getAndIncrement() {
int current;
int next;
do {
current = this.atomicInteger.get();
next = current >= Integer.MAX_VALUE ? 0 : current + 1;
//如果当前值==期望值,则自动将该值设置为给定的更新值。赋值成功则跳出循环
}while (!this.atomicInteger.compareAndSet(current,next));
System.out.println("****第几次访问,次数next: "+next);
return next;
}
/*
将所有的服务实例集合传进来,根据轮询算法计算出来的下标获取对应服务器
*/
@Override
public ServiceInstance instance(List<ServiceInstance> serviceInstances) {
//rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标
int index = getAndIncrement() % serviceInstances.size();
//返回当前对应下标的服务实例
return serviceInstances.get(index);
}
}
修改controller,添加上
@GetMapping("/lb")
public String getPaymentLB() {
//根据serviceId获取服务实例集合
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
if (instances == null || instances.size() <= 0)
return null;
//通过loadBalancer的instance方法获取轮询算法负载均衡下对应分配到的服务器
ServiceInstance serviceInstance = loadBalancer.instance(instances);
//服务URI地址
URI uri = serviceInstance.getUri();
return restTemplate.getForObject(uri+"/payment/lb",String.class);
}
provider模块的controller代码为:
@GetMapping("lb")
public String getPaymentLB() {
return serverPort; //返回端口号
}
最终测试结果:
IDEA控制台输出:
可以看到网页显示内容是在8001与8002之间反复横跳的,说明我们的轮询算法负载均衡生效了