Maison  >  Article  >  développement back-end  >  Question sur la façon de configurer plusieurs écouteurs différents à l'aide de Service Weaver

Question sur la façon de configurer plusieurs écouteurs différents à l'aide de Service Weaver

王林
王林avant
2024-02-14 13:57:07469parcourir

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

L'éditeur PHP Xiaoxin est là pour vous présenter comment utiliser Service Weaver pour configurer plusieurs auditeurs différents. Service Weaver est un outil puissant qui permet aux développeurs de créer et de gérer plusieurs services. En définissant différents auditeurs, nous pouvons surveiller et gérer différents services. Dans cet article, nous expliquerons en détail comment utiliser Service Weaver pour configurer et gérer plusieurs écouteurs différents afin de mieux contrôler et optimiser nos services. Que vous soyez débutant ou développeur expérimenté, cet article vous fournira des conseils détaillés et des conseils pratiques. Explorons ensemble !

Contenu de la question

J'utilise Service Weaver, qui est sorti depuis un certain temps, et j'étais curieux de savoir comment nous devrions l'utiliser pour configurer plusieurs auditeurs. Mon intention est que lorsque nous déployons l'application, le gestionnaire de web 的处理程序和 api s'exécute seul (à titre d'exemple). Mon code ressemble actuellement à ceci :

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

En gros, je viens de mettre en place deux serveurs Echo, un pour chaque composant.

Pour ce que ça vaut, voici ma configuration :

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

Lorsque je l'exécute en un seul processus, tout semble fonctionner comme prévu. Je vois des entrées de journal pour les requêtes réseau indiquant que tout va bien. Lorsque je l'exécute en mode déploiement (c'est-à-dire en faisant la magie multi-processus), je ne peux faire que 1 à 2 requêtes avant de voir une entrée de journal comme celle-ci, et la réponse ne fonctionne pas très souvent :

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

On dirait que je fais quelque chose de mal, mais il semble que ce soit un cas d'utilisation qui serait pris en charge d'une manière ou d'une autre, donc je me demande s'il existe un moyen approprié de résoudre ce problème.

Merci !

Solution

tl;dr Service Weaver Il n'existe actuellement aucun bon moyen d'exécuter un serveur HTTP à partir d'un composant non principal. Je vous recommande de déplacer les deux auditeurs à l'intérieur de la fonction Server 结构,并在 Serve pour exécuter les deux serveurs HTTP. Les serveurs HTTP peuvent appeler des méthodes sur d'autres composants.

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

Détails

weaver multi 部署程序将每个组件复制两次,每个副本都在自己的操作系统进程中运行。考虑当 APIServer 组件请求端口 12345 上的网络侦听器时会发生什么。 APIServer 组件的两个副本不能同时侦听端口 12345;只有一个操作系统进程可以侦听该端口。为了解决这个问题,两个副本分别侦听随机选择的端口,例如 8000 和 9000。然后 weaver multi Le déployeur exécute un proxy HTTP sur le port 12345, transmettant les requêtes vers les ports 8000 et 9000.

Dans votre application, une copie du maître Server 组件被复制两次,并且 Serve 函数运行两次,每个副本运行一次。在 Serve 内部,当您调用 apiServer.Get().Serve(context.Background()) 时,会随机选择 APIServer 的副本来执行 Serve 方法。如果幸运的话,这两个方法调用被发送到两个不同的副本,那么一切都应该顺利运行。但是,如果两个方法调用都发送到同一个副本,则 APIServer exécute un serveur HTTP et l'autre ne l'est pas.

Dans ce cas, le proxy transmet la moitié de toutes les requêtes au serveur HTTP en cours d'exécution et l'autre moitié à l'écouteur non écouté. Cela vous fera voir des erreurs de proxy.

Enfin, veuillez noter que lorsque vous exécutez l'application en utilisant go runweaver single deploy, tout fonctionne correctement car il n'y a pas de proxy et les composants ne sont pas copiés.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer