# XYRPC **Repository Path**: j67mk2/xyrpc ## Basic Information - **Project Name**: XYRPC - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-04 - **Last Updated**: 2026-09-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # XYRPC 基于 TCP 长连接二进制帧协议的轻量 RPC 框架(Java / JDK 21 + Netty + Protobuf)。 - 产品文档:[`docs/product.md`](docs/product.md) - 协议规范:[`docs/protocol-v1.md`](docs/protocol-v1.md)(V1,实现与规范冲突时以规范为准) - P1+P2 模块计划:[`docs/plan-p1p2.md`](docs/plan-p1p2.md) ## 仓库结构 ``` xyrpc/ ├── pom.xml # 聚合父 POM(dependencyManagement 统一版本) ├── docs/ # product / protocol / plan / ADR / 压测报告 ├── proto/ # 顶层 .proto IDL(registry.proto 冻结契约由 xyrpc-proto 生成) ├── xyrpc-core/ # 协议帧模型 + 编解码 + Codec SPI + 安全层 SPI(唯一协议出入口) ├── xyrpc-proto/ # registry.proto 唯一 codegen 归属(生成物模块,零手写逻辑) ├── xyrpc-server/ # 服务端(注册 / 分发 / 线程池隔离 / GoAway / deadline / 注册生命周期) ├── xyrpc-client-java/ # Java 客户端(连接池 / 多路复用 / 心跳 / 重连 / 动态代理) ├── xyrpc-registry-client/# Registry SPI + 注册中心客户端 SDK + 服务发现(轮询/缓存兜底/L1 路由/慢启动) ├── xyrpc-registry/ # 单节点注册中心(本身即第一个 XYRPC 服务,dogfooding) ├── xyrpc-examples/ # 示例服务与端到端验收载体(含 --tls / --registry 演示) ├── scripts/ # 故障演练脚本(GoAway 滚动发布 / 断连重连 / 注册中心 kill -9,见 scripts/README.md) └── benchmarks/ # P2 并发压测与性能基线(报告入 docs/benchmark-v0.2-baseline.md) ``` 模块依赖方向(下游只依赖上游,无环): ``` xyrpc-core ──┬──> xyrpc-server ───────────────┐ └──> xyrpc-client-java ──┬───────┼──> xyrpc-examples ──> benchmarks xyrpc-proto ──┬──> xyrpc-registry ────┘ │ └──> xyrpc-registry-client ─────┘(server 经它自注册,client 经它服务发现) ``` ## 环境要求 - **JDK 21+**(`maven.compiler.release=21`,enforcer 强制) - Maven 3.9+(推荐使用仓库内 Maven Wrapper:`./mvnw`) ## Quickstart(三分钟) 端到端跑通一次真实 RPC:启动示例服务端 → 客户端直连调用(同步 / 异步 / trace-id 透传)。 ```bash # 0. 需要 JDK 21+(如 macOS Homebrew:export JAVA_HOME=/opt/homebrew/opt/openjdk@21) # 1. 构建并安装到本地仓库(首次会按平台自动下载 protoc,无需本机安装) ./mvnw -q install -DskipTests # 2. 终端一:启动示例服务端(缺省端口 9000,可追加参数指定端口) ./mvnw -q -pl xyrpc-examples exec:java -Dexec.mainClass=com.xyrpc.examples.server.ExampleServer # 预期输出: # XYRPC example server listening on port 9000 (services: user.UserService, echo.EchoService; Ctrl+C = graceful GoAway shutdown) # 3. 终端二:客户端直连调用 ./mvnw -q -pl xyrpc-examples exec:java -Dexec.mainClass=com.xyrpc.examples.client.ExampleClient # 预期输出: # [sync ] GetUser(user_id=1) -> name="alice" # [async] GetUser(user_id=2) -> name="bob" # [sync ] Echo("hello xyrpc") -> text="hello xyrpc" # [meta ] GetUser(user_id=1, trace-id=abc123) -> name="alice" # All example calls completed. # 4. 回到终端一 Ctrl+C:触发 GoAway 优雅关闭(规范 §6.4),日志可见 XyRpcServer closed ``` ### TLS 模式(--tls,运行期自签名,零密钥入仓) ```bash # 终端一:服务端以 --tls 启动——运行期调 openssl 生成自签名证书(系统临时目录,仅示例用) ./mvnw -q -pl xyrpc-examples exec:java -Dexec.mainClass=com.xyrpc.examples.server.ExampleServer -Dexec.args="--tls" # 终端二:客户端 --tls 与之配对(缺省读取服务端生成的证书为信任锚) ./mvnw -q -pl xyrpc-examples exec:java -Dexec.mainClass=com.xyrpc.examples.client.ExampleClient -Dexec.args="--tls" # 预期末行:All example calls completed. (over TLS) ``` TLS 开/关两端全部组合(on-on / off-off / 双向混配失败 / mTLS / 信任锚不匹配)的 预期行为与对应测试见 [`docs/tls-matrix.md`](docs/tls-matrix.md)。 ### 服务发现模式(--registry,P3) 注册中心本身即第一个 XYRPC 服务(dogfooding,协议帧零改动)。三端各开一个终端: ```bash # 终端一:启动注册中心(缺省端口 8900) ./mvnw -q -pl xyrpc-registry exec:java -Dexec.mainClass=com.xyrpc.registry.server.RegistryServer # 终端二:服务端自注册(--advertise 缺省 127.0.0.1 仅本机演示;多网卡部署必须显式指定) ./mvnw -q -pl xyrpc-examples exec:java -Dexec.mainClass=com.xyrpc.examples.server.ExampleServer \ -Dexec.args="--registry localhost:8900 --version v1" # 终端三:客户端经发现调用(--version v1 演示 L1 灰度:只打 v1 实例) ./mvnw -q -pl xyrpc-examples exec:java -Dexec.mainClass=com.xyrpc.examples.client.ExampleClient \ -Dexec.args="--registry localhost:8900 --version v1" # 预期输出: # [disc ] GetUser(user_id=1) -> name="alice" # [disc ] Echo("hello registry") -> text="hello registry" # [meta ] GetUser(user_id=1, trace-id=abc123) -> name="alice" # All example calls completed. (via service discovery, L1 version='v1') ``` 行为要点:注册中心未起时服务端照常启动提供服务(注册后台指数退避重试,初始 1s/倍率 2/上限 30s); Ctrl+C 服务端时序「停续约 → Unregister → GoAway drain」(注册中心视图即时摘除该实例)。 灰度演示:再以不同端口起一台 `--version v2` 服务端,客户端 `--version v1` 只打 v1 实例。 端到端证据见 `RegistryDiscoveryEndToEndTest`(`./mvnw -pl xyrpc-examples -am test`); 韧性证据见 `bash scripts/drill-registry-kill.sh`(kill -9 注册中心后 consumer 经内存视图 + 文件缓存继续调用,重启后续约 404 → 重注册自愈,五判据全过 = P3 验收通过)。 设计取舍见 ADR:[`adr-003`](docs/adr-003-registry-storage.md)(内存存储)/ [`adr-004`](docs/adr-004-renew-granularity.md)(按 endpoint 批量注册+续约)/ [`adr-005`](docs/adr-005-lazy-cache-fallback.md)(懒兜底缓存)。 示例代码位置:服务实现 `xyrpc-examples/src/main/java/com/xyrpc/examples/{user,echo}/`, 启动入口 `.../{server,client}/`,端到端验收测试 `xyrpc-examples/src/test/java/com/xyrpc/examples/` (`./mvnw -pl xyrpc-examples -am test` 一键复验:真实 TCP loopback 上的同步/异步调用、 32 路并发多路复用归位、timeout-ms 跨进程 408 且业务零执行、trace-id 透传、GoAway 优雅关闭)。 ## 故障演练(P2/P3 验收) 真实进程级故障演练脚本入仓库([`scripts/`](scripts/README.md),产品文档 §6 可测试性): ```bash export JAVA_HOME=/opt/homebrew/opt/openjdk@21 bash scripts/drill-goaway.sh # 滚动发布零请求失败演练(SIGTERM → GoAway → 重连新实例) bash scripts/drill-reconnect.sh # 断连重连演练(kill -9 → 指数退避 → 重启恢复) bash scripts/drill-registry-kill.sh # 注册中心 kill -9 演练(P3 验收本体:内存视图 + 文件缓存兜底 + 重启自愈,五判据) ``` 三脚本均输出 PASS/FAIL 与统计数字(退出码 0 = PASS);五阶段剧本与判据口径见 plan-p3 §4 D7,实现说明与已知边界见 [`scripts/README.md`](scripts/README.md)。 ## 协议红线速览(写代码前必读,详见计划 §5) 1. 协议只增不改:帧格式演进只允许新增 Type 与 Meta Key 2. 全协议大端序,无例外;hex 对拍测试(规范 §10)是唯一裁决 3. 单帧 8MB 硬上限,BodyLen 校验必须先于任何内存分配 4. 失败即断连(Magic / Version / 未知 Type / Body 超限)不可降级为忽略 5. 500 的 ErrMsg 只带异常摘要,绝不回传堆栈 6. 核心零 Spring(enforcer 已强制);注册中心、Starter、gzip、流式本期出界 7. 传输加密只有 TLS 一条路,绝不自研加密协议进生产路径 ## 测试证书声明 后续 P2 接入的测试证书/私钥仅限测试目录使用,**禁止生产使用**(计划 §5.2 红线 10)。