git地址:https://github.com/sunuanwuhou/SpringCloud2020.git
Ribbon
定义:负载均衡+RestTemplate
ribbon :客户端 负载均衡调用工具
nginx :是服务端
区别在于:客户端是在发送请求之前,进行负载均衡算法
负载均衡算法
IRule
默认为轮训
- 替换负载均衡规则
自定义配置类不能放在@componentScan所扫描的当前包以及子包下,会被适用于全局ribbon规则
@Configuration
public class MyRule {
@Bean
public IRule myRule1() {
return new RandomRule(); // 定义为随机
}
}
@EnableDiscoveryClient
@SpringBootApplication
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MyRule.class)
public class OrderConsulMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderConsulMain80.class, args);
}
}
轮训原理
负载均衡算法:rest接口第几次请求数 % 服务器集群总数量=实际调用服务器位置下标(每次启动rest接口从1开始)
取余数
1%2=1
2%2=0
3%2=1
list.get(?)
源码
RoundRobinRule
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
log.warn("no load balancer");
return null;
}
Server server = null;
int count = 0;
while (server == null && count++ < 10) {
//健康的服务
List<Server> reachableServers = lb.getReachableServers();
//所有服务
List<Server> allServers = lb.getAllServers();
int upCount = reachableServers.size();
int serverCount = allServers.size();
if ((upCount == 0) || (serverCount == 0)) {
log.warn("No up servers available from load balancer: " + lb);
return null;
}
//得到下标
int nextServerIndex = incrementAndGetModulo(serverCount);
server = allServers.get(nextServerIndex);
if (server == null) {
/* Transient. */
Thread.yield();
continue;
}
if (server.isAlive() && (server.isReadyToServe())) {
return (server);
}
// Next.
server = null;
}
if (count >= 10) {
log.warn("No available alive servers after 10 tries from load balancer: "
+ lb);
}
return server;
}
//自旋锁
private int incrementAndGetModulo(int modulo) {
for (;;) {
int current = nextServerCyclicCounter.get();
int next = (current + 1) % modulo;
if (nextServerCyclicCounter.compareAndSet(current, next))
return next;
}
}
手写
原理+CAS+自旋锁