Ribbon 負載均衡機制(自定義負載均衡規則)


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); } }

 

使用自定義負載均衡器

/***
 * 自定義負載均衡器,這里需要實現“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);
    }
}

 

使用自定義負載均衡器訪問服務

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);
    }
}

 

 

OK,以上就是本文的全部內容(負載均衡規則的機制 + 自定義負載均衡規則 + 訪問服務),如果筆者有寫的不對的地方還望大家提出,蟹蟹!!!

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM