詳解Golang net/http包中的RoundTripper接口
RoundTripper 是什么?
RoundTripper 是 net/http 包中的一個接口,定義了處理 HTTP 請求返回和響應的方法,是 http.Client 結(jié)構(gòu)體中執(zhí)行 http 請求的核心部分。接口定義如下:
type RoundTripper interface {
RoundTrip(*Request) (*Response, error)
}只定義了 RoundTrip 一個方法,用于執(zhí)行單個 HTTP 事務,發(fā)送請求數(shù)據(jù)并返回對應的響應數(shù)據(jù)。RoundTrip 不應該去解析響應數(shù)據(jù),特別是如果獲得了響應數(shù)據(jù)后,RoundTrip 必須返回值為 nil 的 error(不管響應的HTTP狀態(tài)碼是什么)。如果沒有獲得響數(shù)據(jù),應返回一個非 nil 的 error,RoundTrip 也不應該嘗試處理更高級的協(xié)議細節(jié),如重定向、身份驗證或 cookie 等。
除了消費和關(guān)閉請求的 Body 之外,RoundTrip 不應該修改請求,RoundTrip 可以在單獨的 goroutine 中讀取請求的字段。在 Response Body 被關(guān)閉之前,調(diào)用方不應該改變或重用請求。RoundTrip 必須始終關(guān)閉 body(即使遇到 error),但根據(jù)實現(xiàn),即使在 RoundTrip 返回之后也可以在單獨的 goroutine 中關(guān)閉。
使用場景
借助 RoundTripper 可以在每個請求中添加特定的 header 或者對返回的響應數(shù)據(jù)進行特定的處理,例如記錄日志或根據(jù)返回的狀態(tài)碼執(zhí)行對應邏輯。接下來看一個用于實現(xiàn)鏈路追蹤功能,只需要實現(xiàn) RoundTripper 接口,在執(zhí)行 HTTP 請求的同時,收集遙測數(shù)據(jù),如請求的持續(xù)時間、狀態(tài)碼等,這些數(shù)據(jù)可以用于性能監(jiān)控和故障排查。實現(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 包實現(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)
}首先定義了一個用于實現(xiàn)鏈路追蹤功能的 OtelRoundTripper 結(jié)構(gòu)體,然后實現(xiàn)了 RoundTrip 方法。在 RoundTrip 方法中,首先開啟一個新的 trace span,并且將追蹤的信息編碼到 HTTP 請求的 header 中。在請求完成后,將返回的 HTTP 響應信息記錄到 trace 中,并返回 HTTP 響應數(shù)據(jù)。
小結(jié)
RoundTripper 接口的強大之處在于能夠以簡單且可擴展的方式自定義和控制 HTTP 請求的處理。無論是添加特定的 header、處理響應還是執(zhí)行其他更高級的邏輯,都可以借助 RoundTripper 來實現(xiàn)。
以上就是詳解Golang net/http包中的RoundTripper接口的詳細內(nèi)容,更多關(guān)于Golang RoundTripper接口的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用dep 配置golang 開發(fā)環(huán)境的操作方法
下面小編就為大家?guī)硪黄褂胐ep 配置golang 開發(fā)環(huán)境的操作方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09
Go Excelize API源碼解讀GetSheetViewOptions與SetPageLayo
這篇文章主要為大家介紹了Go Excelize API源碼解讀GetSheetViewOptions與SetPageLayout方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-08-08
golang實現(xiàn)unicode轉(zhuǎn)換為字符串string的方法
這篇文章主要介紹了golang實現(xiàn)unicode轉(zhuǎn)換為字符串string的方法,實例分析了Go語言編碼轉(zhuǎn)換的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2016-07-07

