欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Ribbon 负载均衡机制(自定义负载均衡规则)

程序员文章站 2022-06-22 11:19:00
Ribbon 负载均衡机制 在上一章的 "Ribbon 框架简介及搭建(没有与SpringCloud整合,独立使用)" 中介绍了Ribbon框架及搭建使用,那么在这一章会讲一讲Ribbon的负载均衡的机制,以下的规则 笔者将会以通俗易懂的介绍给大家讲解。 Ribbon内置的负载均衡规则 1. Rou ......

ribbon 负载均衡机制

 在上一章的 "ribbon 框架简介及搭建(没有与springcloud整合,独立使用)" 中介绍了ribbon框架及搭建使用,那么在这一章会讲一讲ribbon的负载均衡的机制,以下的规则 笔者将会以通俗易懂的介绍给大家讲解。

 

ribbon内置的负载均衡规则

1. roundrobinrule

  通过简单的轮询服务列表,来选择一个服务器
2. availabilityfilteringrule
    对以下两种服务器忽略掉,就不会选择它们了。
        2.2 在默认情况下连接失败3次,这个服务器就会被置为"短路"状态,这个状态将持续30秒。如果再连不上,那么这个状态的持续时间将会持续增加。
        # 连接失败的次数,默认为3次
        niws.loadbalancer.<clientname>.connectionfailurecountthreshold
        # 一个实例可以保持"不可用"状态的最大周期,默认为30秒
        niws.loadbalancer.<clientname>.circuittripmaxtimeoutseconds
        # 最高并发数
        <clientname>.<clientconfignamespace>.activeconnectionslimit
3. weightedrsponsetimerule

  会为每一个服务器赋予一个权重值,服务器响应时间越长,这个服务器的权重值就越少,权重有可能会决定服务器的选择(存在随机)
4. zoneavoidancerule

  以区域,可用的服务器为基础进行服务器的选择,使用zone对服务器进行分类
5. bastavailablerule

  忽略那些短路的服务器,并选择并发数较低的服务器
6. randomrule

  随机选择一个可用的服务器
7. retryrule

  它是一个含有重试机制的选择逻辑

其他配置
nfloadbalancerpingclassname:检查服务器是否存活
nfloadbalanceclassname:指定负载均衡器的实现类,可以使用该配置自定义负载均衡器
niwsserverlistclassname:服务器列表的处理类,用来维护服务器列表的
nisserverlistfilterclassname:服务器拦截类

 

这里我就不给大家一一贴配置了,感兴趣的可以到官网的wiki去看:https://github.com/netflix/ribbon

 


 

首先需要创建一个ribbon服务器,即使在上一章中写过,但是不免有一些懒懒的小伙伴(偷偷的告诉大家,笔者也是其中之一,恨不得直接复制粘贴(*^_^*))。

1:创建ribbon服务器(一个单纯的springboot程序)

pom.xml

<dependencies>
    <dependency>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-web</artifactid>
        <version>1.5.7.release</version>
    </dependency>
</dependencies>

为了方便ribbon客户端测试,在这里建一个实体类:person.java

public class person {
    private string url;// 处理请求的服务器url
    private string message;// 提示信息
    
    public string geturl() {
        return url;
    }
    public void seturl(string url) {
        this.url = url;
    }
    public string getmessage() {
        return message;
    }
    public void setmessage(string message) {
        this.message = message;
    }
}

personcontroller.java

@restcontroller
public class personcontroller {

    @requestmapping(value="/getperson", method=requestmethod.get, produces=mediatype.application_json_value)
    public person getperson(httpservletrequest request){
        person p = new person();
        p.setmessage("请求成功");
        p.seturl(request.getrequesturl().tostring());
        return p;
    }
}

启动类:application.java(因为要测试负载均衡,所有这里需要启动多个服务,以下配置以手动输入端口号方式启动)

@springbootapplication
public class application {

