通俗易懂的 Dubbo 教程(八):負載均衡

前言

Dubbo 是一個分佈式服務框架,一個服務可能會部署多個實例,我們應該如何從多個服務提供者組成的集羣挑選一個進行調用呢?這就涉及到一個負載均衡的問題。

四種負載均衡策略

Dubbo 內置了四種負載均衡策略,分別如下:

  1. RandomLoadBalance:隨機負載均衡
  2. RoundRobinLoadBalance:輪詢負載均衡
  3. LeastActiveLoadBalance:最少活躍調用數負載均衡
  4. ConsistentHashLoadBalance:一致性哈希負載均衡

下面我們對這四種負載均衡策略做一個簡單的介紹。

隨機負載均衡

隨機負載均衡是 Dubbo 默認的負載均衡策略,顧名思義,就是從多個服務提供者中隨機選擇一個。

需要注意的是,Dubbo 的隨機負載均衡並非是完全的隨機,它有一個權重的概念,會按照權重來設置隨機概率,舉個例子,我們現在有兩個服務提供者,一個的權重是100,另一個的權重是300,那麼前者被分配的概率就爲 25%,後者被分配的概率爲 75%。

我們可以對服務提供者設置不同的權重,例如對性能較好的機器設置大權重,對差一點的機器設置小一點的權重。

輪詢負載均衡

輪詢負載均衡,即會輪詢每一個服務提供者,依次對其進行調用。

輪詢負載均衡也有權重的概念,可以嚴格按照我們設置的比例進行分配,這個是該算法的優點,不過,該算法的缺點也很明顯,可能會存在較慢的機器,那麼請求會在這臺機器上進行累積,很容易導致整個系統變慢。

最少活躍調用數負載均衡

最少活躍調用數負載均衡會將請求轉發至活躍調用數最少的機器上,如果有兩臺機器活躍數相同,會採取隨機負載均衡的策略。

什麼是活躍調用數呢?每個服務維護一個活躍數計數器,該計數器存放機器未處理完的請求。當有請求產生時,會選擇活躍數最小的機器去執行。

最少活躍調用數負載均衡可以令慢的機器收到更少的請求。

一致性哈希負載均衡

要了解這種負載均衡策略,我們首先得學習一下一致性哈希算法。不會一致性哈希算法的同學可以看一下我之前寫的這篇博客,質量保證過硬:一致性哈希算法詳解

一致性哈希可以保證相同參數的請求一定會發送到同一臺機器上,即使有機器崩潰,由於一致性哈希算法的特性與虛擬節點的存在,發往該機器的請求會被髮送到其它機器上,並不會引發劇烈變動。

配置

我們可以在多個地方(客戶端,服務端),以多個級別(方法級,接口級,全局配置)配置負載均衡。它們之間的優先關係如下:

  1. 方法級優先,接口級次之,全局配置再次之
  2. 如果級別一樣,則消費方優先,提供方次之

實現

我們創建兩個服務提供者,兩個服務提供者的實現分別如下,它們提供的返回值是不同的。

package edu.szu.producer.serviceImpl;

import com.alibaba.dubbo.config.annotation.Service;
import edu.szu.api.service.NameService;
import org.springframework.stereotype.Component;

@Component
@Service
public class NameServiceImpl implements NameService {

    @Override
    public String updateName(String name) {
        return "舊機器:" + name;
    }
}
package edu.szu.producer_new.serviceImpl;

import com.alibaba.dubbo.config.annotation.Service;
import edu.szu.api.service.NameService;
import org.springframework.stereotype.Component;

@Component
@Service
public class NameServiceImpl implements NameService {

    @Override
    public String updateName(String name) {
        return "新機器:" + name;
    }
}

我們發起十次遠程調用,其返回值分別如下:

舊機器:HelloDubbo
舊機器:HelloDubbo
新機器:HelloDubbo
舊機器:HelloDubbo
新機器:HelloDubbo
新機器:HelloDubbo
新機器:HelloDubbo
舊機器:HelloDubbo
新機器:HelloDubbo
新機器:HelloDubbo

我們可以發現,在默認情況下,其採取的是隨機的負載均衡策略。如果我們想要換一種負載均衡策略,例如就換成輪詢負載均衡,應該怎麼實現呢?

我們修改一下服務消費者的代碼,在 @Reference 註解中添加一個 loadbalance 屬性來指定負載均衡策略。

package edu.szu.consumer.serviceImpl;

import com.alibaba.dubbo.config.annotation.Reference;
import edu.szu.api.service.NameService;
import edu.szu.consumer.service.ChangeService;
import org.springframework.stereotype.Component;

@Component
public class ChangeServiceImpl implements ChangeService {

    @Reference(loadbalance = "roundrobin")
    NameService nameService;

    @Override
    public String change(String name) {
        return nameService.updateName(name);
    }
}

然後我們再發起十次遠程調用,其返回值分別如下:

舊機器:HelloDubbo
新機器:HelloDubbo
舊機器:HelloDubbo
新機器:HelloDubbo
舊機器:HelloDubbo
新機器:HelloDubbo
舊機器:HelloDubbo
新機器:HelloDubbo
舊機器:HelloDubbo
新機器:HelloDubbo

可見其完全遵循了輪詢的規則,也證明了我們的負載均衡策略設置成功。

參考:Dubbo的負載均衡

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章