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

Go编写的gRPC客户端无法连接暴露的gRPC服务地址排查

问题描述

我用Go写了一个gRPC客户端,用来连接其他团队暴露的gRPC服务,服务地址是catalogue-go.domain.dev。用Postman gRPC客户端调用这个地址能正常拿到响应,但代码调用时出现如下错误:

2023-11-24T10:53:52.452+0530 ERROR utils/validation.go:256 received error from Catalogue gRPC server {"err": "rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial tcp: address catalogue-go.domain.dev""}

我的代码实现如下:

// Establish gRPC connection
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) // Waiting time(timeout)
defer cancel()
cataloguegRPCUrl := os.Getenv("CATALOGUE_GRPC_DOMAIN")
conn, err := grpc.DialContext(ctx, cataloguegRPCUrl, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
    zap.L().Error("Error setting up GRPC connection", zap.Reflect("err", err.Error()))
    return nil, errors.New(constant.SomethingWentWrong)
} else {
    zap.L().Info("Connection established with Catalogue GRPC server")
}
defer conn.Close()

// Connection established
client := numbers.NewNumberSubscriptionServiceClient(conn)

// Prepare gRPC metadata
md := metadata.New(
    map[string]string {
        // Required meta data added here
    })
ctx = metadata.NewOutgoingContext(ctx, md)

// Prepare input for gRPC call
inputPhoneNumber := numbers.ManageNumberRequest {
    Number: []string {
        number,
    },
}

// Calling the gRPC
zap.L().Debug("Request made to Catalogue gRPC", zap.String("cataloguegRPCUrl", cataloguegRPCUrl), zap.Reflect("metadata", md), zap.Reflect("input phone number", inputPhoneNumber.Number))
serverResponse, err := client.ManageNumbers(ctx, &inputPhoneNumber)
if err != nil {
    zap.L().Error("received error from Catalogue gRPC server", zap.Reflect("err", err.Error()))
    return nil, errors.New(constant.SomethingWentWrong)
}
zap.L().Debug("catalogue gRPC returned response", zap.Reflect("response", serverResponse))

克隆这个gRPC服务在本地运行时,代码能正常工作并获取响应,但连接线上暴露的服务地址就失败了,请问我遗漏了什么?

可能的原因及解决方案

1. 地址格式缺失端口

错误提示中的dial tcp: address catalogue-go.domain.dev说明地址解析失败,gRPC的DialContext要求地址必须明确包含端口号(除非服务使用默认的80/443端口,但gRPC通常使用50051这类自定义端口):

  • 检查环境变量CATALOGUE_GRPC_DOMAIN的值,确认是否带了端口,比如应该是catalogue-go.domain.dev:50051而非单纯的域名。
  • Postman可能自动补全了默认端口,但代码不会自动处理,必须显式指定。

2. DNS解析异常

本地代码的DNS解析环境可能和Postman不一致:

  • 在代码运行的机器上执行nslookup catalogue-go.domain.dev,验证是否能正常解析到服务IP。
  • 如果是内部域名,确认代码运行环境(如容器、服务器)的DNS配置能访问该内部域名。

3. TLS安全配置不匹配

你在代码中用grpc.WithTransportCredentials(insecure.NewCredentials())禁用了TLS,但线上服务可能开启了TLS加密:

  • Postman默认会适配TLS配置,但代码强制使用不安全连接会导致握手失败。
  • 解决方案:替换为TLS凭证,比如使用credentials.NewClientTLSFromCert(nil, "")(服务使用公开CA证书时),或者指定自定义CA证书。

4. 网络访问权限受限

代码运行的环境(如容器、服务器)可能没有访问线上服务的网络权限:

  • 检查防火墙、安全组规则,确认代码所在机器能访问目标服务的端口。
  • 对比Postman所在机器和代码运行机器的网络环境,排查是否存在网络隔离(比如Postman在办公网,代码在隔离的测试环境)。

5. 超时时间过短

你设置的上下文超时为5秒,线上网络延迟可能更高:

  • 尝试延长超时时间,比如改为10*time.Second,看是否能成功建立连接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 09:33:26