EventStoreDB三节点集群gRPC连接失败问题求助
EventStoreDB集群连接问题排查
我在Azure VM上部署了3节点EventStoreDB集群,使用C#代码连接并追加事件流时,出现**DiscoveryException(10次尝试未发现候选节点)及Grpc.Core.RpcException(StatusCode=DeadlineExceeded)**错误。本地可通过telnet连通节点地址,但gRPC连接存在问题。以下是相关信息:
客户端代码
var settings = EventStoreClientSettings.Create("esdb://admin:changeit@{node1IP}:2113,{node2IP}:2113,{node3IP}:2113?tls=true&tlsVerifyCert=false&keepAliveTimeout=10000&keepAliveInterval=10000"); var client = new EventStoreClient(settings); var evt = new { EntityId = Guid.NewGuid().ToString("N"), ImportantData = "I wrote my first event!" }; var eventData = new EventData( Uuid.NewUuid(), "TestEvent", JsonSerializer.SerializeToUtf8Bytes(evt) ); await client.AppendToStreamAsync( "some-stream", StreamRevision.None, new[] { eventData }); var result = client.ReadStreamAsync( Direction.Forwards, "some-stream", StreamPosition.Start); var events = await result.ToListAsync(); foreach (var eventIn in events) { Console.WriteLine($"event: {eventIn.ToString()}\n"); }
核心错误信息
DiscoveryException: Failed to discover candidate in 10 attempts.
节点配置文件(其余节点仅IP不同)
--- # Paths Db: /var/lib/eventstore Index: /var/lib/eventstore/index Log: /var/log/eventstore LogLevel: Information # LogFileInterval: 62 LogFileRetentionCount: 100 SkipDbVerify: True SkipIndexVerify: True ChunksCacheSize: 1073741824 CachedChunks: 4 # Certificates configuration CertificateFile: /etc/eventstore/certs/node.crt CertificatePrivateKeyFile: /etc/eventstore/certs/node.key TrustedRootCertificatesPath: /etc/eventstore/certs/ca # Network configuration ## TCP/IP Settings IntIp: 10.3.0.4 ExtIp: 10.3.0.4 IntTcpPort: 1112 ExtTcpPort: 1113 IntTcpHeartbeatInterval: 5000 IntTcpHeartbeatTimeout: 2000 ExtTcpHeartbeatInterval: 5000 ExtTcpHeartbeatTimeout: 2000 ## HTTP Settings HttpPort: 2113 HttpPortAdvertiseAs: 2113 # Cluster gossip ClusterSize: 3 DiscoverViaDns: false GossipSeed: 10.3.0.5:2113,10.3.0.6:2113 # Projections configuration RunProjections: All StartStandardProjections: True # Misc Settings EnableExternalTcp: True EnableAtomPubOverHTTP: True ---
控制台错误日志
Grpc.Core.RpcException: Status(StatusCode="DeadlineExceeded", Detail="") at EventStore.Client.Interceptors.TypedExceptionInterceptor.<AsyncUnaryCall>b__5_0[TRequest,TResponse](Task`1 t) at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke() at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj) at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location --- at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread) --- End of stack trace from previous location --- at EventStore.Client.GrpcServerCapabilitiesClient.GetAsync(CallInvoker callInvoker, CancellationToken cancellationToken) at EventStore.Client.EventStoreClientBase.GetChannelInfoExpensive(ReconnectionRequired reconnectionRequired, Action`1 onReconnectionRequired, IChannelSelector channelSelector, CancellationToken cancellationToken) at EventStore.Client.SharingProvider`2.FillBoxAsync(TaskCompletionSource`1 box, TInput input) at EventStore.Client.TaskExtensions.WithCancellation[T](Task`1 task, CancellationToken cancellationToken) at EventStore.Client.EventStoreClientBase.GetChannelInfo(CancellationToken cancellationToken) at EventStore.Client.EventStoreClient.<CreateStreamAppender>g__GetCall|14_0() at EventStore.Client.EventStoreClient.StreamAppender.IsUsable() at EventStore.Client.EventStoreClient.AppendToStreamAsync(String streamName, StreamRevision expectedRevision, IEnumerable`1 eventData, Action`1 configureOperationOptions, Nullable`1 deadline, UserCredentials userCredentials, CancellationToken cancellationToken) at TestClusterConnection.Program.Main() in /Users/krishna/Desktop/TestClusterConnection/TestClusterConnection/Program.cs:line 97 Unhandled exception. Grpc.Core.RpcException: Status(StatusCode="DeadlineExceeded", Detail="") at EventStore.Client.Interceptors.TypedExceptionInterceptor.<AsyncUnaryCall>b__5_0[TRequest,TResponse](Task`1 t) at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke() at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj) at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location --- at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread) --- End of stack trace from previous location --- at EventStore.Client.GrpcServerCapabilitiesClient.GetAsync(CallInvoker callInvoker, CancellationToken cancellationToken) at EventStore.Client.EventStoreClientBase.GetChannelInfoExpensive(ReconnectionRequired reconnectionRequired, Action`1 onReconnectionRequired, IChannelSelector channelSelector, CancellationToken cancellationToken) at EventStore.Client.SharingProvider`2.FillBoxAsync(TaskCompletionSource`1 box, TInput input) at EventStore.Client.TaskExtensions.WithCancellation[T](Task`1 task, CancellationToken cancellationToken) at EventStore.Client.EventStoreClientBase.GetChannelInfo(CancellationToken cancellationToken) at EventStore.Client.EventStoreClient.<CreateStreamAppender>g__GetCall|14_0() at EventStore.Client.EventStoreClient.StreamAppender.IsUsable() at EventStore.Client.EventStoreClient.AppendToStreamAsync(String streamName, StreamRevision expectedRevision, IEnumerable`1 eventData, Action`1 configureOperationOptions, Nullable`1 deadline, UserCredentials userCredentials, CancellationToken cancellationToken) at TestClusterConnection.Program.Main() in /Users/krishna/Desktop/TestClusterConnection/TestClusterConnection/Program.cs:line 97 at TestClusterConnection.Program.<Main>()
排查与解决步骤
1. 修复集群Gossip配置
当前节点的GossipSeed仅包含其他两个节点,需修改为包含所有集群节点(含自身),确保每个节点的配置一致:
GossipSeed: 10.3.0.4:2113,10.3.0.5:2113,10.3.0.6:2113
修改后重启所有EventStore节点,保证集群内部能正常发现彼此。
2. 检查Azure网络规则
- 确认Azure NSG(网络安全组)允许2113端口(gRPC/HTTP)、**1112/1113端口(内部/外部TCP)**的入站/出站流量,覆盖客户端IP和集群VM的IP范围。
- 检查VM本地防火墙,确保上述端口未被拦截。
3. 调整客户端连接参数
- 在连接字符串中添加
discover=false,强制客户端使用指定节点列表,跳过集群自动发现:var settings = EventStoreClientSettings.Create("esdb://admin:changeit@{node1IP}:2113,{node2IP}:2113,{node3IP}:2113?tls=true&tlsVerifyCert=false&keepAliveTimeout=10000&keepAliveInterval=10000&discover=false"); - 增加gRPC超时时间,避免网络延迟导致超时:
settings.TimeoutAfter = TimeSpan.FromSeconds(30);
4. 验证证书有效性
尽管客户端关闭了证书验证,仍需确保:
- 节点的
node.crt和node.key文件有效,且EventStore进程拥有读取权限。 - 自签名CA证书已放置在
TrustedRootCertificatesPath指定的目录中。
5. 确认集群运行状态
在每个节点执行以下命令,检查集群节点信息:
curl -k https://<node-ip>:2113/cluster/nodeinfo
若返回正常节点数据,说明集群内部通信正常;若无法访问,检查节点服务状态和端口监听:
netstat -tulpn | grep eventstore
内容的提问来源于stack exchange,提问作者Krishna
相关产品推荐
相关产品推荐

