簡易RPC框架-客戶端限流配置

来源:http://www.cnblogs.com/ASPNET2008/archive/2017/10/23/7712974.html
-Advertisement-
Play Games

關鍵資源 關鍵資源總是有限的,也就意味著處理能力也有限,所以當面對大量業務時,為了保障自己能夠有序的提供服務最經濟的做法就是限制同一時間處理的事務數。比如銀行的工作人員,一個工作人員同時只能為一個客戶服務,來多了根本處理不了,不光是一種浪費而且有可以造成混亂的局面導致工作人員無法工作。 網路請求漏斗 ...


關鍵資源

關鍵資源總是有限的,也就意味著處理能力也有限,所以當面對大量業務時,為了保障自己能夠有序的提供服務最經濟的做法就是限制同一時間處理的事務數。比如銀行的工作人員,一個工作人員同時只能為一個客戶服務,來多了根本處理不了,不光是一種浪費而且有可以造成混亂的局面導致工作人員無法工作。

網路請求漏斗

越上層的伺服器處理的事務越輕,應付請求的能力也越強,也就意味著同一請求越上層處理時間越短。為了有效的保護下層伺服器,就需要對發送給下層的請求量做限流,在下層伺服器可接受的範圍內。否則就可能會出現下層伺服器資源耗盡而無法正常提供服務的情況。

限流場景

服務端限流

如果在服務端做限流,無論有多少個客戶端,總的提供能力是固定的(感謝@ xuanbg提出的評論,指出服務端也可以對客戶端做精準的判斷,後續我再想想實現方案),所以不會因為客戶端數量過多而導致資源不足,因為處理不過來的請求會被阻塞等待獲取資源。

缺點

缺點也比較明顯,由於服務提供者整體設置了最大限流數,此時所有的客戶端共用同一份限流數據,那麼有可能導致有的服務能分配到資源有些服務請求分配不到資源導致無法請求的情況。

客戶端限流

客戶端限流解決上服務端限流提到的問題,它能保證每個客戶端都能得到響應。但是從其它方面考慮,必須針對不同的客戶端做不同的限流策略:

  • 請求量大,但時效性不高,此時將限流數控制小一些會比較合適
  • 請求量大,但時效性高,此時將限流數適當調高
  • 響應時間長,即慢介面,適當降低
  • 主流業務,核心業務,適當調高
  • 非主流業務,適當降低
  • ......

缺點

  • 如果客戶端的數量不固定,那麼有可能導致客戶端數量過多造成大量請求打到服務端導致處理不了的結果,所以需要嚴格監控客戶端的調用情況。

  • 配置複雜,需要針對每個客戶端做相對精準的判斷

RPC實現

限流

這裡指的限流是指每秒從客戶端提交到服務端的請求數量。

過濾器機制可參考:簡易RPC框架-過濾器機制

服務引用註解上增加限流

public @interface RpcReference {
    boolean isSync() default true;

    /**
     * 客戶端最大併發數
     * @return
     */
    int maxExecutesCount() default 10;
}

創建動態代理時將限流參數傳遞到服務端

需要修改RpcProxy類,構造函數中增加服務引用註解參數,然後在invoke方法中從服務引用註解中獲取限流參數傳遞給request對象。

public RpcProxy(Class<T> clazz,ReferenceConfig referenceConfig,RpcReference reference) {
        this.clazz = clazz;
        this.referenceConfig=referenceConfig;
        this.reference=reference;
        this.isSync=reference.isSync();
    }

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        ...

        if (this.reference != null) {
            request.setMaxExecutesCount(this.reference.maxExecutesCount());
        }

        ...
    }

RpcInvocation增加限流參數

public interface RpcInvocation {

    ...

    int getMaxExecutesCount();

}

AbstractInvoker修改buildRpcInvocation方法

從request對象中獲取限流參數,傳遞給RpcInvocation對象。

public RpcInvocation buildRpcInvocation(RpcRequest request){
        RpcInvocation rpcInvocation=new RpcInvocation() {
            ...
            @Override
            public int getMaxExecutesCount() {
                return request.getMaxExecutesCount();
            }
        };
        return rpcInvocation;
    }

AccessLimitFilter

  • 修改令牌管理器

按介面分配令牌管理器,令牌管理器存儲在map中共用。如果未初始化則進行令牌管理器的初始化,如果已經初始化則直接申請令牌。

static class AccessLimitManager{

        private final static Object lock=new Object();

        private final static Map<String,RateLimiter> rateLimiterMap= Maps.newHashMap();

