Spring Boot微服务连接K8s中EventStoreDB失败求助
我在本地Kubernetes集群中通过Helm Chart部署了EventStoreDB,通过端口转发2113可正常访问管理控制台localhost:2113/web/index.html。
现在尝试从同集群内的Spring Boot微服务连接该实例,使用的EventStoreDB客户端依赖如下:
<dependency> <groupId>com.eventstore</groupId> <artifactId>db-client-java</artifactId> <version>5.2.0</version> <scope>provided</scope> </dependency>
我编写了如下代码尝试建立连接并发布事件,但触发时appendToStream()无限挂起:
EventStoreDBClientSettings settings = EventStoreDBClientSettings.builder() .addHost("localhost", 1113) .tls(false) .defaultCredentials("admin", "changeit") .maxDiscoverAttempts(1) .buildConnectionSettings(); EventStoreDBClient client = EventStoreDBClient.create(settings); AppendToStreamOptions appendToStreamOptions = AppendToStreamOptions.get().expectedRevision(ExpectedRevision.noStream()); client.appendToStream("some-stream", appendToStreamOptions, eventData).get();
其中eventData的定义如下({myObject}为领域对象):
final EventData eventData = EventData.builderAsJson(UUID.randomUUID(), "some-event", {myObject}).build();
我也尝试过使用连接字符串配置连接:
String connectionString = "esdb://localhost:2113?tls=false"; EventStoreDBConnectionString.parseOrThrow(connectionString);
以及TCP连接字符串:
ConnectTo=tcp://localhost:1113; UseSslConnection=false;
但根据官方说明,TCP客户端已被弃用,推荐使用新版客户端方式。
执行过程无异常抛出,仅无限挂起,推测是appendToStream().get()等待CompleteableFuture响应导致。管理控制台也未显示任何连接和流。
我已尝试使用1113和2113两个端口,均未解决问题。请问无法连接或发布事件的原因是什么?
补充:环境为JDK 21.0.1、ESDB 4.1.1.0
1. 修正集群内服务访问地址
同K8s集群内的微服务不能用localhost访问EventStoreDB,必须使用EventStore部署时生成的Service名称作为主机名。比如Helm默认部署的Service名称为eventstore,则代码中应改为:
.addHost("eventstore", 2113)
2. 端口与客户端类型匹配
你使用的db-client-java是新版gRPC客户端,仅支持ESDB的2113端口(gRPC端口),1113是旧版TCP端口,新版客户端不兼容。确保代码中连接的是2113端口,同时检查Helm部署的Service是否正确暴露了2113端口。
3. 解决版本兼容性问题
db-client-java 5.2.0是为ESDB 20+版本设计的,而你使用的ESDB是4.1.1.0(旧版),版本完全不兼容:
- 若坚持使用ESDB 4.x,需切换到旧版TCP客户端,依赖配置如下:
<dependency> <groupId>com.geteventstore</groupId> <artifactId>eventstore-client</artifactId> <version>4.1.1</version> </dependency> - 若想使用新版gRPC客户端,需将ESDB升级到20.x及以上版本。
4. 避免同步阻塞导致死锁
不要用.get()同步阻塞CompletableFuture,尤其是在Spring Web线程或主线程中,极易引发死锁。建议改为异步处理:
client.appendToStream("some-stream", appendToStreamOptions, eventData) .thenAccept(result -> { // 处理事件发布成功逻辑 }) .exceptionally(ex -> { // 处理异常 ex.printStackTrace(); return null; });
若必须同步,可使用CompletableFuture.join()替代.get(),或确保调用线程不在阻塞上下文内。
5. 验证权限配置
检查Helm部署时配置的ESDB用户名密码是否正确,ESDB 4.x的默认凭据可能不是admin/changeit,可查看EventStore Pod的启动日志确认实际配置的凭据。
6. 排查网络策略限制
确认K8s集群中没有网络策略阻止微服务Pod与EventStore Pod之间的通信,确保两个Pod所在的Namespace允许互相访问。
内容的提问来源于stack exchange,提问作者Scott

