微架构 springcloud-13. Ribbon 负载均衡机

2018-03-27  本文已影响0人  程序员_超

Ribbon 负载均衡机制分析

这一小结分析Ribbon的机制

默认规则获取服务器

  1. 定义Ribbon负载均衡器对象 ILoadBalancer
//负载均衡器对象
ILoadBalancer loadBalancer = new BaseLoadBalancer();
  1. 定义服务器列表,是要将哪些服务器交与Ribbon以实现负载均衡
//准备服务器列表
List<Server> serverList = new ArrayList<Server>();
serverList.add(new Server("localhost", 8080));
serverList.add(new Server("localhost", 8081));
  1. 将服务器列表交与Ribbon
//将服务器列表加载到负载均衡器
loadBalancer.addServers(serverList);
  1. 从Ribbon负载均衡器中获取服务器对象
for (int i = 0; i < 10; i++) {
    Server server = loadBalancer.chooseServer(null);
    System.out.println(server);
}
  1. 完整代码如下:
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);
        }
    }
}

  1. 运行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

可知,负载均衡器选择服务器是以轮询的方式!

自定义规则获取服务器

  1. 定义类实现 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;
    }
}

  1. 测试方法

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);
    }
}
  1. 运行测试方法,控制台运行如下:
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 被调用的概率明显降低,测试成功

以上就是对负载均衡器的使用与测试

使用自定义规则

  1. 了解了负载均衡器的调用逻辑,接下来就是如何将自定义的规则应用到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);
    }
}
  1. 运行以上测试方法,控制台打印如下:
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:

  1. RoundRobinRule(默认)
轮询
  1. AvailabilityFilteringRule
过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值)
  1. WeightedResponseTimeRule
根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。
  1. ZoneAvoidanceRule
复合判断server所在区域的性能和server的可用性选择server
  1. BestAvailableRule
选择一个最小的并发请求的server
  1. RandomRule
随机选择一个server
  1. RetryRule
对选定的负载均衡策略机上重试机制。
上一篇 下一篇

猜你喜欢

热点阅读