        public static void acquire(RpcInvocation invocation){
            if(!rateLimiterMap.containsKey(invocation.getClassName())) {
                synchronized (lock) {
                    if(!rateLimiterMap.containsKey(invocation.getClassName())) {
                        final RateLimiter rateLimiter = RateLimiter.create(invocation.getMaxExecutesCount());
                        rateLimiterMap.put(invocation.getClassName(), rateLimiter);
                    }
                }
            }
            else {
                RateLimiter rateLimiter=rateLimiterMap.get(invocation.getClassName());
                rateLimiter.acquire();
            }
        }
    }
  • 修改invoke方法

將invocation參數傳遞給acquire方法。

    public Object invoke(RpcInvoker invoker, RpcInvocation invocation) {
        logger.info("before acquire,"+new Date());
        AccessLimitManager.acquire(invocation);

        Object rpcResponse=invoker.invoke(invocation);
        logger.info("after acquire,"+new Date());
        return rpcResponse;
    }

客戶端

  • 服務引用配置限流

這裡配置每秒一個請求

@RpcReference(maxExecutesCount = 1)
private ProductService productService;
  • 執行結果

如下圖所示,每次請求相隔了一秒,達到了限流請求的目的。

待完善

  • 支持方法級限流

以上只支持客戶端介面級別的限流配置,可以再單獨創建一個方法級的註解來配置相關參數。

  • 支持服務端限流

服務端限流儘管有它的缺點,但為了更好的保護服務提供者,需要結合多種業務場景來配合客戶端限流一起完善,取長補短共同發揮作用。

本文源碼

https://github.com/jiangmin168168/jim-framework

文中代碼是依賴上述項目的,如果有不明白的可下載源碼


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 題目描述 現有n個正整數,n≤10000,要求出這n個正整數中的第k個最小整數(相同大小的整數只計算一次),k≤1000,正整數均小於30000。 輸入輸出格式 輸入格式: 第一行為n和k; 第二行開始為n個正整數的值,整數間用空格隔開。 輸出格式: 第k個最小整數的值;若無解,則輸出“NO RES ...
  • 1、簡介 從接觸yii框架到現在已經快有兩個月了,但是自己對yii框架的瞭解程度並不是很深,並沒有系統地去學習,僅僅只是在做項目的時候遇到不懂得知識才去翻手冊。 在上一個項目中因為需要將關聯的表的欄位顯示出來並且帶搜索排序功能,這個在之前並沒有接觸過,因此在手冊中查找了相關的資料把這個需求寫出來了, ...
  • 題目描述 一組數,分別表示地平線的高度變化。高度值為整數,相鄰高度用直線連接。找出並統計有多少個可能積水的低窪地? 如圖:地高變化為 0 1 0 2 1 2 0 0 2 0 輸入輸出格式 輸入格式: 兩行,第一行n,表示有n個數。第2行連續n個數表示地平線高度變化的數據,保證首尾為0。(3<=n<= ...
  • InputStream is = null;try { is = new FileInputStream(textPath); BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"), 512); / ...
  • 1.功能簡介 此程式模擬員工信息資料庫操作,按照語法輸入指令即能實現員工信息的增、刪、改、查功能。 2.實現方法 架構: 本程式採用python語言編寫,關鍵在於指令的解析和執行:其中指令解析主要運用了正則表達式來高效匹配有效信息;指令執行通過一個commd_exe主執行函數和增、刪、改、查4個子執 ...
  • [摘要] 對 Base64 編碼的簡介,常用場景舉例,編、解碼流程,以及如何在 Python 中使用 Base64編碼與解碼 ...
  • FIRSTCRM 學員管理開發需求: 1.分講師\學員\課程顧問角色, 2.學員可以屬於多個班級,學員成績按課程分別統計 3.每個班級至少包含一個或多個講師 4.一個學員要有狀態轉化的過程 ,比如未報名前,報名後,畢業老學員 5.客戶要有咨詢紀錄, 後續的定期跟蹤紀錄也要保存 6.每個學員的所有上課 ...
  • 縱觀現狀:大學是一個自由的小社會,無憂無慮,天真爛漫,然而當你正式步入社會,你會漸漸明白“你今後人生的艱難,恰恰是在一個能讓自己自由充分成長的黃金四年裡,卻把自己荒廢了”。難道我們非要“後知後覺”嗎? 展望未來:如果你以後有意從事編程的相關工作,你應該要知道,在找工作時和其他競爭者拉開差距的,起絕對 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...