2016-04-16 11 views
6

Rozwijamy bot za pomocą BotKit, a teraz próbujemy rozwiązać problem z minimalnym przestojem wdrożenia.Wdrożenie luki bota Slack

Na tym serwerze działa serwer i kontener dokowania. Wewnątrz kontenera uruchom instancję bot-app połączoną z serwerem RTM (Slack). Kiedy zaczynam wdrażać nową wersję (v2) bot-app, chcę uzyskać zero przestojów, użytkownicy nie powinni widzieć "bot jest w trybie offline".

timeline

Deploy skrypt uruchamia drugi pojemnik Döcker z nową wersją bot aplikacji. A bot-app łączy się również z serwerem RTM. W ten sposób jest kilka sekund, kiedy obie aplikacje działają, są podłączone do serwera RTM i odpowiadają na polecenia użytkownika (a użytkownik zobaczy dwie odpowiedzi na swoje polecenie).

Jaką optymalną decyzję mogę uzyskać, jeśli z jednej strony chcemy uzyskać zero przestojów, az drugiej strony chcemy zapobiec interakcji użytkownika z dwoma przypadkami w tym samym czasie?

Decyzja 1: Aby umożliwić małe prawdopodobieństwo prawdopodobieństwa kolizji, gdy obie instancje odpowiedzą na polecenie użytkownika.

Decyzja 2: Porzucić wdrożenie zerowego czasu przestoju. W takim przypadku wdróż skrypt najpierw zatrzyma pierwszy kontener dokera, a następnie uruchom inny. Aplikacja nie będzie reagować na polecenia użytkownika wysyłane między zatrzymaniem bieżącej wersji aplikacji a uruchomieniem nowej wersji aplikacji.

Decyzja 3: Z interakcją prądu biegu równoległego i nowej wersji aplikacji lub muteksów. Ogólny schemat: 1) Aktualna wersja aplikacji działa 2) Wdróż skrypt uruchamia nową wersję aplikacji 3) Czas, kiedy nowa wersja aplikacji prawie działa i jest gotowy do połączenia z serwerem RTM, wysyła do bieżącej wersji aplikacji polecenie, aby zamknąć połączenie RTM. 4) Aktualna wersja aplikacji zamyka połączenie RTM 5) Nowa wersja aplikacji otwarte połączenie RTM

Myślę, że istnieją inne dobre rozwiązania.

Jak rozwiązałbyś ten problem w swojej aplikacji?

Odpowiedz

1

(Przepraszam za drugą odpowiedź, miałem inny pomysł.)

Podejście, które opisałem wcześniej, byłoby dość destrukcyjne dla istniejącego kodu, ponieważ prawdopodobnie musiałbyś przestać używać botkita (lub przynajmniej nie używać go do komunikacji z interfejsem RTM API). Podejście, które może być mniej uciążliwe, byłoby użycie jakiegoś zewnętrznego sposobu sygnalizowania, że ​​dana wiadomość została już przetworzona.

Na przykład, używając Redis, mają bot wykonać następujące polecenie, gdy wiadomość jest w:

SET message:<message timestamp> 1 NX PX 30000 

Opcja NX Oznacza to polecenie uda tylko wtedy, gdy klucz nie istnieje. Tak więc pierwsze wystąpienie bota, któremu uda się to wykonać, powiedzie się, a druga instancja zakończy się niepowodzeniem. Bot powinien tylko przetworzyć wiadomość i odpowiedzieć, jeśli to polecenie się powiedzie.

(The PX 30000 ustawia ważności 30 sekund tak Redis nie uzyskać pełny z tych klawiszy.)

ten powinien pozwolić zrobić swoje ulepszenia zero przestojów poprzez nałożenie na siebie działających kopii bot bez konieczności martwienia się o wiadomość przetwarzana dwa razy.

Należy zauważyć, że w tym schemacie nadal jest możliwe, że wiadomość zostanie całkowicie usunięta, jeśli bot zostanie zamknięty w sposób niewystarczający. (Może zginąć zaraz po wywołaniu komendy SET, ale zanim faktycznie zostanie przekazana wiadomość.) Prawdziwa kolejka z dwufazowym "get/delete" byłaby lepsza, ale wracasz do mojej drugiej odpowiedzi. :-)

+0

Dzięki smarx! Jest bardzo dobre rozwiązanie! W przeciwieństwie do pierwszego wariantu wydaje się mniej skomplikowany i bardziej niezawodny. – vovan

0

Jeden pomysł uważam jest rozdzielenie na dwie części:

  1. komponentem, który utrzymuje websocket podłączonego do Slack RTM API. Ten komponent po prostu odczytuje komunikaty z interfejsu API i umieszcza je w kolejce. (Nazwijmy to "queuer").
  2. Rzeczywisty "bot", który odczytuje wiadomości z kolejki i odpowiada w razie potrzeby.

Zależnie od tego, jak zachowuje się twój bot, może korzystać z Web API bezpośrednio lub może umieścić własne wiadomości w kolejce wyjściowej, którą "queuer" może wysłać przez interfejs API RTM.

Ta architektura prawdopodobnie rozwiązuje Twój problem ... możesz teraz albo krótko przerwać działanie na czas aktualizacji - odpowiedzi będą opóźnione do momentu uruchomienia nowej wersji - albo możesz uruchomić dwie wersje bota w tym samym czasie i polegać na semantyce kolejki, aby obie wersje nie reagowały na tę samą wiadomość.

+0

Zapobiega to byciu przez użytkownika stanem. Bez bezpośredniego połączenia z Websocket będziesz musiał kpić z obiektów konwersacji. –

+0

To prawda. (Lub przynajmniej stan musi być zewnętrzny dla procesu bota.) – smarx