    public static void main(string[] args) {
        scanner scan = new scanner(system.in);
        string port = scan.nextline();
        new springapplicationbuilder(application.class).properties("server.port="+port).run(args);
    }
}

本次启动以端口:8080、8081分别启动,稍后我们配置完客户端 统一测试(配置后,将服务启动)

 

2:创建ribbon客户端

pom.xml 中只需要引入核心及客户端的依赖即可

<dependency>
    <groupid>com.netflix.ribbon</groupid>
    <artifactid>ribbon-core</artifactid>
    <version>2.2.5</version>
</dependency>
<dependency>
    <groupid>com.netflix.ribbon</groupid>
    <artifactid>ribbon-httpclient</artifactid>
    <version>2.2.5</version>
</dependency>

上面的配置与上一章的内容完全一样,那么接下来的内容大家就要注意了,也是本次讲解的重点。(本次的事例有轮询 + 自定义负载均衡器 + 访问服务)

 

使用默认的轮询规则


public static void main(string[] args) throws exception { // 创建负载均衡器对象 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); } }
Ribbon 负载均衡机制(自定义负载均衡规则)

 

使用自定义负载均衡器

/***
 * 自定义负载均衡器,这里需要实现“irule”接口
 * 比如端口为8081的服务器是新买的,不想让它处理太多的任务,那么可以用随机数去控制它的访问量
 * @author lpx
 *
 */
public class myrule implements irule{
    
    private iloadbalancer lb;// 声明负载均衡器接口
    
    @override
    public server choose(object key) {
        // 获取服务器列表
        list<server> servers = lb.getallservers();
        // 生产随机数
        random r = new random();
        int rand = r.nextint(10);
        if(rand > 7){
            return getserverbyport(servers, 8081);
        }else{
            return getserverbyport(servers, 8080);
        }
    }
    /**
     * 根据传入的端口号,返回服务对象
     * @param servers
     * @param port
     * @return
     */
    private server getserverbyport(list<server> servers, int port){
        for(server s : servers){
            if(s.getport() == port){
                return s;
            }
        }
        return null;
    }
    @override
    public void setloadbalancer(iloadbalancer lb) {
        this.lb = lb;
    }
    @override
    public iloadbalancer getloadbalancer() {
        return this.lb;
    }
}
public static void main(string[] args) throws exception {
    // 创建负载均衡器
    baseloadbalancer blb = new baseloadbalancer();
    // 创建自定义负载均衡器
    myrule myrule = new myrule();
    // 设置负载均衡器
    myrule.setloadbalancer(blb);
    // 设置负载均衡器规则
    blb.setrule(myrule);
    // 设置服务器列表
    list<server> servers = new arraylist<server>();
    servers.add(new server("localhost", 8080));
    servers.add(new server("localhost", 8081));
    blb.setserverslist(servers);
    for(int i=0; i<10; i++){
        server s = blb.chooseserver(null);
        system.out.println(s);
    }
}
Ribbon 负载均衡机制(自定义负载均衡规则)

 

使用自定义负载均衡器访问服务

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());
    // 输出服务列表
    system.out.println("服务列表:" + configurationmanager.getconfiginstance().getproperty("my-client.ribbon.listofservers"));
    // 创建客户端
    restclient client = (restclient) clientfactory.getnamedclient("my-client");
    // 创建request对象
    httprequest request = httprequest.newbuilder().uri(new uri("/getperson")).build();
    // 多次访问测试
    for (int i = 0; i < 10; i++) {
        // 创建response对象
        httpresponse response = client.executewithloadbalancer(request);
        // 接收请求结果
        string json = response.getentity(string.class);
        // 打印结果
        system.out.println(json);
    }
}
Ribbon 负载均衡机制(自定义负载均衡规则)

 

 

ok,以上就是本文的全部内容(负载均衡规则的机制 + 自定义负载均衡规则 + 访问服务),如果笔者有写的不对的地方还望大家提出,蟹蟹!!!