gRPC 错误:如何解决“在收到服务器前言之前已关闭连接”?

我在 docker 中部署了 DgraphAlpha 和 DgraphZero。我正在按照文档中的说明连接到 Dgraph。

func newClient() *dgo.Dgraph {
    d, err := grpc.Dial("localhost:9080", grpc.WithInsecure())
    if err != nil {
        log.Fatal(err)
    }

    return dgo.NewDgraphClient(
        api.NewDgraphClient(d),
    )
}

并且客户端创建成功,但是当我尝试搜索时

txn := i.dgraphClient.NewReadOnlyTxn()
defer txn.Discard(context.Background())

dgraphQuery := "search here"

response, err := txn.Query(context.Background(), dgraphQuery)
if err != nil {
    // error here
}

我收到一个错误:

rpc error: code = Unavailable desc = connection closed before server preface received

这个错误并不总是在意想不到的时刻发生,因此我很难确定它的根源。有没有人遇到过类似的事情?可能是什么问题呢?

stack overflow gRPC error: How to solve "Connection closed before server preface received"?
原文答案

答案:

作者头像

时间可能有些问题。这可能在第一个请求中更频繁地发生?你在 Dgraph 端有日志吗?

考虑:

1.使用拨号选项WithBlock()来确保你有一个连接

  1. 使用 DialContext 并使用带超时的上下文以避免大量等待
  2. 请注意不安全拨号选项已弃用

已弃用:改用 WithTransportCredentials 和 insecure.NewCredentials()。

关于错误:

https://grpc.github.io/grpc/core/md_doc_statuscodes.html

状态码 14

这似乎是一个暂时的错误。

您可以在一段时间后重试。在这种情况下可以使用一些重试器,例如:

https://pkg.go.dev/github.com/eapache/go-resiliency/retrier

作者头像

除了其他暂时性原因外,此错误的常见原因是服务器在启用 TLS 的情况下运行,而客户端尝试在没有 TLS 的情况下进行连接。

确保您在客户端上正确配置了 TLS 选项:

tlsConfig := &tls.Config{
    Certificates: []tls.Certificate{myCertificate},
    RootCAs:      myCAPool,
}

tlsOpt := grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig))

conn, err := grpc.DialContext(ctx, "<connection_string>", tlsOpt)

还要确保您实际上在客户端连接上使用 client 证书。