You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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创建服务客户端并调用接口

核心逻辑说明

  1. passthrough解析器:不对传入的地址做任何解析,直接将地址传递给拨号器,完美适配bufconn的虚拟地址场景。
  2. 自定义拨号器:把连接请求直接导向bufconn的listener,确保客户端和服务端在虚拟网络中完成通信。

这样修改后,grpc.NewClient就能和bufconn正常配合,功能和原来的DialContext完全一致,同时避开了弃用API的问题。

内容的提问来源于stack exchange,提问作者Kurt Peek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 00:05:05