Skip to content

fix: harden service startup and discovery lifecycle - #10

Merged
xiaoyumuxi merged 1 commit into
mainfrom
fix/p1-service-lifecycle-discovery
Sep 14, 2026
Merged

xiaoyumuxi merged 1 commit into
mainfrom
fix/p1-service-lifecycle-discovery

Conversation

@xiaoyumuxi

Copy link
Copy Markdown
Owner

目标

继续完成 P1 级别的工程化完善,集中处理服务启动顺序、Spring Boot 生命周期和 Nacos 服务发现缓存正确性。

1. bind 成功后再发布服务

之前 RpcServer.register() 会立即写注册中心,而底层 Netty 端口可能尚未 bind,存在“注册中心可见但端口未 ready”的窗口。

本次调整生命周期语义:

  • TransportServer.start() 只负责启动并在监听端口 bind 成功后返回
  • 新增 TransportServer.awaitTermination()
  • RpcServer.register() 在启动前只登记本地服务,不再提前发布
  • RpcServer.start() 严格执行:transport bind -> publish services
  • 启动完成后新增服务仍会立即发布
  • ProviderApp 显式 start() 后调用 awaitTermination()

新增 RpcServerLifecycleTest 固定验证 bind/publish 顺序。

2. Spring Boot 使用 SmartLifecycle

移除原先:

  • CommandLineRunner
  • 手工 daemon thread

改为 SmartLifecycle:

  • Spring Context 启动时同步启动 RpcServer
  • bind/注册失败会直接向上抛出,避免后台线程静默失败
  • Context 关闭时自动 RpcServer.close()
  • 高 phase 保证 RPC 服务启动靠后、关闭靠前

新增 Starter 生命周期单测,并将 rpc-spring-boot-starter 纳入主 CI unit-test job。

3. 修复 Nacos stale cache

NacosServiceDiscovery 由 static 全局缓存改为实例级状态:

  • 缓存和订阅不再跨 RpcClient 实例共享
  • Nacos 明确返回空实例时立即删除旧缓存,不再继续路由到已下线节点
  • 只有真实 Nacos 网络/协议异常时才允许 fallback 到最近一次成功缓存
  • 订阅事件为空时同样删除缓存
  • close() 会幂等取消订阅、清缓存并关闭 NamingService
  • ServiceDiscovery 增加 AutoCloseable 契约
  • RpcClient.close() 同时释放 TransportClient 和 ServiceDiscovery

测试覆盖:

  • 同服务只订阅一次
  • 网络异常缓存回退
  • 空实例权威结果清理 stale cache
  • close 取消订阅并 shutdown NamingService

CI

主 Unit Tests 现在覆盖:

  • rpc-core
  • rpc-transport-netty
  • rpc-spring-boot-starter

等待 Build / Unit Tests & Coverage / RPC Integration / CI Gate 全量验证。

@xiaoyumuxi
xiaoyumuxi merged commit 4e8caab into main Sep 14, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant