Netty 實戰篇:為自研 RPC 框架加入異步調用與 Future 支持

我們在上篇實現了一個輕量級 RPC 框架,現在要進一步優化 —— 加入異步響應支持,讓 RPC 通信變得真正高效、非阻塞、支持并發。


一、為什么需要異步調用?

上篇的 RPC 框架是“同步阻塞”的:

  • 每次發送請求后,必須等待服務端響應后才能返回結果

  • 對于高并發請求,會導致線程阻塞、資源浪費、吞吐低下

理想方案:客戶端請求后立即返回一個 Future 對象,等響應來了再異步設置結果,主線程不用阻塞。


二、核心機制:RequestId + ChannelFuture + Map 緩存

我們引入一個全局 ConcurrentHashMap<Long, CompletableFuture<RpcResponse>>:

public class RpcResponseRegistry {public static final Map<Long, CompletableFuture<RpcResponse>> futures = new ConcurrentHashMap<>();
}

每次發送請求時:

  • 生成唯一 requestId

  • 創建一個 CompletableFuture 存入 RpcResponseRegistry

  • 異步監聽服務端響應,當收到響應時設置結果


三、發送請求(非阻塞)

public class NettyClient {private static AtomicLong REQUEST_ID_GEN = new AtomicLong();public static CompletableFuture<RpcResponse> send(RpcRequest request, Channel channel) {long requestId = REQUEST_ID_GEN.incrementAndGet();request.setRequestId(requestId);CompletableFuture<RpcResponse> future = new CompletableFuture<>();RpcResponseRegistry.futures.put(requestId, future);channel.writeAndFlush(request); // 不阻塞等待return future;}
}

四、接收響應并完成 Future

服務端處理完成后寫出響應:

ctx.writeAndFlush(response);

客戶端接收時通過 requestId 找到對應的 future 并完成它:

public class RpcClientHandler extends SimpleChannelInboundHandler<RpcResponse> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, RpcResponse response) {long requestId = response.getRequestId();CompletableFuture<RpcResponse> future = RpcResponseRegistry.futures.remove(requestId);if (future != null) {future.complete(response);}}
}

五、客戶端調用示例

// 獲取動態代理
HelloService proxy = proxyFactory.getProxy(HelloService.class);// 發起異步調用
CompletableFuture<RpcResponse> future = NettyClient.send(request, channel);
future.thenAccept(response -> {System.out.println("異步結果:" + response.getResult());
});// 主線程可以干其他事情
System.out.println("我可以繼續做別的事情了!");

六、增強:自動類型轉換 + 異常處理

你可以在 Future 結果返回時:

  • 自動封裝返回值類型(比如String,List<T>)

  • 自動處理異常并打印日志

future.whenComplete((resp, ex) -> {if (ex != null) {System.err.println("RPC 異常: " + ex.getMessage());} else {System.out.println("返回結果: " + resp.getResult());}
});

七、總結

通過本篇的異步機制改造,我們的 Netty RPC 框架已經擁有了:

? 異步非阻塞調用
? CompletableFuture 響應映射
? 并發安全的請求響應管理
? 更高的吞吐能力和性能提升

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/85036.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/85036.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/85036.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

for(auto a:b)和for(auto a:b)的區別

#include<iostream> using namespace std; int main() {string s( "hello world" );for (auto c:s)c t ;cout<<s<<endl; //結果為hello worldfor (auto &c:s)c t ;cout<<s<<endl; //結果為ttttttttttt }for(auto a:b)中b為一…

超級對話2:大跨界且大綜合的學問融智學應用場景述評(不同第三方的回應)之二

摘要&#xff1a;《人機協同文明升維行動框架》提出以HIAICI/W公式推動認知革命&#xff0c;構建三大落地場景&#xff1a;1&#xff09;低成本認知增強神經接口實現300%學習效率提升&#xff1b;2&#xff09;全球學科活動化閃電戰快速轉化知識體系&#xff1b;3&#xff09;人…

多方法解決MNIST數字識別

全連接層 import torch from torchvision import datasets, transforms import torch.nn as nn import torch.optim as optim from tqdm import tqdm # 用于進度條顯示 import os# 定義數據預處理(標準化+Tensor轉換) transform = transforms.Compose([transforms.ToTensor…

安裝 Node.js 和配置 cnpm 鏡像源

一、安裝 Node.js 方式一&#xff1a;官網下載&#xff08;適合所有系統&#xff09; 訪問 Node.js 官網 推薦選擇 LTS&#xff08;長期支持&#xff09;版本&#xff0c;點擊下載安裝包。 根據系統提示一步步完成安裝。 方式二&#xff1a;通過包管理器安裝&#xff08;建…

vue 自定義組件的事件綁定

基本知識點 &#x1f3af;什么是自定義事件 自定義事件是子組件向父組件發送消息的機制&#xff0c;通常用于通知父組件發生了某些行為或狀態變化。 &#x1f4cc; 基本語法 子組件觸發事件&#xff08;$emit&#xff09; this.$emit(事件名, 參數);或在 const emit de…

進程同步機制-信號量機制-記錄型信號量機制中的的wait和signal操作

wait和signal是記錄型信號量機制中用于實現進程同步與互斥的兩個重要操作&#xff0c; wait 操作 wait(semaphores *S) {S->value --;if (S->value<0) block(S->list) }請求資源&#xff1a;S->value --; 這一步表示進程請求一個單位的資源&#xff0c;將信號…

sd webui 安裝sd-webui-TemporalKit 加載報錯解決辦法

ModuleNotFoundError: No module named moviepy.editer 報錯內容類似上面截圖&#xff0c;我的已經解決&#xff0c;暫時無法截圖了 處理方法&#xff1a; 重點說明&#xff1a;插件目錄必須是TemporalKit&#xff0c;不能更改 進入到安裝目錄&#xff1a;extensions\Tempor…

