亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

每個主機的 Golang ReverseProxy

每個主機的 Golang ReverseProxy

Go
冉冉說 2022-11-28 10:36:25
我正在嘗試在 Go 中實現一個反向代理,它根據嵌入在 URL 中的某些租戶將流量代理到不同的主機。實現看起來像這樣:type Offloader struct {    tenantHostMap   map[string]string                   // Map a tenant to its host:port    tenantProxyMap  map[string](*httputil.ReverseProxy) // Map a tenant to its reverse proxy}func (o *Offloader) OnCreate() {    // Tenants Map    o.tenantHostMap = make(map[string]string)    o.tenantProxyMap = make(map[string]*httputil.ReverseProxy)    o.PopulateTenantHostMap()    // Rx    http.HandleFunc("/", o.ServeHTTP)    go http.ListenAndServe(":5555", nil)}// ServeHTTP is the callback that is called each time a Http Request is received.func (o *Offloader) ServeHTTP(w http.ResponseWriter, req *http.Request) {    incomingUrl := req.URL.RequestURI()    tenant := o.GetTenantFromUrl(incomingUrl)    if proxy, ok := o.tenantProxyMap[tenant]; ok {        proxy.ServeHTTP(w, req)    }    if remoteHostAddr, ok := o.tenantHostMap[tenant]; ok {        remoteUrl, err := url.Parse(fmt.Sprintf("http://%s", remoteHostAddr))        if err != nil {            return        }        proxy := httputil.NewSingleHostReverseProxy(remoteUrl)        o.tenantProxyMap[tenant] = proxy        proxy.ServeHTTP(w, req) // non blocking    } else {        panic("Unknown Tenant")    }}當收到新的 HTTP 請求時,我從 URL 中獲取租戶。如果這是我第一次看到這個租戶,我會創建一個新的 ReverseProxy,否則我會嘗試使用我之前創建并存儲在tenantProxyMap.當我對此進行測試時,出現以下錯誤:2022/04/05 12:31:01 http: proxy error: readfrom tcp ****: http: invalid Read on closed Body2022/04/05 12:31:01 http: superfluous response.WriteHeader call from net/http/httputil.(*ReverseProxy).defaultErrorHandler (reverseproxy.go:190)如果我為每個請求創建一個新的反向代理而不是重復使用相同的代理,則不會發生錯誤。我認為代理是按主機而不是按請求(顧名思義),所以我想知道為什么會發生此錯誤?我知道我需要保護地圖免受并發讀/寫的影響,但目前這無關緊要。
查看完整描述

1 回答

?
尚方寶劍之說

TA貢獻1788條經驗 獲得超4個贊

問題是,在以前的代理已經存在的情況下,您首先將請求傳遞給它 - 然后仍然重新創建代理,并再次傳遞請求。換句話說:當 tentantProxyMap 已經為該租戶填充時,您正在為每個傳入請求發出兩個代理請求。


該ReverseProxy實現會關閉req.Body,因此您第二次將請求傳遞給代理時,它會嘗試從已經關閉的主體中讀取。結果您看到了http: invalid Read on closed Body錯誤。


您應該嘗試在代理請求后返回,例如通過添加return:


if proxy, ok := o.tenantProxyMap[tenant]; ok {

    proxy.ServeHTTP(w, req)

    return

}


查看完整回答
反對 回復 2022-11-28
  • 1 回答
  • 0 關注
  • 132 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號