Jaws:从零构建一个“五脏俱全“的 Java RPC 框架

📅 2026/7/20 11:35:36
Jaws:从零构建一个“五脏俱全“的 Java RPC 框架
Java 17|Netty 4.1|Spring Boot 3.5|SPI 全可插拔|开箱即用在 Java RPC 的世界里Dubbo 和 gRPC 早已是家喻户晓的名字。但当你真正去读它们的源码时往往会陷入几十万行代码的汪洋——核心逻辑被淹没在大量的兼容性代码、扩展点和历史包袱中。如果你渴望有一个 RPC 框架代码量可控、架构清晰、每一行都有意义同时又不失生产级该有的核心能力——那么 Jaws 正是为此而生。 为什么需要 Jaws痛点一RPC 框架会用但不懂大多数开发者对 RPC 框架的使用停留在配置层面——加个注解、写个 YAML、服务就跑起来了。但背后的协议编解码、服务注册发现、负载均衡、容错机制几乎是黑盒。面试被问到RPC 框架原理时你能讲清楚几层痛点二生产级能力不是可选项很多教学型 RPC Demo 只实现了最基本的调用链路缺少优雅停机发布时丢请求泛化调用网关无法依赖每个服务的接口 JAR可观测性链路追踪和指标采集方法级别配置不同方法不同超时/重试策略主流注册中心适配Nacos / ZooKeeper 双支持一键切换这些在生产环境中都是刚需。痛点三Spring Boot 集成体验参差不齐有些 RPC 框架的 Spring Boot 集成还停留在 XML 配置或复杂的 Bean 定义阶段。开发者需要的是两个注解搞定一切。 项目亮点✨ 1. 自定义二进制协议基于 Netty 实现的jaws二进制协议结构清晰编解码过程完全透明┌──────────┬──────────┬──────────┬──────────────┬──────────┬──────────┐ │ magic │ type │ id │ serialization│ status │ body │ │ 2 bytes │ 1 byte │ 8 bytes │ 1 byte │ 1 byte │ variable │ └──────────┴──────────┴──────────┴──────────────┴──────────┴──────────┘支持fastjson2和hessian2两种序列化方式可通过配置一键切换。️ 2. 双注册中心支持注册中心依赖说明ZooKeeperjaws-registry-zookeeper基于 Curator 5.9临时节点 心跳续约Nacosjaws-registry-nacos基于 Nacos 3.2.2支持心跳续约与失败重连切换注册中心只需更换一个 Maven 依赖和一行配置业务代码零改动。 3. 五种负载均衡策略策略适用场景Random默认简单高效RoundRobin均匀分配LeastActive热点感知慢节点自动降权ShortestResponse响应时间感知选择预估最快的节点ConsistentHash相同参数路由到同一节点适合缓存场景所有策略均通过 SPI 可插拔你可以轻松实现自定义策略。️ 4. 高可用容错Failover— 调用失败自动切换到其他节点可配置重试次数Failfast— 快速失败适用于非幂等写操作⚙️ 5. 四阶段优雅停机这是很多 RPC 教程忽略但生产环境至关重要的能力。Jaws 实现了完整的停机流程确保零请求丢失、零损伤发布Phase 1: stopAccept() 关闭 ServerChannel不再 accept 新连接 Phase 2: awaitInactiveRequests() 轮询 activeRequests 计数器等待在途请求完成默认 10s Phase 3: unregister() 从注册中心注销所有服务 URL Phase 4: unexport() → destroy() 移除 Provider、关闭连接、释放 EventLoopGroup 和线程池验证方式# 启动 Provider./run-sample.sh provider# 另开终端运行 Consumer./run-sample.sh consumer# 发送 SIGTERM 信号观察四阶段日志jps|grepSampleProvider# 找到 PIDkill-TERMPID# Provider 日志依次输出# [GracefulShutdown] Phase 1: Stop accepting new requests# [GracefulShutdown] Phase 2: Waiting for in-flight requests to complete# [GracefulShutdown] Phase 3: Unregister from registry# [GracefulShutdown] Phase 4: Close connections and release resources 6. 泛化调用无需依赖 Provider 的接口 JAR 包即可发起 RPC 调用。API 网关、测试平台、Mock 服务的必备能力// Spring Boot 注解方式JawsReference(generictrue,serviceInterfacecom.example.DemoService)privateGenericServicedemoService;// 调用ObjectresultdemoService.$invoke(hello,newString[]{java.lang.String},newObject[]{jaws});Provider 端自动完成 Map↔POJO 参数转换调用方完全无感知。 7. 可观测性引入jaws-observability-spring-boot-starter即可获得完整的可观测性能力能力实现说明链路追踪Micrometer Tracing OpenTelemetryW3C TraceContext 格式自动传播全链路 traceId 一致指标采集MicrometerRPC 调用次数、成功率、耗时分布、活跃请求数sidetag 区分 consumer/provider日志关联OTel 日志桥接traceId/spanId 自动注入 MDC无需手动处理无需额外代码Filter SPI 自动生效。 8. 方法级别配置全局配置不够精细Jaws 支持在消费端为单个方法设置独立的超时和重试策略JawsReference(methods{Method(namehello,timeout5000,retries3),// 这个方法单独配置Method(namegetUser,timeout500)// 这个方法快速失败})privateDemoServicedemoService; 9. injvm 协议JVM 内部直调零网络开销适合本地开发和单元测试./run-sample.sh injvm无需任何中间件一行命令即可运行。 10. RpcContext消费端可获取实际调用的服务端地址提供端可获取调用方 IP// Consumer 端URLserverUrlRpcContext.getContext().getServerUrl();// Provider 端StringcallerIpRpcContext.getContext().getCallerIp();️ 架构设计jaws-parent ├── jaws-core # 核心协议抽象、SPI、序列化、集群、路由、Filter、配置 ├── jaws-transport-netty # Netty 4.1 传输层实现 ├── jaws-registry-zookeeper # ZooKeeper 注册中心 ├── jaws-registry-nacos # Nacos 3.x 注册中心 ├── jaws-extensions # 可观测性Micrometer 指标 OpenTelemetry 链路追踪 ├── jaws-spring-boot │ ├── jaws-spring-boot-starter # Spring Boot 自动配置 │ └── jaws-observability-spring-boot-starter # 可观测性自动装配 └── jaws-samples ├── jaws-sample-api # 接口定义 ├── jaws-sample-injvm # injvm 协议示例无需 ZK ├── jaws-sample-provider # 服务提供者ZooKeeper ├── jaws-sample-consumer # 服务消费者 泛化调用 ├── jaws-sample-provider-boot # Spring Boot ProviderNacos ├── jaws-sample-consumer-boot # Spring Boot Consumer └── jaws-sample-benchmark # 性能基准测试核心设计理念SPI 全可插拔Protocol、Cluster、LoadBalance、Filter、Serialization 等所有核心组件均通过SPIActivation机制可插拔替换任何一层不影响其他模块分层解耦core 保持轻量extensions 承载附加功能starter 负责自动装配配置模型统一URL 参数 → ServiceConfig/ReferenceConfig → Spring YAML三层配置自动映射 学习价值对于想理解 RPC 原理的开发者✅ 从零实现协议编解码理解网络上传的是什么✅ 手写服务注册发现理解服务怎么找到对方✅ 五种负载均衡策略实现理解请求怎么分配✅ 四阶段优雅停机理解服务下线怎么不丢请求对于需要轻量 RPC 方案的团队✅ Spring Boot 两个注解开箱即用✅ 双注册中心ZK/Nacos自由选择✅ 泛化调用支持网关和测试平台场景✅ 可观测性 starter 一键引入对于架构师✅ SPI 扩展点设计模式参考✅ 自定义二进制协议设计✅ 优雅停机与在途请求管理✅ 依赖版本统一管理核心 jar 足够精简 快速开始前置要求Java 17Maven 3.8或使用内置./mvnwZooKeeper 3.9 或 Nacos 3.x三步启动1. 编译项目gitclone https://github.com/javahongxi/jaws.gitcdjaws ./mvnwinstall-DskipTests2. 引入依赖dependencygroupIdorg.hongxi/groupIdartifactIdjaws-spring-boot-starter/artifactIdversion${jaws.version}/version/dependencydependencygroupIdorg.hongxi/groupIdartifactIdjaws-registry-nacos/artifactIdversion${jaws.version}/version/dependency3. 发布与引用服务ProviderEnableJawsSpringBootApplicationpublicclassProviderApplication{publicstaticvoidmain(String[]args){SpringApplication.run(ProviderApplication.class,args);}}JawsServicepublicclassDemoServiceImplimplementsDemoService{OverridepublicStringhello(Stringname){returnhello name;}}ConsumerComponentpublicclassMyRunnerimplementsCommandLineRunner{JawsReferenceprivateDemoServicedemoService;Overridepublicvoidrun(String...args){System.out.println(demoService.hello(jaws));}}一键运行示例# injvm 协议无需中间件./run-sample.sh injvm# 完整 RPC 调用需要 ZK./run-sample.sh run# 性能基准测试./run-sample.sh bench-jaws# 自定义参数THREADS16DURATION20./run-sample.sh bench-jaws 技术栈组件技术版本语言Java17网络Netty4.1.132注册中心ZooKeeper Curator3.9 / 5.9注册中心Nacos3.2.2序列化fastjson2 / hessian-lite2.0.62 / 4.0.5框架集成Spring Boot3.5可观测性Micrometer OpenTelemetry1.14 / 1.48工具Guava33.6 相关链接项目地址: https://github.com/javahongxi/jaws作者主页: hongxi.orgJava 全栈研究: whatsmars☁️微服务最佳实践: spring-cloud-samplesSpring Boot: https://spring.io/projects/spring-bootNetty: https://netty.ioNacos: https://nacos.io 贡献指南欢迎提交 Issue 和 PR如果你发现 Bug 或有更好的实现方案想添加新的容错策略或负载均衡算法希望支持更多序列化方式或注册中心对性能优化有经验或建议请随时参与贡献让 Jaws 成为学习 RPC 原理的最佳参考项目© hongxi.org| 以生产级标准打造最清晰的 Java RPC 框架实现 结语Jaws 不是要取代 Dubbo 或 gRPC而是回答一个问题一个生产级 RPC 框架最少需要多少代码答案是2万行 Java。从协议设计到服务发现从负载均衡到优雅停机从泛化调用到链路追踪——每一个模块都经过精心设计每一行代码都有实际意义。没有几十万行的历史包袱没有看不懂的魔法。如果你正在 想深入理解 RPC 框架的核心原理 需要一个轻量级但功能完整的 RPC 方案️ 学习 SPI 扩展点设计和自定义协议实现 寻找一个代码量可控、可以通读的框架源码Star ⭐ Jaws开启你的 RPC 原理探索之旅gitclone https://github.com/javahongxi/jaws.gitcdjaws ./run-sample.sh injvm让我们一起探索 RPC 框架的本质