首頁  >  文章  >  後端開發  >  關於如何使用 Service Weaver 設定多個不同偵聽器的問題

關於如何使用 Service Weaver 設定多個不同偵聽器的問題

王林
王林轉載
2024-02-14 13:57:07465瀏覽

关于如何使用 Service Weaver 设置多个不同侦听器的问题

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 runweaver single deploy 運行應用程式時,一切正常,因為沒有代理,且元件不會被複製。

以上是關於如何使用 Service Weaver 設定多個不同偵聽器的問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除