詳解Golang net/http包中的RoundTripper接口
RoundTripper 是什么?
RoundTripper 是 net/http 包中的一個(gè)接口,定義了處理 HTTP 請求返回和響應(yīng)的方法,是 http.Client 結(jié)構(gòu)體中執(zhí)行 http 請求的核心部分。接口定義如下:
type RoundTripper interface { RoundTrip(*Request) (*Response, error) }
只定義了 RoundTrip 一個(gè)方法,用于執(zhí)行單個(gè) HTTP 事務(wù),發(fā)送請求數(shù)據(jù)并返回對應(yīng)的響應(yīng)數(shù)據(jù)。RoundTrip 不應(yīng)該去解析響應(yīng)數(shù)據(jù),特別是如果獲得了響應(yīng)數(shù)據(jù)后,RoundTrip 必須返回值為 nil 的 error(不管響應(yīng)的HTTP狀態(tài)碼是什么)。如果沒有獲得響數(shù)據(jù),應(yīng)返回一個(gè)非 nil 的 error,RoundTrip 也不應(yīng)該嘗試處理更高級的協(xié)議細(xì)節(jié),如重定向、身份驗(yàn)證或 cookie 等。
除了消費(fèi)和關(guān)閉請求的 Body 之外,RoundTrip 不應(yīng)該修改請求,RoundTrip 可以在單獨(dú)的 goroutine 中讀取請求的字段。在 Response Body 被關(guān)閉之前,調(diào)用方不應(yīng)該改變或重用請求。RoundTrip 必須始終關(guān)閉 body(即使遇到 error),但根據(jù)實(shí)現(xiàn),即使在 RoundTrip 返回之后也可以在單獨(dú)的 goroutine 中關(guān)閉。
使用場景
借助 RoundTripper 可以在每個(gè)請求中添加特定的 header 或者對返回的響應(yīng)數(shù)據(jù)進(jìn)行特定的處理,例如記錄日志或根據(jù)返回的狀態(tài)碼執(zhí)行對應(yīng)邏輯。接下來看一個(gè)用于實(shí)現(xiàn)鏈路追蹤功能,只需要實(shí)現(xiàn) RoundTripper 接口,在執(zhí)行 HTTP 請求的同時(shí),收集遙測數(shù)據(jù),如請求的持續(xù)時(shí)間、狀態(tài)碼等,這些數(shù)據(jù)可以用于性能監(jiān)控和故障排查。實(shí)現(xiàn) RoundTripper 接口的示例代碼如下:
package http_otel import ( "net/http" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" ) type OtelRoundTripper struct { original http.RoundTripper } func (ort *OtelRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { tracer := otel.Tracer("") ctx, span := tracer.Start(req.Context(), req.URL.Path) defer span.End() req = req.WithContext(ctx) resp, err := ort.original.RoundTrip(req) if err != nil { span.RecordError(err) span.SetStatus(codes.Error, err.Error()) } else { attrs := []attribute.KeyValue{ { Key: "http.status_code", Value: attribute.IntValue(resp.StatusCode), }, { Key: "http.method", Value: attribute.StringValue(req.Method), }, { Key: "http.route", Value: attribute.StringValue(req.URL.RequestURI()), }, { Key: "http.scheme", Value: attribute.StringValue(req.URL.Scheme), }, { Key: "http.user_agent", Value: attribute.StringValue(req.UserAgent()), }, } span.SetAttributes(attrs...) } return resp, err } func New() *OtelRoundTripper { return &OtelRoundTripper{ original: tripper, } }
使用 net/http 包實(shí)現(xiàn)鏈路追蹤代碼如下:
package main import ( "bytes" "fmt" "xxx/http-otel" "io" "net/http" ) func main() { reader := bytes.NewReader([]byte(`{"foo":"bar"}`)) request, err := http.NewRequest("POST", "http://xxx.com/user/list", reader) if err != nil { panic(err) } request = request.WithContext(traceCtx) // traceCtx 指上文的 context,這里使用偽代碼作演示 request.Header.Set("Content-Type", "application/json") client := http.Client{Transport: http_otel.New()} resp, err := client.Do(request) if err != nil { panic(err) } defer resp.Body.Close() b, err := io.ReadAll(resp.Body) fmt.Println(string(b), err) }
首先定義了一個(gè)用于實(shí)現(xiàn)鏈路追蹤功能的 OtelRoundTripper 結(jié)構(gòu)體,然后實(shí)現(xiàn)了 RoundTrip 方法。在 RoundTrip 方法中,首先開啟一個(gè)新的 trace span,并且將追蹤的信息編碼到 HTTP 請求的 header 中。在請求完成后,將返回的 HTTP 響應(yīng)信息記錄到 trace 中,并返回 HTTP 響應(yīng)數(shù)據(jù)。
小結(jié)
RoundTripper 接口的強(qiáng)大之處在于能夠以簡單且可擴(kuò)展的方式自定義和控制 HTTP 請求的處理。無論是添加特定的 header、處理響應(yīng)還是執(zhí)行其他更高級的邏輯,都可以借助 RoundTripper 來實(shí)現(xiàn)。
以上就是詳解Golang net/http包中的RoundTripper接口的詳細(xì)內(nèi)容,更多關(guān)于Golang RoundTripper接口的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用dep 配置golang 開發(fā)環(huán)境的操作方法
下面小編就為大家?guī)硪黄褂胐ep 配置golang 開發(fā)環(huán)境的操作方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09Go語言特點(diǎn)及基本數(shù)據(jù)類型使用詳解
這篇文章主要為大家介紹了Go語言特點(diǎn)及基本數(shù)據(jù)類型使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03go單例實(shí)現(xiàn)雙重檢測是否安全的示例代碼
這篇文章主要介紹了go單例實(shí)現(xiàn)雙重檢測是否安全,本文給大家分享雙重檢驗(yàn)示例代碼,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03Go Excelize API源碼解讀GetSheetViewOptions與SetPageLayo
這篇文章主要為大家介紹了Go Excelize API源碼解讀GetSheetViewOptions與SetPageLayout方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08Golang使用JWT進(jìn)行認(rèn)證和加密的示例詳解
JWT是一個(gè)簽名的JSON對象,通常用作Oauth2的Bearer?token,JWT包括三個(gè)用.分割的部分。本文將利用JWT進(jìn)行認(rèn)證和加密,感興趣的可以了解一下2023-02-02golang實(shí)現(xiàn)unicode轉(zhuǎn)換為字符串string的方法
這篇文章主要介紹了golang實(shí)現(xiàn)unicode轉(zhuǎn)換為字符串string的方法,實(shí)例分析了Go語言編碼轉(zhuǎn)換的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-07-07