当前位置: 首页 > article >正文

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.lryc.cn/news/2392802.html

相关文章:

  • python37天打卡
  • 变焦位移计:机器视觉如何克服人工疲劳与主观影响?精准对结构安全实时监测
  • 嵌入式硬件篇---Ne555定时器
  • 【Axure结合Echarts绘制图表】
  • 使用web3工具结合fiscobcos网络部署调用智能合约
  • Oracle/openGauss中,DATE/TIMESTAMP与数字日期/字符日期比较
  • Datatable和实体集合互转
  • Win11切换JDK版本批处理脚本
  • 爬虫学习-Scrape Center spa6 超简单 JS 逆向
  • 对数的运算困惑
  • C++ 图像处理库 CxImage 简介 (迁移至OpenCV)
  • linux系统与shell 笔记
  • 尚硅谷redis7 86 redis集群分片之3主3从集群搭建
  • Kaggle-Predict Calorie Expenditure-(回归+xgb+cat+lgb+模型融合+预测结果)
  • 【解决办法】Git报错error: src refspec main does not match any.
  • React与Vue的内置指令对比
  • 2025年5月24号高项综合知识真题以及答案解析(第1批次)
  • 【NATURE氮化镓】GaN超晶格多沟道场效应晶体管的“闩锁效应”
  • Ubuntu24.04换源方法(新版源更换方式,包含Arm64)
  • 26 C 语言函数深度解析:定义与调用、返回值要点、参数机制(值传递)、原型声明、文档注释
  • 彻底理解一个知识点的具体步骤
  • FFmpeg 时间戳回绕处理:保障流媒体时间连续性的核心机制
  • yolov8改进模型
  • PostgreSQL日常运维
  • << C程序设计语言第2版 >> 练习 1-23 删除C语言程序中所有的注释语句
  • Fluence (FLT) 2026愿景:RWA代币化加速布局AI算力市场
  • 如何撰写一篇优质 Python 相关的技术文档 进阶指南
  • 选择if day5
  • MiniMax V-Triune让强化学习(RL)既擅长推理也精通视觉感知
  • Hash 的工程优势: port range 匹配