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

Go语言特定编译命令下HTTP GET请求失败问题求助

编译Go程序时启用CGO_ENABLED=0导致DNS解析失败的问题分析与解决

问题重现

使用Go的net/http包调用api.ipify.org获取公网IP时,常规编译/运行命令(go build get.go、go run get.go)完全正常,但使用以下静态编译命令后,程序运行出现DNS解析错误:

CGO_ENABLED=0 GOOS=linux go build -a -ldflags "-s -w" -o ip get.go

错误信息:

dial tcp: lookup api.ipify.org on [::1]:53: read udp [::1]:50975->[::1]:53: read: connection refused

使用的代码如下:

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
)

func get() {
    resp, err := http.Get("https://api.ipify.org")
    if err == nil {
        defer resp.Body.Close()
        bodyBytes, _ := ioutil.ReadAll(resp.Body)
        body := string(bodyBytes)
        fmt.Println(body)
    } else {
        fmt.Println(err)
    }
}

func main() {
    get()
}

原因分析

核心差异在于DNS解析器的实现方式:

  • 当CGO_ENABLED=1(默认状态,对应go build/go run)时,Go会调用系统C库的DNS解析器,它会自动处理IPv6/IPv4的回退逻辑,即使本地IPv6 DNS服务不可用,也会切换到IPv4的DNS服务器。
  • 当CGO_ENABLED=0时,Go会使用纯Go实现的DNS解析器,默认会优先尝试IPv6的DNS服务器(即[::1]:53),如果你的系统未启用IPv6 DNS服务(比如本地没有运行IPv6的DNS代理),就会触发连接拒绝的错误。

解决方法

方法1:强制纯Go编译时使用系统DNS解析器

编译时添加GODEBUG=netdns=cgo环境变量,让Go在CGO禁用的情况下依然调用系统DNS解析逻辑:

CGO_ENABLED=0 GOOS=linux GODEBUG=netdns=cgo go build -a -ldflags "-s -w" -o ip get.go

方法2:修改代码强制使用IPv4解析

自定义http.Client的Transport,禁用双栈解析,强制使用IPv4进行DNS查询和连接:

package main

import (
    "fmt"
    "io/ioutil"
    "net"
    "net/http"
    "time"
)

func get() {
    // 自定义Transport,禁用双栈,强制IPv4
    transport := &http.Transport{
        DialContext: (&net.Dialer{
            Timeout:   30 * time.Second,
            KeepAlive: 30 * time.Second,
            DualStack: false, // 关闭双栈,只使用IPv4
        }).DialContext,
    }
    client := &http.Client{Transport: transport}

    resp, err := client.Get("https://api.ipify.org")
    if err == nil {
        defer resp.Body.Close()
        bodyBytes, _ := ioutil.ReadAll(resp.Body)
        body := string(bodyBytes)
        fmt.Println(body)
    } else {
        fmt.Println(err)
    }
}

func main() {
    get()
}

方法3:配置系统DNS服务器

修改系统的/etc/resolv.conf,添加IPv4的公共DNS服务器(比如8.8.8.8、1.1.1.1),让纯Go解析器能找到可用的IPv4 DNS服务:

nameserver 8.8.8.8
nameserver 1.1.1.1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 00:22:04