Slack bot的零停机时间部署

vov*_*van 7 deployment parallel-processing mutex devops slack

我们使用BotKit开发bot,现在我们尝试以最小的部署停机时间来解决问题.

此服务器上运行服务器和docker容器.内部容器运行bot-app实例与RTM-server(Slack)连接.当我开始部署bot-app的新版本(v2)时,我希望零停机时间,用户不应该看到"僵尸程序脱机".

时间线

部署脚本使用新版本的bot-app运行第二个docker容器.bot-app也连接到RTM服务器.通过这种方式,当两个应用程序都运行时,几秒钟连接到RTM服务器并响应用户命令(并且用户将看到他的命令的两个答案).

如果一方面我们希望获得零停机时间,另一方面,我们希望阻止用户同时与这两个实例进行交互,那么我可以得到什么样的最佳决策?

决策1:当两个实例都响应用户命令时,允许发生冲突的可能性很小.

决策2:放弃零停机部署.在这种情况下,部署脚本首先停止第一个docker-container,然后启动另一个docker-container.该应用程序不会响应用户命令,在停止当前版本的应用程序和完全启动应用程序的新版本之间发送.

决策3:通过并行运行当前和新版本的应用程序或互斥体进行交互.一般原理图:1)当前版本的应用程序正在运行2)部署脚本启动应用程序的新版本3)我新的应用程序版本几乎运行并准备连接到RTM服务器,它发送到当前版本的app命令关闭RTM-连接.4)当前版本的应用程序关闭RTM连接5)新版本的应用程序打开RTM连接

我认为还有其他好的解决方案.

您如何在应用程序中解决此问题?

use*_*559 1

(抱歉第二次回复;有另一个想法。)

我之前描述的方法会对您现有的代码造成很大的破坏,因为您可能需要停止使用 botkit(或者至少不使用它来进行 RTM API 通信)。一种破坏性较小的方法是使用某种外部方式来表明给定消息已被处理。

例如,使用 Redis,让机器人在收到消息时执行以下命令:

SET message:<message timestamp> 1 NX PX 30000
Run Code Online (Sandbox Code Playgroud)

NX选项意味着仅当密钥尚不存在时此命令才会成功。因此,设法执行此操作的机器人的第一个实例将成功,而另一个实例将失败。如果此命令成功,机器人应仅处理消息并做出响应。

PX 30000设置了 30 秒的过期时间,这样 Redis 就不会填满这些键。)

这应该让您可以通过重叠运行的机器人实例来进行零停机升级,而不必担心消息被处理两次。

请注意,在此方案中,如果机器人以非正常方式关闭,消息仍然有可能被完全丢弃。(它可能会在调用命令后SET但在实际处理消息之前死亡。)具有两阶段“获取/删除”的真正队列会更好,但随后您又回到了我的另一个答案。:-)