Ribbon均衡机制

一 新建项目user-ribbon
1 添加依赖
    <dependencies>
        <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon-core</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon-httpclient</artifactId>
            <version>2.2.2</version>
        </dependency>
    </dependencies>
2 新建负载均衡测试类
package org.crazyit.cloud;

import java.util.ArrayList;
import java.util.List;

import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

public class LBMain {

    public static void main(String[] args) {
        ILoadBalancer lb = new BaseLoadBalancer();
        List<Server> servers = new ArrayList<Server>();
        servers.add(new Server("localhost", 8080));
        servers.add(new Server("localhost", 8081));
        
        lb.addServers(servers);
        for(int i = 0; i < 10; i++) {
            Server s = lb.chooseServer(null);
            System.out.println(s);
        }
    }

}
3 运行测试,默认采用轮询规则
localhost:8081
localhost:8080
localhost:8081
localhost:8080
localhost:8081
localhost:8080
localhost:8081
localhost:8080
localhost:8081
localhost:8080
4 源码分析
默认使用的规则是RoundRobinRule
public class BaseLoadBalancer extends AbstractLoadBalancer implements
        PrimeConnections.PrimeConnectionListener, IClientConfigAware {
    private static Logger logger = LoggerFactory
            .getLogger(BaseLoadBalancer.class);
    private final static IRule DEFAULT_RULE = new RoundRobinRule();
5 新建自定义规则,使得大部分选择8080端口
package org.crazyit.cloud;

import java.util.List;
import java.util.Random;

import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;

public class MyRule implements IRule {
    
    private ILoadBalancer lb;

    public Server choose(Object key) {
        Random r = new Random();
        int rNum = r.nextInt(10);
        
        List<Server> servers = lb.getAllServers();
        
        if(rNum > 7) {
            return getServerByPort(servers, 8081);
        }
        return getServerByPort(servers, 8080);
    }
    
    private Server getServerByPort(List<Server> servers, int port) {
        for(Server s : servers) {
            if(s.getPort() == port) {
                return s;
            }
        }
        return null;
    }

    public void setLoadBalancer(ILoadBalancer lb) {
        this.lb = lb;
    }

    public ILoadBalancer getLoadBalancer() {
        return this.lb;
    }

}
6 新建负载均衡规则测试类
package org.crazyit.cloud;

import java.util.ArrayList;
import java.util.List;

import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

public class TestMyRule {

    public static void main(String[] args) {
        BaseLoadBalancer lb = new BaseLoadBalancer();
        MyRule rule = new MyRule();
        rule.setLoadBalancer(lb);
        lb.setRule(rule);
        
        List<Server> servers = new ArrayList<Server>();
        servers.add(new Server("localhost", 8080));
        servers.add(new Server("localhost", 8081));
        lb.addServers(servers);
        for(int i = 0; i < 10; i++) {
            Server s = lb.chooseServer(null);
            System.out.println(s);
        }
    }

}
7 启动测试,观察发现大部分选择到8080端口,规则生效
localhost:8081
localhost:8080
localhost:8080
localhost:8080
localhost:8080
localhost:8080
localhost:8081
localhost:8080
localhost:8080
localhost:8080
8 新建Ribbon测试类,使用我们新建的规则,通过微服务的方式调用
package org.crazyit.cloud;

import com.netflix.client.ClientFactory;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpResponse;
import com.netflix.config.ConfigurationManager;
import com.netflix.niws.client.http.RestClient;

public class TestRibbon {

    public static void main(String[] args) throws Exception {
        ConfigurationManager.getConfigInstance().setProperty(
                  "my-client.ribbon.listOfServers", "localhost:8080,localhost:8081");
        ConfigurationManager.getConfigInstance().setProperty(
                  "my-client.ribbon.NFLoadBalancerRuleClassName", MyRule.class.getName());
        
        // 获取REST请求客户端
        RestClient client = (RestClient) ClientFactory
                .getNamedClient("my-client");
        // 创建请求实例
        HttpRequest request = HttpRequest.newBuilder().uri("/person/1").build();
        // 发 送10次请求到服务器中
        for (int i = 0; i < 10; i++) {
            HttpResponse response = client.executeWithLoadBalancer(request);
            String result = response.getEntity(String.class);
            System.out.println(result);
        }
    }

}
二 新建一个服务提供者
1 新建启动类
package org.crazyit.cloud;

import java.util.Scanner;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@SpringBootApplication
public class FirstApp {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String port = scan.nextLine();
        new SpringApplicationBuilder(FirstApp.class).properties("server.port=" + port).run(args);
        
    }

}
2 新建实体类
package org.crazyit.cloud;
public class Person {
      private Integer id;
      private String name;
      private Integer age;
      private String message;
      public Integer getId() {
            return id;
      }
      public void setId(Integer id) {
            this.id = id;
      }
      public String getName() {
            return name;
      }
      public void setName(String name) {
            this.name = name;
      }
      public Integer getAge() {
            return age;
      }
      public void setAge(Integer age) {
            this.age = age;
      }
      public String getMessage() {
            return message;
      }
      public void setMessage(String message) {
            this.message = message;
      }
      
}
3 启动两个实例
三 通过调用微服务的方式进行测试
1 启动TestRibbon
2 观察结果,大部分选到8080,规则生效
{"id":1,"name":"angus","age":30,"message":"http://localhost:8080/person/1"}
{"id":1,"name":"angus","age":30,"message":"http://localhost:8080/person/1"}
{"id":1,"name":"angus","age":30,"message":"http://localhost:8081/person/1"}
{"id":1,"name":"angus","age":30,"message":"http://localhost:8080/person/1"}
{"id":1,"name":"angus","age":30,"message":"http://localhost:8080/person/1"}
{"id":1,"name":"angus","age":30,"message":"http://localhost:8080/person/1"}
{"id":1,"name":"angus","age":30,"message":"http://localhost:8080/person/1"}
{"id":1,"name":"angus","age":30,"message":"http://localhost:8080/person/1"}
{"id":1,"name":"angus","age":30,"message":"http://localhost:8080/person/1"}
{"id":1,"name":"angus","age":30,"message":"http://localhost:8081/person/1"}
四 Ribbon内置的负载均衡规则
  • RoundRobinRule:轮询规则
  • AvailabilityFilteringRule:可用性敏感规则,首先轮询选择一个server,如果该server没有熔断并且正在请求中的数量没有达到限制,则选中它。
  • WeightedResponseTimeRule:根据响应时间分配权重
  • ZoneAvoidanceRule:区域敏感性规则,如果这个ip区域内有一个或多个实例不可达或响应变慢,都会降低该ip区域内其他ip被选中的权重。
  • BestAvailableRule:最佳使用性规则,选择正在请求中的并发数最小的那个server,除非这个server在熔断中。
  • RandomRule:随机原则
  • RetryRule:重试机制选择
五 其他配置
  • NFLoadBalancerPingClassName
  • NFLoadBalancerClassName
  • NIWSServerListClassName
  • NIWSServerListFilterClassName


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值