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

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

http.Server {} - 多個處理程序?

http.Server {} - 多個處理程序?

Go
慕少森 2023-06-26 15:11:23
我有一個結構性問題:我不知道如何使用我現在構建它的方式(我可以找到可以看到它與其他模型一起使用的解決方案)。我使用的是 standard net/http,并使用以下代碼啟動我的服務器:gv := GlobalVars{    jobs:             make(chan QueueElement),    appConfig:        appConfig,}go worker(&gv)server := http.Server{    Handler: &gv,    Addr:    ":" + appConfig.Port,}log.Fatal(server.ListenAndServe())然后我有一個處理程序來檢查案例中的所有路由:func (gv *GlobalVars) ServeHTTP(w http.ResponseWriter, r *http.Request) {}應用程序正在啟動一些將作業傳遞到隊列的 API。我的問題是,我需要啟動其中的 3 個(不同的隊列,不同的配置)但具有相同的全局變量結構。但這一個只有一個我可以設置的處理程序 - 我如何添加多個處理程序(我不想要多個服務器,必須在同一端口上運行)來理解其尋址不同的全局變量?server := http.Server{    Handler: &gv,    Addr:    ":" + appConfig.Port,}去
查看完整描述

1 回答

?
慕的地10843

TA貢獻1785條經驗 獲得超8個贊

看一下net.http.ServeMux類型:

ServeMux 是一個 HTTP 請求多路復用器。它將每個傳入請求的 URL 與注冊模式列表進行匹配,并調用與 URL 最匹配的模式的處理程序。

ServeMux 本身就是一個http.Handler,并通過請求路由復用到不同的子處理程序。根據我對您問題的理解,您希望在同一服務器上有不同的處理程序,并且每個處理程序使用不同的配置來處理不同的隊列。

使用 ServeMux 可以輕松實現這一目標:

gv1 := GlobalVars{

? ? jobs:? ? ? ? ? ? ?make(chan QueueElement),

? ? appConfig:? ? ? ? appConfig1,

}

gv2 := GlobalVars{

? ? jobs:? ? ? ? ? ? ?make(chan QueueElement),

? ? appConfig:? ? ? ? appConfig2,

}

gv3 := GlobalVars{

? ? jobs:? ? ? ? ? ? ?make(chan QueueElement),

? ? appConfig:? ? ? ? appConfig3,

}


sm := http.NewServeMux()

// Let gv{1,2,3} handle routes{1,2,3} respectively

sm.Handle("/route1", &gv1)

sm.Handle("/route2", &gv2)

sm.Handle("/route3", &gv3)


// Register the ServeMux as the sole Handler. It will delegate to the subhandlers.

server := http.Server{

? ? Handler: sm,

? ? Addr:? ? ":" + globalAppConfig.Port,

}

請注意,您不必http.Server自己構建。如果您只需要一臺服務器,您可以使用 http 包級函數http.ListenAndServe和http.Handle來為您創建服務器和默認 ServeMux。


// same GlobalVars as above

// ...


// Instead of creating a ServeMux we can use the global DefaultServeMux

http.Handle("/route1", &gv1)

http.Handle("/route2", &gv2)

http.Handle("/route3", &gv3)


// Calling the package level ListenAndServe uses the single global server.

// Passing nil as the Handler uses the DefaultServeMux as Handler on which we registered the Handlers above.

log.Fatal(http.ListenAndServe(":" + globalAppConfig.Port, nil)

更新


標準的一個小例子ServeMux,其中兩個Handlers 服務 3 個路由


// Keeping this type simple for the example

type GlobalVars struct {

? ? appConfig string

}


// This method makes every GlobalVars a net.http.Handler

func (gv *GlobalVars) ServeHTTP(w http.ResponseWriter, req *http.Request) {

? ? fmt.Fprintf(w, "%s here. Receiving request for %s\n", gv.appConfig, req.URL.Path)

}


func main() {

? ? gv1 := &GlobalVars{

? ? ? ? appConfig: "gv1",

? ? }

? ? gv2 := &GlobalVars{

? ? ? ? appConfig: "gv2",

? ? }


? ? // Handle requires a route and a Handler, our gvs are Handlers.

? ? // gv1 handles two routes, while gv2 handles only one.

? ? http.Handle("/route1", gv1)

? ? http.Handle("/route2", gv1)

? ? http.Handle("/route3", gv2)


? ? log.Fatal(http.ListenAndServe(":8000", nil))

}

如果我依次調用所有三個路由,我將收到以下響應:


$ curl localhost:8000/route1

gv1 here. Receiving request for /route1

$ curl localhost:8000/route2

gv1 here. Receiving request for /route2

$ curl localhost:8000/route3

gv2 here. Receiving request for /route3

這展示了如何使用有狀態變量作為處理程序(例如 GlobalVars 類型的變量)。


注意:處理程序方法ServeHTTP有一個指針接收器GlobalVars。這意味著該方法可能會更改GlobalVars變量。HTTP 處理程序是并發執行的(想象一下在很短的時間內向同一處理程序發出多個請求,您將希望盡可能保持響應)。這個例子只讀取appConfig值,所以沒問題。然而,一旦對變量/字段進行寫入,您就需要適當的同步。


查看完整回答
反對 回復 2023-06-26
  • 1 回答
  • 0 關注
  • 141 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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