2016-04-16 59 views
6

我們用BotKit開發機器人,現在我們嘗試用最少的部署停機時間來解決問題。Slack機器零停機部署

在此服務器上運行服務器和碼頭工具容器。在容器中運行與RTM-server(Slack)連接的bot-app實例。 當我開始部署bot-app的新版本(v2)時,我希望得到零停機時間,用戶不應該看到「bot離線」。

timeline

部署腳本運行與殭屍應用程序的新版本,第二泊塢窗容器。而bot-app也連接到RTM服務器。這樣,當兩個應用程序都運行時,幾秒鐘連接到RTM服務器並響應用戶命令(並且用戶將看到他的命令的兩個答案)。

我可以得到,如果我們想要獲得零停機時間,而另一方面,我們要防止用戶在同一時間兩個實例互動,一方面有什麼最優決策?

決策1: 爲了允許小的機會發生碰撞的可能性,當兩個實例將用戶命令進行響應。

決定2: 摒棄零停機時間部署。在這種情況下,部署腳本首先停止第一個docker-container,然後啓動另一個。該應用不會響應用戶命令,在停止當前版本的應用和完全啓動應用的新版本之間發送。

決策3: 通過並行運行電流和應用或互斥的新版本的相互作用。一般原理: 1)應用程序的當前版本正在運行 2)部署腳本啓動應用程序的新版本 3)我時間,當應用程序的新版本差不多用完,準備連接到RTM服務器,發送到當前版本的應用程序命令關閉RTM連接。 4)當前版本的應用程序關閉RTM連接 5)新版本的應用程序打開RTM連接

我認爲還有其他好的解決方案。

您如何在您的應用程序中解決此問題?

回答

1

(對不起第二個答覆;有另一個想法。)

由於您可能需要停止使用botkit(或者至少不使用它來執行RTM API通信),因此前面描述的方法會對您現有的代碼造成相當的破壞性。一種可能不那麼具有破壞性的方法是使用某種外部方式來表示給定的消息已經被處理。

例如,使用Redis的,有機器人做下面的命令發來的郵件中:

SET message:<message timestamp> 1 NX PX 30000 

NX選項意味着此命令如果該鍵不存在,纔會成功。因此,設法執行此操作的bot的第一個實例將成功,而另一個實例將失敗。機器人只應處理消息並在該命令成功時作出響應。

(該PX 30000設置爲30秒屆滿所以Redis的不充分得到這些密鑰。)

這應該讓你通過重疊運行BOT實例,而不需要擔心做你的零停機升級一個消息正在處理兩次。

請注意,如果殭屍程序以非優雅的方式關閉,則在此方案中仍可能完全丟棄消息。 (它可以在調用SET命令之後但在它實際處理消息之前死亡。)具有兩階段「獲取/刪除」的真實隊列會更好,但是隨後又回到了我的其他答案。 :-)

+0

謝謝smarx!有非常好的解決方案!與第一個變體不同,它看起來不那麼複雜和可靠。 – vovan

0

一個想法,我會考慮被分成兩個部分:

  1. ,保持連接到鬆弛RTM API一個WebSocket的一個組件。該組件簡單地從API讀取消息並將它們放入隊列中。 (我們稱之爲「queuer」)
  2. 實際的「機器人」,它從隊列中讀取消息並根據需要進行響應。

根據您的bot的行爲方式,它可以直接使用Web API,也可以將其自己的消息放在「queuer」可以通過RTM API發送的出站隊列中。

該體系結構可能解決了您的問題......您現在可以在升級時短暫停用機器人 - 響應只會延遲到新版本運行時 - 或者您可以同時運行兩個版本的機器人並依賴隊列的語義來防止兩個版本響應相同的消息。

+0

這可以防止殭屍狀態。沒有直接的WebSocket連接,你將不得不模擬對話對象。 –

+0

這是真的。 (或至少國家需要在bot程序外部。) – smarx