gRPC错误:如何解决“在服务器前导接收之前连接关闭”的问题?

huangapple go评论91阅读模式
英文:

gRPC error: How to solve "Connection closed before server preface received"?

问题

我在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 := "在这里搜索"

response, err := txn.Query(context.Background(), dgraphQuery)
if err != nil {
	// 这里有错误
}

我收到了一个错误信息:

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

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

英文:

I deployed DgraphAlpha and DgraphZero in docker. I am connecting to Dgraph as described in the documentation.

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

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

And the client is created successfully, but when I try to search

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

dgraphQuery := "search here"

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

I get an error:

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

This error does not always occur, at unexpected moments, and because of this it is difficult for me to determine its root. Has anyone encountered something similar? What could be the problem?

答案1

得分: 5

除了其他暂时性原因外,导致此错误的常见原因是服务器启用了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)

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

英文:

Beside other transitory causes, a common cause of this error is the server running with TLS enabled and the client attempting to connect without TLS.

Make sure you correctly configured TLS options on the client:

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

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

conn, err := grpc.DialContext(ctx, &quot;&lt;connection_string&gt;&quot;, tlsOpt)

Make also sure you are actually using client certificates on the client connection.

答案2

得分: 1

可能是时间问题导致的。这种情况在最初的请求中可能更常见。你在Dgraph方面有任何日志吗?

考虑以下几点:

  1. 使用dial选项WithBlock()确保你有一个连接。
  2. 使用DialContext并使用带有超时的上下文,以避免等待太长时间。
  3. 注意,不安全的dial选项已被弃用。

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

关于错误:

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

状态码14

这似乎是一个临时错误。

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

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

英文:

It may be some issue with timing. This may happens more often in the first requests? Do you have any log on the Dgraph side?

Consider:

  1. Use dial option WithBlock() to ensure you have a connection
  2. Use DialContext and use a context with timeout to avoid wait a lot
  3. Be aware that Insecure dial option is deprecated

> Deprecated: use WithTransportCredentials and insecure.NewCredentials() instead.

About the error:

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

Status code 14

This seems a transient error.

You may retry after some time. There are some retriers that can be used on this case like:

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

huangapple
  • 本文由 发表于 2022年3月26日 20:14:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/71627962.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定