php小編小新在這裡為大家介紹如何使用Service Weaver來設定多個不同偵聽器的問題。 Service Weaver是一個功能強大的工具,它允許開發人員建立和管理多個服務。透過設定不同的偵聽器,我們可以實現對不同的服務進行監控和管理。在本文中,我們將詳細討論如何使用Service Weaver來設定和管理多個不同偵聽器,以便更好地控制和最佳化我們的服務。無論您是初學者還是有經驗的開發人員,本文都將為您提供詳細的指導和實用的技巧。讓我們一起來探索吧!
我一直在使用 Service Weaver,它已經發布了一段時間,並且很好奇我們應該如何使用它來設定多個偵聽器。我的意圖是,當我們部署應用程式時,web
的處理程序和 api
的處理程序單獨運行(作為範例)。我的程式碼目前如下:
<code>package main import ( "context" "log" "sync" "github.com/ServiceWeaver/weaver" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" ) type Server struct { weaver.Implements[weaver.Main] apiServer weaver.Ref[APIServer] webServer weaver.Ref[WebServer] } type APIServer interface { Serve(context.Context) error } type apiServer struct { weaver.Implements[APIServer] api weaver.Listener } func (a apiServer) Serve(ctx context.Context) error { logger := a.Logger(ctx) e := echo.New() e.Listener = a.api e.Use(middleware.RequestID()) e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{ LogStatus: true, LogURI: true, LogValuesFunc: func(c echo.Context, v middleware.RequestLoggerValues) error { logger.Info("Request", "id", v.RequestID, "uri", v.URI, "status", v.Status, "size", v.ResponseSize) return nil }, })) return e.Start("") } type WebServer interface { Serve(context.Context) error } type webServer struct { weaver.Implements[WebServer] web weaver.Listener } func (w webServer) Serve(ctx context.Context) error { logger := w.Logger(ctx) e := echo.New() e.Listener = w.web e.Use(middleware.RequestID()) e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{ LogStatus: true, LogURI: true, LogValuesFunc: func(c echo.Context, v middleware.RequestLoggerValues) error { logger.Info("Request", "id", v.RequestID, "uri", v.URI, "status", v.Status, "size", v.ResponseSize) return nil }, })) return e.Start("") } func main() { if err := weaver.Run(context.Background(), serve); err != nil { log.Fatal(err) } } func serve(ctx context.Context, server *Server) error { wg := sync.WaitGroup{} wg.Add(2) go func() { defer wg.Done() server.apiServer.Get().Serve(context.Background()) }() go func() { defer wg.Done() server.webServer.Get().Serve(context.Background()) }() wg.Wait() return nil } </code>
基本上,我只是設定兩個 Echo 伺服器,每個元件一個。
對於它的價值,這是我的配置:
<code>[serviceweaver] binary = "./platform" [multi] listeners.api = { address = "localhost:12345" } listeners.web = { address = "localhost:54321" } [single] listeners.api = { address = "localhost:12345" } listeners.web = { address = "localhost:54321" } </code>
當我在單一進程中運行它時,一切似乎都按預期進行。我看到網路請求的日誌條目,表明一切正常。當我在部署模式下運行它時(即,實際上執行多進程魔法),我只能發出1-2 個請求,然後才能看到如下所示的日誌條目,然後回應不會經常起作用:
2023/09/14 21:35:51 http: proxy error: context canceled
看起來我做錯了什麼,但似乎這是一個會以某種方式支援的用例,所以我想知道是否有適當的方法來解決這個問題。
謝謝!
tl;dr Service Weaver 目前沒有從非主要元件執行 HTTP 伺服器的好方法。我建議您將兩個偵聽器移至 Server
結構,並在 Serve
函數內執行兩個 HTTP 伺服器。 HTTP 伺服器可以呼叫其他元件上的方法。
type Server struct { weaver.Implements[weaver.Main] api weaver.Listener web weaver.Listener }
weaver multi
部署程式將每個元件複製兩次,每個副本都在自己的作業系統進程中執行。考慮當 APIServer
元件請求連接埠 12345 上的網路偵聽器時會發生什麼。 APIServer
元件的兩個副本不能同時偵聽連接埠 12345;只有一個作業系統程序可以偵聽該連接埠。為了解決這個問題,兩個副本分別偵聽隨機選擇的端口,例如 8000 和 9000。然後 weaver multi
部署程式在連接埠 12345 上執行 HTTP 代理,將請求轉送至連接埠 8000 和 9000。
在您的應用程式中,主 Server
元件被複製兩次,並且 Serve
函數運行兩次,每個副本運行一次。在Serve
內部,當您呼叫apiServer.Get().Serve(context.Background())
時,會隨機選擇APIServer
的副本來執行Serve
方法。如果幸運的話,這兩個方法呼叫被傳送到兩個不同的副本,那麼一切都應該順利運作。但是,如果兩個方法呼叫都傳送到同一個副本,則 APIServer
的一個副本正在執行 HTTP 伺服器,而另一個則沒有。
在這種情況下,代理程式會將所有請求的一半轉送到正在執行的 HTTP 伺服器,並將另一半請求轉送到未偵聽的偵聽器。這會導致您看到代理錯誤。
最後請注意,當您使用 go run
或 weaver single deploy
運行應用程式時,一切正常,因為沒有代理,且元件不會被複製。
以上是關於如何使用 Service Weaver 設定多個不同偵聽器的問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!