Heim  >  Artikel  >  Backend-Entwicklung  >  Frage zum Einrichten mehrerer verschiedener Listener mit Service Weaver

Frage zum Einrichten mehrerer verschiedener Listener mit Service Weaver

王林
王林nach vorne
2024-02-14 13:57:07429Durchsuche

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

Der PHP-Editor Xiaoxin ist hier, um Ihnen vorzustellen, wie Sie mit Service Weaver mehrere verschiedene Listener einrichten. Service Weaver ist ein leistungsstarkes Tool, mit dem Entwickler mehrere Dienste erstellen und verwalten können. Durch die Einrichtung verschiedener Listener können wir verschiedene Dienste überwachen und verwalten. In diesem Artikel besprechen wir ausführlich, wie Sie mit Service Weaver mehrere verschiedene Listener konfigurieren und verwalten, um unsere Dienste besser steuern und optimieren zu können. Egal, ob Sie Anfänger oder erfahrener Entwickler sind, dieser Artikel bietet Ihnen detaillierte Anleitungen und praktische Tipps. Lasst uns gemeinsam erkunden!

Frageninhalt

Ich verwende Service Weaver, das seit einiger Zeit veröffentlicht wird, und war neugierig, wie wir damit mehrere Listener einrichten sollten. Meine Absicht ist, dass bei der Bereitstellung der Anwendung der Handler für web 的处理程序和 api alleine läuft (als Beispiel). Mein Code sieht derzeit so aus:

<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>

Im Grunde habe ich einfach zwei Echo-Server eingerichtet, einen für jede Komponente.

Für das, was es wert ist, hier ist meine Konfiguration:

<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>

Wenn ich es in einem einzigen Prozess ausführe, scheint alles wie erwartet zu funktionieren. Ich sehe Protokolleinträge für Netzwerkanfragen, die darauf hinweisen, dass alles in Ordnung ist. Wenn ich es im Bereitstellungsmodus ausführe (also tatsächlich die Multiprozess-Magie ausführe), kann ich nur 1-2 Anfragen stellen, bevor ich einen Protokolleintrag wie diesen sehe, und dann funktioniert die Antwort nicht sehr oft:

2023/09/14 21:35:51 http: proxy error: context canceled

Sieht so aus, als ob ich etwas falsch mache, aber es scheint, dass dies ein Anwendungsfall ist, der in irgendeiner Weise unterstützt würde, also frage ich mich, ob es einen geeigneten Weg gibt, dieses Problem zu lösen.

Danke!

Workaround

tl;dr Service Weaver Es gibt derzeit keine gute Möglichkeit, einen HTTP-Server von einer Nicht-Hauptkomponente aus auszuführen. Ich empfehle, dass Sie die beiden Listener innerhalb der Server 结构,并在 Serve-Funktion verschieben, um die beiden HTTP-Server auszuführen. HTTP-Server können Methoden anderer Komponenten aufrufen.

type Server struct {
    weaver.Implements[weaver.Main]
    api weaver.Listener
    web weaver.Listener
}

Details

weaver multi 部署程序将每个组件复制两次,每个副本都在自己的操作系统进程中运行。考虑当 APIServer 组件请求端口 12345 上的网络侦听器时会发生什么。 APIServer 组件的两个副本不能同时侦听端口 12345;只有一个操作系统进程可以侦听该端口。为了解决这个问题,两个副本分别侦听随机选择的端口,例如 8000 和 9000。然后 weaver multi Der Deployer führt einen HTTP-Proxy auf Port 12345 aus und leitet Anfragen an die Ports 8000 und 9000 weiter.

In Ihrer Anwendung führt eine Kopie des Masters Server 组件被复制两次,并且 Serve 函数运行两次,每个副本运行一次。在 Serve 内部,当您调用 apiServer.Get().Serve(context.Background()) 时,会随机选择 APIServer 的副本来执行 Serve 方法。如果幸运的话,这两个方法调用被发送到两个不同的副本,那么一切都应该顺利运行。但是,如果两个方法调用都发送到同一个副本,则 APIServer einen HTTP-Server aus und die andere nicht.

In diesem Fall leitet der Proxy die Hälfte aller Anfragen an den laufenden HTTP-Server und die andere Hälfte an den nicht abgehörten Listener weiter. Dadurch werden Proxy-Fehler angezeigt.

Bitte beachten Sie abschließend, dass beim Ausführen der Anwendung mit go runweaver single deploy alles einwandfrei funktioniert, da kein Proxy vorhanden ist und die Komponenten nicht kopiert werden.

Das obige ist der detaillierte Inhalt vonFrage zum Einrichten mehrerer verschiedener Listener mit Service Weaver. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen