Symfony Messenger-检查队列是否为空

Symfony Messenger-检查队列是否为空,symfony,message-queue,Symfony,Message Queue,我们正在迁移我们的体系结构以利用Symfony Messenger组件。我目前正在处理的是调整应用程序的部署过程 建议在部署时重新启动worker以获取新代码。有道理。我的问题是,这并不能解决升级已部署代码时的问题。假设假设版本1和2。 版本1使用并理解一组特定的消息 版本2添加了更多的消息类型,并更改了版本1中定义的某些消息类型的名称/结构/任何内容 在部署过程中,为了确保所有消息都已处理,并且在新版本发布时不存在不兼容,我认为这是一个直观的过程: 停止接受队列中的新消息(将站点置于“维护模

我们正在迁移我们的体系结构以利用Symfony Messenger组件。我目前正在处理的是调整应用程序的部署过程

建议在部署时重新启动worker以获取新代码。有道理。我的问题是,这并不能解决升级已部署代码时的问题。假设假设版本1和2。 版本1使用并理解一组特定的消息

版本2添加了更多的消息类型,并更改了版本1中定义的某些消息类型的名称/结构/任何内容

在部署过程中,为了确保所有消息都已处理,并且在新版本发布时不存在不兼容,我认为这是一个直观的过程:

  • 停止接受队列中的新消息(将站点置于“维护模式”)
  • 让工人完成处理队列中挂起的消息
  • 部署新代码
  • 重新启动工人
  • 开始接受新邮件
我面临的问题是,我找不到任何方法来检查队列是否为空


我的部署方案正确吗?部署通常如何在使用Symfony messenger组件(或任何消息队列)的应用程序中完成?是确保所有消息类型向后兼容的唯一方法吗?

这是一个有趣的挑战

Version 1(新的处理程序用于您在上一版本中发送的相同消息)

为此,您可以使用中间件和戳记将版本头添加到通过传输发送的消息中。然后,在消费端,您的处理程序可以监视版本戳,并检查它是否对此消息负责。这种方法的优点是,您可以在不更改消息本身的情况下更改处理程序逻辑,只需让新代码向之前发送的相同消息类型添加新版本即可

这可以很容易地引入到现有的应用程序中,方法是让您现有的处理程序查找戳记,如果戳记不存在,则假定他们负责,否则就退出。当一个新版本想要引入一个新的处理程序时,它将只与您指定的任何版本一起工作,并忽略没有此头的任何消息

第2版(修改数据结构)

解决这个问题的一种方法是在每个版本之间只对消息和处理程序进行向后兼容的更改。例如,假设您的消息如下所示:

{
    "foo": 123
}
{
   "bar": "123"
}
{
  "foo": 123,
  "bar": "123",
}
你想把它改成这样:

{
    "foo": 123
}
{
   "bar": "123"
}
{
  "foo": 123,
  "bar": "123",
}
在这种情况下,您将首先发布一个中间版本,其中包含新旧字段,过一段时间后,您可以发布删除旧逻辑的版本。消息的中间版本可能如下所示:

{
    "foo": 123
}
{
   "bar": "123"
}
{
  "foo": 123,
  "bar": "123",
}
然后,您将有一个处理程序,首先检查
bar
,如果缺少
bar
,则返回到使用
foo
和旧逻辑。通过这种方式,您可以确保新应用程序处理新消息和旧消息,并且通过添加日志,您可以很容易地看到旧代码何时不再被调用,从而确保在即将发布的版本中安全地删除旧属性和逻辑


这种方法的主要缺点是,您必须提前捕获破坏性的更改,这需要彻底的审查和测试过程。幸运的是,当处理程序遇到问题时,故障传输可以捕获问题,但如果消息无法正确解码,这些消息可能会立即被抛出,所以要小心。

有趣的问题。你有没有想过像这样的技术来避免这些场景的重叠?这将是完美的,因为您的策略是有风险的,例如,队列高度拥挤,需要几次时间才能清空(或类似场景)。谢谢,我已经考虑过类似的事情(尽管我不知道它有名字)。在停机时间将是一个更大因素的大规模部署中,这可能是值得投资的。然而,在这一点上,对于我们来说,在工作时间之外部署时,如果我们可以忍受长达几个小时的停机时间,那么这将是太多的开销。在当前部署规模下,我们的队列不会那么拥挤,因此这也不是一个紧迫的问题。好的。顺便说一句,我已经检查过了,上面写着“要做到这一点,运行messenger:stop workers on deploy。这将向每个worker发出信号,它应该完成当前正在处理的消息并优雅地关闭。”在您提供的链接中,要达到您想要的内容对您来说是微不足道的。我已经有这个问题很多年了(与SimpleBus一起)。它本身并没有谈到这个问题,但是我会看看如何在事件驱动系统中讨论这个问题,例如,事件版本控制:Greg Young还有一本书:就我个人而言,功能标志在某些命令场景中似乎是有意义的。我只是不知道我是否太欣赏我所看到的这些技术。谢谢,这也是滚动更新和无缝回滚的方法。但正如您所注意到的,它伴随着更多关于数据库模式更改设计的工作。不适用于我的团队,但对某些人来说仍然是一个很好的解决方案。