如何将bufconn包与grpc.NewClient正确配合使用?
解决bufconn配合grpc.NewClient的地址解析问题
问题根源很明确:grpc.NewClient默认使用DNS解析器,而bufconn用的是虚拟地址(比如常用的"bufnet"),DNS解析器找不到对应的真实地址,所以报出"produced zero addresses"错误。旧的DialContext内部自动加了passthrough解析器,它会直接把地址原封不动传给拨号器,不会做DNS解析,因此能正常工作。
要让两者配合,只需手动给grpc.NewClient加上passthrough解析器,并保留bufconn的自定义拨号逻辑即可,具体代码修改如下:
示例代码
首先是bufconn的listener初始化和服务启动部分(这部分无需改动):
import ( "context" "net" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/resolver/passthrough" "google.golang.org/grpc/test/bufconn" ) // 初始化bufconn listener lis := bufconn.Listen(1024 * 1024) defer lis.Close() // 启动gRPC服务到bufconn listener server := grpc.NewServer() // 注册你的服务... go func() { if err := server.Serve(lis); err != nil { // 处理错误 } }()
然后是替换成grpc.NewClient的客户端创建代码:
// 创建passthrough解析器构建器 resolverBuilder := passthrough.NewBuilder() // 创建gRPC客户端 conn, err := grpc.NewClient( "bufnet", // 沿用之前DialContext使用的虚拟地址 grpc.WithResolvers(resolverBuilder), // 显式指定passthrough解析器 grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) { // 自定义拨号逻辑,直接连接到bufconn的listener return lis.Dial() }), grpc.WithTransportCredentials(insecure.NewCredentials()), // 测试环境使用不安全凭证 ) if err != nil { // 处理连接错误 } defer conn.Close() // 后续可通过conn创建服务客户端并调用接口
核心逻辑说明
- passthrough解析器:不对传入的地址做任何解析,直接将地址传递给拨号器,完美适配bufconn的虚拟地址场景。
- 自定义拨号器:把连接请求直接导向bufconn的listener,确保客户端和服务端在虚拟网络中完成通信。
这样修改后,grpc.NewClient就能和bufconn正常配合,功能和原来的DialContext完全一致,同时避开了弃用API的问题。
内容的提问来源于stack exchange,提问作者Kurt Peek
相关产品推荐
相关产品推荐