decimal.js庫處理js浮點數精度誤差問題

1、經常遇到前端計算金額的時候出現精度誤差問題&#xff0c;導致前后端計算的金額不一致導致校驗過不去的情況&#xff0c;相信有不少人寫過Math.floor(e*100)/100來實現保留2位小數&#xff0c;但是這么寫就會出現上面的精度問題。怎么解決呢&#xff1f;這里使用的是decimal…

如何將 WSL 的 Ubuntu-24.04 遷移到其他電腦

在使用 Windows Subsystem for Linux (WSL) 時&#xff0c;我們可能會遇到需要將現有的 WSL 環境遷移到其他電腦的情況。無論是為了備份、更換設備&#xff0c;還是在不同電腦之間共享開發環境&#xff0c;掌握遷移 WSL 子系統的方法都是非常有用的。本文將以 Ubuntu-24.04 為例…

RISCV——內核及匯編

RISCV——內核及匯編 小狼http://blog.csdn.net/xiaolangyangyang 1、寄存器組&#xff08;ABI&#xff09; 2、異常及中斷 XV6 trap&#xff08;二&#xff09;RISCV中斷異常處理/定時器中斷 mie&#xff1a;中斷開關mip&#xff1a;中斷狀態mstatus.mie&#xff1a;全局中斷…

算法日記32:埃式篩、gcd和lcm、快速冪、乘法逆元

一、埃式篩&#xff08;計算質數&#xff09; 1.1、概念 1.1.1、在傳統的計算質數中&#xff0c;我們采用單點判斷&#xff0c;即判斷(2~sqrt(n))是否存在不合法元素&#xff0c;若存在則判否&#xff0c;否則判是 1.1.2、假設&#xff0c;此時我們需要求1~1000的所有質數&am…

使用 mysqldump 獲取 MySQL 表的完整創建 DDL

要獲取 MySQL 中某個表的完整創建 DDL&#xff08;僅結構&#xff0c;不含數據&#xff09;&#xff0c;可以使用 mysqldump 工具的以下命令&#xff1a; 基本命令格式 bash mysqldump -h [主機名] -u [用戶名] -p --no-data --single-transaction --routines --triggers --…

Debian 系統 Python 開發全解析:從環境搭建到項目實戰

Debian 系統 Python 開發全解析:從環境搭建到項目實戰 在當今數字化時代,Python 憑借其簡潔易讀的語法和強大的功能,成為了最受歡迎的編程語言之一。Debian 作為一款穩定、安全且開源的 Linux 操作系統,為 Python 開發提供了理想的環境。本文將詳細介紹在 Debian 系統上進…

實時技術對比:SSE vs WebSocket vs Long Polling

早期網站僅展示靜態內容&#xff0c;而如今我們更期望&#xff1a;實時更新、即時聊天、通知推送和動態儀表盤。 那么要如何實現實時的用戶體驗呢&#xff1f;三大經典技術各顯神通&#xff1a; ? SSE&#xff08;Server-Sent Events&#xff09;&#xff1a;輕量級單向數據…

【前端】es6新特性全解

第一章 簡介 1.1 ES6概述 1.1.1 ES6定義與發展歷程 1. ES6 定義 ES6 全稱 ECMAScript 6.0&#xff0c;它是 JavaScript 語言的下一代標準&#xff0c;對 JavaScript 語言進行了許多增強和擴展&#xff0c;帶來了更簡潔、更強大的語法特性。可以把 ES6 想象成是 JavaScript …

nlp中的頻率就是權重嗎

&#x1f522; 一、“頻率”是什么&#xff1f; 在 NLP 中&#xff0c;**詞頻&#xff08;frequency&#xff09;**通常指的是&#xff1a; 某個單詞或 token 在語料庫中出現的次數&#xff08;或比例&#xff09; 舉例&#xff1a; "The cat sat on the mat. The cat i…

多模態大語言模型arxiv論文略讀(九十八)

Accelerating Pre-training of Multimodal LLMs via Chain-of-Sight ?? 論文標題&#xff1a;Accelerating Pre-training of Multimodal LLMs via Chain-of-Sight ?? 論文作者&#xff1a;Ziyuan Huang, Kaixiang Ji, Biao Gong, Zhiwu Qing, Qinglong Zhang, Kecheng Zhe…

WEB安全--RCE--webshell HIDS bypass4

繼WEB安全--RCE--webshell HIDS bypass3的補充&#xff1a; 十三、時間開關 webshell&#xff1a; <?php ini_set("display_errors",1); function foo($test, $bar FSYSTEM) {echo $test . $bar; } $function new ReflectionFunction(foo); $q new ParseEr…

.NET 7 AOT 使用及 .NET 與 Go 語言互操作詳解

.NET 7 AOT 使用及 .NET 與 Go 語言互操作詳解 目錄 .NET 7 AOT 使用及 .NET 與 Go 語言互操作詳解 一、背景與技術概述 1.1 AOT 編譯技術簡介 1.2 Go 語言與 .NET 的互補性 二、.NET 7 AOT 編譯實踐 2.1 環境準備 2.2 創建 AOT 項目 2.3 AOT 編譯流程 2.4 調試信息處…

機器人--里程計

教程 輪式里程計視頻講解 里程計分類 ros--odometry 什么是里程計 里程計是一種利用從移動傳感器獲得的數據來估計物體位置隨時間的變化而改變的方法。該方法被用在許多機器人系統來估計機器人相對于初始位置移動的距離。 注意&#xff1a;里程計是一套算法&#xff0c;不…