微架構(gòu) springcloud-13. Ribbon 負(fù)載均衡機(jī)制

Ribbon 負(fù)載均衡機(jī)制分析

這一小結(jié)分析Ribbon的機(jī)制

默認(rèn)規(guī)則獲取服務(wù)器

  1. 定義Ribbon負(fù)載均衡器對(duì)象 ILoadBalancer
//負(fù)載均衡器對(duì)象
ILoadBalancer loadBalancer = new BaseLoadBalancer();
  1. 定義服務(wù)器列表,是要將哪些服務(wù)器交與Ribbon以實(shí)現(xiàn)負(fù)載均衡
//準(zhǔn)備服務(wù)器列表
List<Server> serverList = new ArrayList<Server>();
serverList.add(new Server("localhost", 8080));
serverList.add(new Server("localhost", 8081));
  1. 將服務(wù)器列表交與Ribbon
//將服務(wù)器列表加載到負(fù)載均衡器
loadBalancer.addServers(serverList);
  1. 從Ribbon負(fù)載均衡器中獲取服務(wù)器對(duì)象
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() {
        //負(fù)載均衡器對(duì)象
        ILoadBalancer loadBalancer = new BaseLoadBalancer();

        //準(zhǔn)備服務(wù)器列表
        List<Server> serverList = new ArrayList<Server>();
        serverList.add(new Server("localhost", 8080));
        serverList.add(new Server("localhost", 8081));

        //將服務(wù)器列表加載到負(fù)載均衡器
        loadBalancer.addServers(serverList);
        for (int i = 0; i < 10; i++) {
            Server server = loadBalancer.chooseServer(null);
            System.out.println(server);
        }
    }
}

  1. 運(yùn)行main 函數(shù),控制臺(tái)打印如下:
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

可知,負(fù)載均衡器選擇服務(wù)器是以輪詢的方式!

自定義規(guī)則獲取服務(wù)器

  1. 定義類實(shí)現(xiàn) com.netflix.loadbalancer.IRule 接口,讓8080調(diào)用的概率只有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;
    //負(fù)載均衡器選擇服務(wù)器
    @Override
    public Server choose(Object key) {
        int n = new Random().nextInt(10) + 1;
        if(n<2){
            return getServerByPort(8080);
        }
        return getServerByPort(8081);
    }
    //工具方法,根據(jù)端口獲取服務(wù)器
    private Server getServerByPort(int port){
        List<Server> serverList = lb.getAllServers();
        for (Server server : serverList) {
            if(server.getPort()==port){
                return server;
            }
        }
        return null;
    }
    //設(shè)置負(fù)載均衡器
    @Override
    public void setLoadBalancer(ILoadBalancer lb) {
        this.lb=lb;
    }
    //獲取負(fù)載均衡器
    @Override
    public ILoadBalancer getLoadBalancer() {
        return this.lb;
    }
}

  1. 測(cè)試方法

Rule對(duì)象要運(yùn)行需要 ILoadBalancer 對(duì)象以獲取服務(wù)器:

MyRule rule=new MyRule();
rule.setLoadBalancer(lb);

將rule對(duì)象交與ILoadBalancer:

lb.setRule(rule);

方法完整代碼如下:

@Test
public void testRule() {
    //負(fù)載均衡器對(duì)象
    BaseLoadBalancer lb = new BaseLoadBalancer();
    MyRule rule=new MyRule();
    rule.setLoadBalancer(lb);
    lb.setRule(rule);

    //準(zhǔn)備服務(wù)器列表
    List<Server> serverList = new ArrayList<Server>();
    serverList.add(new Server("localhost", 8080));
    serverList.add(new Server("localhost", 8081));

    //將服務(wù)器列表加載到負(fù)載均衡器
    lb.addServers(serverList);
    for (int i = 0; i < 10; i++) {
        Server server = lb.chooseServer("key");
        System.out.println(server);
    }
}
  1. 運(yùn)行測(cè)試方法,控制臺(tái)運(yùn)行如下:
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 被調(diào)用的概率明顯降低,測(cè)試成功

以上就是對(duì)負(fù)載均衡器的使用與測(cè)試

使用自定義規(guī)則

  1. 了解了負(fù)載均衡器的調(diào)用邏輯,接下來就是如何將自定義的規(guī)則應(yīng)用到Ribbon客戶端調(diào)用,需配置:NFLoadBalancerRuleClassName,指定規(guī)則的類名實(shí)現(xiàn):
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. 運(yùn)行以上測(cè)試方法,控制臺(tái)打印如下:
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開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8080/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info

# 已經(jīng)未采用輪詢規(guī)則來調(diào)用服務(wù)器,使用的是我們自定義的規(guī)則

Ribbon 內(nèi)置的幾種規(guī)則 Common rules:

  1. RoundRobinRule(默認(rèn))
輪詢
  1. AvailabilityFilteringRule
過濾掉那些因?yàn)橐恢边B接失敗的被標(biāo)記為circuit tripped的后端server,并過濾掉那些高并發(fā)的的后端server(active connections 超過配置的閾值)
  1. WeightedResponseTimeRule
根據(jù)相應(yīng)時(shí)間分配一個(gè)weight,相應(yīng)時(shí)間越長,weight越小,被選中的可能性越低。
  1. ZoneAvoidanceRule
復(fù)合判斷server所在區(qū)域的性能和server的可用性選擇server
  1. BestAvailableRule
選擇一個(gè)最小的并發(fā)請(qǐng)求的server
  1. RandomRule
隨機(jī)選擇一個(gè)server
  1. RetryRule
對(duì)選定的負(fù)載均衡策略機(jī)上重試機(jī)制。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容