如果一個域名可以解析出多個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\n", addr) }, ConnectDone: func(net, addr string, err error) { fmt.Printf("ConnectDone addr=%s\n", 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() }