symfony - Symfony Messenger 不同的消费者用于不同的应用服务器
问题描述
我有一个 Symfony 应用程序,它在负载均衡器后面的几台服务器上运行。所以我有单独的主机 www1、www2、www3 等。
目前我messenger:consume
只在 www1 上运行,担心竞争条件和潜在的消息被处理两次。
现在我有一个场景,我需要在每个主机上执行一个命令。
我正在考虑为每个主机使用单独的传输并messenger:consume
在每个主机上运行,只使用来自其各自队列的消息。但是我希望配置是动态的,即我不想在添加或删除新主机时使用不同的传输配置进行另一个代码发布。
你能提出一个实现这一目标的策略吗?
解决方案
如果你想使用不同的队列和不同的消费者......只需为每个 www 配置不同的 DSN,存储在环境变量(而不是代码)中。然后,您可以为每个服务器设置不同的队列或传输。
传输配置可以在DSN 中包含所需的队列名称,最佳实践是将该配置存储在环境变量中,而不是作为代码,因此当添加新主机时,您不需要“具有不同传输配置的另一个代码版本或删除”。只需在部署每个实例时添加适当的环境变量,就像您对其余配置所做的那样。
framework:
messenger:
transports:
my_transport:
dsn: "%env(MESSENGER_TRANSPORT_DSN)%"
在每个“www”主机上,您将拥有不同的 值MESSENGER_TRANSPORT_DSN
,其中包括不同的队列名称(或完全不同的传输)。
您需要为每个实例创建一个单独的使用者,并使用匹配的配置(或在同一实例上运行使用者)。
但是,如果所有主机实际上都在运行同一个应用程序,通常你会使用一个消费者,并且所有实例都应该发布到同一个队列。
消费者甚至不需要在与任何 Web 实例相同的服务器上运行,只需将其配置为从适当的传输/队列消费。