如果一个域名可以解析出多个IP地址,那想在http请求过程中知道程序实际请求的是哪个IP地址该怎么办?带着这个疑问我找到了两个方法来解决这个问题。
一个是通过httptrace.ClientTrace获取服务IP;
另一个是通过http.Transport中的DialContext获取服务IP;
具体代码如下:
package main import ( "context" "crypto/tls" "fmt" "log" "net" "net/http" "net/http/httptrace" ) // 方法一:通过httptrace.ClientTrace获取服务IP地址 func m1() { trace := &httptrace.ClientTrace{ DNSStart: func(_ httptrace.DNSStartInfo) {}, DNSDone: func(_ httptrace.DNSDoneInfo) {}, ConnectStart: func(net, addr string) { fmt.Printf("ConnectStart addr=%s ", addr) }, ConnectDone: func(net, addr string, err error) { fmt.Printf("ConnectDone addr=%s ", addr) }, GotConn: func(_ httptrace.GotConnInfo) {}, GotFirstResponseByte: func() {}, TLSHandshakeStart: func() {}, TLSHandshakeDone: func(_ tls.ConnectionState, _ error) {}, } req, err := http.NewRequest(http.MethodGet, "http://www.baidu.com", nil) if err != nil { log.Fatal(err) } req = req.WithContext(httptrace.WithClientTrace(context.Background(), trace)) resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() } // 方法二:通过DialContext获取服务IP地址 func m2() { req, err := http.NewRequest(http.MethodGet, "http://www.baidu.com", nil) if err != nil { log.Fatal(err) } client := http.Client{ Transport: &http.Transport{ DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { conn, err := net.Dial(network, addr) req.RemoteAddr = conn.RemoteAddr().String() return conn, err }, }, } resp, err := client.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() fmt.Println("RemoteAddr:", req.RemoteAddr) } func main() { m1() m2() }