知識庫 / REST RSS 訂閱

Quarkus 中的負載均衡

REST
HongKong
5
03:34 AM · Dec 06 ,2025

1. 概述

`quarkus-load-shedding 擴展提供了一種機制,在高流量條件下主動拒絕請求,以防止應用程序或服務內的系統過載。該庫還暴露了關鍵的配置屬性,以幫助自定義負載削減的處理方式。

在本教程中,我們將學習如何將此擴展集成到我們的 Quarkus 應用程序中,並自定義其配置以滿足我們的特定需求。`

2. 安裝配置

為了演示 quarkus-load-shedding 擴展的關鍵功能,我們將使用兩個 Web 資源作為 REST 接口暴露:FibonacciResourceFactorialResource。 調用這些資源時,它們會在返回結果之前引入 1 到 15 秒的隨機響應延遲。

接下來,讓我們將擴展作為依賴項添加到我們的 Quarkus 項目中:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-load-shedding</artifactId>
</dependency>

當我們啓動應用時,如果處於開發模式,我們應該能夠在開發者 UI 上看到擴展程序:

./mvnw quarkus:dev

截至寫作時,此擴展程序仍處於實驗階段:

3. 默認負載削減

一旦添加了擴展,它將默認啓用。它將使用默認配置開始削減請求。

請編輯 application.properties 文件,以調整此配置,使其更嚴格:

quarkus.load-shedding.enabled=true
quarkus.load-shedding.max-limit=10
quarkus.load-shedding.initial-limit=5

此配置設置了允許的併發請求的初始和最大限制。<em title="max-limit">max-limit</em> 設置併發請求的上限,而<em title="initial-limit">initial-limit</em> 主要用於計算可接受的隊列大小。

現在,讓我們通過 JMeter 測試我們的配置。在 JMeter 中,我們設置了 7 個用户線程並行運行兩次,並設置了 5 秒的 ramp-up 週期:

運行此測試計劃,我們得到下面的結果,顯示 HTTP 503 錯誤率在兩個端點之間均勻分佈。

Label # Samples Average Min Max Std. Dev. Error %
Fibonacci HTTP Request 14 5735 2 12613 4517.63 28.571%
Factorial HTTP Request 14 5195 1 11470 4133.69 28.571%
TOTAL 28 5465 1 12613 4338.33 28.571%

<em title="quarkus-load-shedding">quarkus-load-shedding</em> 擴展根據 <em title="application.properties">application.properties</em> 中的配置,無差別地拒絕請求。

4. 自定義負載削減

<em>quarkus-load-shedding</em> 擴展暴露了一些配置,使我們能夠自定義負載削減行為。其中一項功能是能夠在系統負載過高時,優先削減哪些請求。 詳細內容請參見下一小節。

4.1. 請求優先級

首先,讓我們在我們的 application.properties 文件中啓用優先級設置:

# ...
quarkus.load-shedding.priority.enabled=true

現在,讓我們提供一個 RequestPrioritizer 的實現,以指定我們的請求優先級:

@Provider
public class LoadRequestPrioritizer implements RequestPrioritizer<HttpServerRequestWrapper> {
    @Override
    public boolean appliesTo(Object request) {
        return request instanceof HttpServerRequestWrapper;
    }

    //...
}

我們的 LoadRequestPrioritizer 類被標註為 @Provider 作為 CDI 豆,以便運行時能夠自動發現它。我們還指定它僅處理 HttpServerRequestWrapper 類型的請求。

接下來,我們為特定的目標端點分配優先級:

@Provider
public class LoadRequestPrioritizer implements RequestPrioritizer<HttpServerRequestWrapper> {
    //...
    @Override
    public RequestPriority priority(HttpServerRequestWrapper request) {
        String requestPath = request.path();
        if (requestPath.contains("fibonacci")) {
            return RequestPriority.CRITICAL;
        } else {
            return RequestPriority.NORMAL;
        }
    } 
}

因此,/fibonacci 端點將具有更高的優先級,這意味着 對該端點的請求比其他請求更不容易被拒絕

4.2. 觸發式負載檢測

由於 quarkus-load-shedding 擴展僅在檢測到系統負載過高時才應用優先級負載削減,接下來,我們模擬 CPU 負載:

@Path("/fibonacci")
public class FibonacciResource {
    //...
    @PostConstruct
    public void startLoad() {
        for (int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) {
            new Thread(() -> {
                while (true) {
                    Math.pow(Math.random(), Math.random());
                }
            }).start();
        }
    }
}

首次調用時,FibonacciResource@PostConstruct 觸發了一個 CPU 密集型任務,以確保在測試期間 CPU 負載保持在一定水平。重啓應用程序後,讓我們觸發一個初始請求到 /fibonacci 端點:

curl -X GET http://localhost:8080/api/fibonacci?iterations=9

接下來,我們使用相同的參數再次執行 JMeter 測試計劃,生成了以下結果:

Label # Samples Average Min Max Std. Dev. Error %
Fibonacci HTTP Request 14 5848 9 13355 4280.47 14.286%
Factorial HTTP Request 14 6915 10 14819 5905.41 28.571%
TOTAL 28 6381 9 14819 5184.86 21.429%

如表所示,由於該端點的優先級較高,因此在 /fibonacci 端點上的拒絕率較低。

4.3. 系統探測率

probeFactor 配置項影響擴展程序檢查系統請求處理能力波動發生的頻率。

默認情況下,probeFactor 設置為 30。為了比較該設置的影響,我們首先在 FibonacciResource 上僅運行一個 JMeter 測試計劃,使用 11 個用户線程:

下面是運行 JMeter 測試計劃後的結果:

Label # Samples Average Min Max Std. Dev. Error %
Fibonacci HTTP Request 33 8236 3 14484 4048.21 9.091%
TOTAL 33 8236 3 14484 4048.21 9.091%

正如預期的那樣,只有三個請求(即 33 個樣本乘以 9.091% 的錯誤率)由於我們在 application.properties 文件中將允許的最大併發請求設置為 10 時而被拒絕。

現在,讓我們將 probeFactor30 的默認值增加到 application.properties 文件中:

quarkus.load-shedding.probe-factor=70

然後,讓我們使用之前相同的配置重新運行 JMeter 測試,並查看結果:

標籤 # 樣本 平均值 最小值 最大值 標準差 誤差 %
Fibonacci HTTP 請求 33 6515 11 13110 3850.50 6.061%
總計 33 6515 11 13110 3850.50 6.061%

這次,只有兩個請求被拒絕。 設置較高的 <em probeFactor 可以降低系統對負載波動敏感度。

4.4. 隊列管理

<em>alphaFactor</em><em>betaFactor</em> 配置項控制了基於實際請求隊列大小,從初始值到最大限制值的增量和減量方式。要查看它們的效果,請將它們添加到我們的 <em>application.properties</em> 文件中:

quarkus.load-shedding.alpha-factor=1
quarkus.load-shedding.beta-factor=5

再次運行上一節中包含 11 個用户線程的 JMeter 測試,我們得到了以下結果:

從結果中可以看出,限制分配是逐步進行的,導致第六次請求被拒絕,即使最大限制尚未達到。

5. 結論

在本文中,我們瞭解到如何將 quarkus-load-shedding 擴展集成到我們的 Quarkus 應用程序中,從而使我們的系統在負載下能夠有效響應。我們還學習瞭如何自定義擴展以滿足我們的需求,通過調整其配置屬性,並對每個屬性的含義有了更深入的理解。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.