Ribbon 负载均衡机制分析
这一小结分析Ribbon的机制
默认规则获取服务器
- 定义Ribbon负载均衡器对象 ILoadBalancer
//负载均衡器对象
ILoadBalancer loadBalancer = new BaseLoadBalancer();
- 定义服务器列表,是要将哪些服务器交与Ribbon以实现负载均衡
//准备服务器列表
List<Server> serverList = new ArrayList<Server>();
serverList.add(new Server("localhost", 8080));
serverList.add(new Server("localhost", 8081));
- 将服务器列表交与Ribbon
//将服务器列表加载到负载均衡器
loadBalancer.addServers(serverList);
- 从Ribbon负载均衡器中获取服务器对象
for (int i = 0; i < 10; i++) {
Server server = loadBalancer.chooseServer(null);
System.out.println(server);
}
- 完整代码如下:
package person.jack.ribbon.client;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.LoadBalancerBuilder;
import com.netflix.loadbalancer.Server;
import java.util.ArrayList;
import java.util.List;
public class LBTest {
@Test
public void testBalancer() {
//负载均衡器对象
ILoadBalancer loadBalancer = new BaseLoadBalancer();
//准备服务器列表
List<Server> serverList = new ArrayList<Server>();
serverList.add(new Server("localhost", 8080));
serverList.add(new Server("localhost", 8081));
//将服务器列表加载到负载均衡器
loadBalancer.addServers(serverList);
for (int i = 0; i < 10; i++) {
Server server = loadBalancer.chooseServer(null);
System.out.println(server);
}
}
}
- 运行main 函数,控制台打印如下:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
localhost:8081
localhost:8080
localhost:8081
localhost:8080
localhost:8081
localhost:8080
localhost:8081
localhost:8080
localhost:8081
localhost:8080
可知,负载均衡器选择服务器是以轮询的方式!
自定义规则获取服务器
- 定义类实现 com.netflix.loadbalancer.IRule 接口,让8080调用的概率只有10%,完整代码如下:
package person.jack.ribbon.rule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;
import java.util.List;
import java.util.Random;
public class MyRule implements IRule {
private ILoadBalancer lb;
//负载均衡器选择服务器
@Override
public Server choose(Object key) {
int n = new Random().nextInt(10) + 1;
if(n<2){
return getServerByPort(8080);
}
return getServerByPort(8081);
}
//工具方法,根据端口获取服务器
private Server getServerByPort(int port){
List<Server> serverList = lb.getAllServers();
for (Server server : serverList) {
if(server.getPort()==port){
return server;
}
}
return null;
}
//设置负载均衡器
@Override
public void setLoadBalancer(ILoadBalancer lb) {
this.lb=lb;
}
//获取负载均衡器
@Override
public ILoadBalancer getLoadBalancer() {
return this.lb;
}
}
- 测试方法
Rule对象要运行需要 ILoadBalancer 对象以获取服务器:
MyRule rule=new MyRule();
rule.setLoadBalancer(lb);
将rule对象交与ILoadBalancer:
lb.setRule(rule);
方法完整代码如下:
@Test
public void testRule() {
//负载均衡器对象
BaseLoadBalancer lb = new BaseLoadBalancer();
MyRule rule=new MyRule();
rule.setLoadBalancer(lb);
lb.setRule(rule);
//准备服务器列表
List<Server> serverList = new ArrayList<Server>();
serverList.add(new Server("localhost", 8080));
serverList.add(new Server("localhost", 8081));
//将服务器列表加载到负载均衡器
lb.addServers(serverList);
for (int i = 0; i < 10; i++) {
Server server = lb.chooseServer("key");
System.out.println(server);
}
}
- 运行测试方法,控制台运行如下:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
localhost:8080
localhost:8081
localhost:8081
localhost:8081
localhost:8081
localhost:8081
localhost:8081
localhost:8081
localhost:8081
localhost:8081
# 8080 被调用的概率明显降低,测试成功
以上就是对负载均衡器的使用与测试
使用自定义规则
- 了解了负载均衡器的调用逻辑,接下来就是如何将自定义的规则应用到Ribbon客户端调用,需配置:NFLoadBalancerRuleClassName,指定规则的类名实现:
ConfigurationManager.getConfigInstance().setProperty("myClient.ribbon.NFLoadBalancerRuleClassName",MyRule==.class.getName());
完整代码如下:
@Test
public void testMyRuleBalancer() throws Exception {
ConfigurationManager.getConfigInstance().setProperty(
"myClient.ribbon.listOfServers", "localhost:8080,localhost:8081");
ConfigurationManager.getConfigInstance().setProperty(
"myClient.ribbon.NFLoadBalancerRuleClassName",
MyRule.class.getName());
RestClient client = (RestClient) ClientFactory.getNamedClient("myClient");
HttpRequest request = HttpRequest.newBuilder().uri("/info").build();
for (int i = 0; i < 10; i++) {
HttpResponse response = client.executeWithLoadBalancer(request);
String json = response.getEntity(String.class);
System.out.println(json);
}
}
- 运行以上测试方法,控制台打印如下:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
springBoot 是javaWEB开发最优美的姿势!http://localhost:8081/info
springBoot 是javaWEB开发最优美的姿势!http://localhost:8081/info
springBoot 是javaWEB开发最优美的姿势!http://localhost:8081/info
springBoot 是javaWEB开发最优美的姿势!http://localhost:8080/info
springBoot 是javaWEB开发最优美的姿势!http://localhost:8081/info
springBoot 是javaWEB开发最优美的姿势!http://localhost:8081/info
springBoot 是javaWEB开发最优美的姿势!http://localhost:8081/info
springBoot 是javaWEB开发最优美的姿势!http://localhost:8081/info
springBoot 是javaWEB开发最优美的姿势!http://localhost:8081/info
springBoot 是javaWEB开发最优美的姿势!http://localhost:8081/info
# 已经未采用轮询规则来调用服务器,使用的是我们自定义的规则
Ribbon 内置的几种规则 Common rules:
- RoundRobinRule(默认)
轮询
- AvailabilityFilteringRule
过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值)
- WeightedResponseTimeRule
根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。
- ZoneAvoidanceRule
复合判断server所在区域的性能和server的可用性选择server
- BestAvailableRule
选择一个最小的并发请求的server
- RandomRule
随机选择一个server
- RetryRule
对选定的负载均衡策略机上重试机制。
网友评论