Технічна підтримка микросервисов 24/7: як ми будували процес

Всім привіт. Мене звати Андрій Трубіцин, я співпрацюю з ЕРАМ як Java System Architect. У цій статті розповім, як ми побудували процес технічної підтримки микросервисов в режимі нон-стоп для великого американського клієнта.

Це був перший досвід впровадження такого підходу за моїх 4 роки роботи в харківському офісі ЕРАМ, і він виявився непростим для команди: треба було розібратися в новій для нас системі — Opsgenie та її інтеграції, знайти бажаючих для нічних чергувань, спланувати роботу і поставити процес на рейки. На нашому проекті чинності микросервисной архітектури дуже часті релізи та динамічний ритм. Ми завжди в тонусі, багатьом хлопцям такий інтенсив по душі. Однак важливо, щоб баланс роботи та особистого життя зберігався без шкоди для якості безперервних поставок оновлень (у тому числі і в середу промислової експлуатації).

Якщо ви працюєте над вирішенням на микросервисах або маєте справу з частими релізами для досить вимогливого клієнта, то, можливо, вас зацікавить наш досвід використання Opsgenie як системи управління аваріями.

Бізнес-проблема

Зараз практично будь-яка компанія знаходиться в умовах гострої конкурентної боротьби. Важливо разом з клієнтами встигати за змінами на ринку з допомогою своєчасної цифровий трансформації бізнесу. Платформи повинні бути швидкими і адаптивними — це одна з умов виживання і запорука зростання доходів клієнта. Микросервисы, зокрема, дають можливість зменшити time to market. Зворотна сторона медалі: часті релізи, відкладене end-to-end-тестування та інші фактори можуть призводити до збоїв, на які бізнес хоче швидко реагувати.

Це і стало причиною того, що одного разу прекрасним ввечері на черговому созвоне один з наших американських клієнтів повідомив, що хоче організувати технічну підтримку свого продукту 24 години в добу 7 днів в тиждень.

Як я згадував раніше, що продукт побудований на микросервисной архітектурі і для нього використовується підхід безперервного постачання оновлень. Це означає, що зміна, внесена інженерами, після проходження по CI/CD-процесу з різними тестами і рівнями контролю якості потрапляє в промислову середу приблизно через 25-30 хвилин.

Над продуктом працюють понад 200 осіб, понад 70 з них — в Харкові. До складу кожної проектної команди входять розробники, системні інженери, автоматизаторы. Разом вони відповідають за написання коду і тестів, за процес оновлення микросервиса в продукті (CI/CD pipeline) і «викачування» в промислову середовище експлуатації. Вимоги до якості високі: на проекті використовується статичний аналіз вихідного коду, повузлова перевірка тестами, тестування компонентів на моделях, інтеграційне і функціональне тестування, перевірка на наявність вразливостей і продуктивності і т. д.

Але все ж іноді у промисловому середовищі відбуваються збої. Інженери не завжди можуть усунути їх оперативно: клієнт надає свої сервіси в Північній Америці, різниця в часі становить 7-10 годин. Крім того, у всіх інженерів є свій список спланованих завдань, і якщо вони будуть відволікатися на усунення збоїв, то може бути порушений графік розробки нових можливостей продукту.

Однак клієнт хотів, щоб у момент виникнення неполадок хтось почав працювати над ними протягом 30 хвилин в будь-який час доби. Значить, повинен бути хтось, хто міг би отримати повідомлення про збої і включитися в роботу протягом півгодини. Це передбачає, що безперервно на відстані витягнутої руки «чергового» інженера повинні перебувати телефон і ноутбук з надійним інтернет-з'єднанням.

Також клієнт хотів мати можливість ескалірувати проблему, якщо з якихось причин у заздалегідь обумовлений час інженер не відповів, що взявся за роботу; лід команди повинен отримувати дзвінок з описом складнощів, наступним — прийняти повідомлення архітектор, після нього — сам замовник. Якщо ця ієрархія стане «пробиватися» та проблема доходити до клієнта, нам будуть загрожувати фінансові санкції.

Початок шляху

На старті наша робота складалася з таких етапів:

1. Зрозуміти, на які події повинна реагувати система управління аваріями, а які може ігнорувати. Треба було проаналізувати весь продукт, зібрати перелік всіх потенційних негативних моментів і направити його клієнту.

2. Обговорити кожну подію з переліку із замовником, щоб виявити критично важливі для нього моменти.

3. Сформувати фінальний список завдань, які програмісти будуть контролювати 24/7. Насправді, не всі збої вимагають негайного реагування і виправдовують додаткові витрати клієнта на цілодобову технічну підтримку.

Критерії, за якими ми сформували список критичних для нас подій, що стосуються основного бізнес-флоу замовника. Якщо один з микросервисов, який обслуговує цю частину системи, дає сигнал про відмову (видає помилку, відпрацьовує повільніше певних SLA або виявляється недоступний), це проблема, яка вимагає негайного втручання програмістів.

4. Зробити PoC. Ми вивчили документацію обраної системи управління аваріями, отримали доступ до їх «пісочниці», побудували свій Proof of Concept на базі тестового сервісу, який моделював б різні виняткові ситуації, і відпрацювали схему взаємодії з Opsgenie.

Після презентації результатів клієнту та документування процесу команди взяли систему в роботу, щоб у плановій імплементації додати функціонал техпідтримки 24/7 бізнес-флоу замовника. Технічну сторону питання виконали архітектор і технічний лідер однієї з команд.

5. Налагодити і впровадити новий процес у роботу команди. Цим займався в основному наш проектний менеджер, і він зіткнувся з непростим завданням. З самого початку стало зрозуміло, що команді на «чергуванні» потрібні саме розробники (зазвичай трапляються збої в ході бізнес-процесу сервісів, а не з конфігурацією стендів наприклад). Однак це не можуть бути ті ж люди, які працюють над розширенням функціоналу, технічним боргом та іншими завданнями. Їх режим передбачає днем регулярні зустрічі, написання коду, час на обід.

Увечері такі розробники можуть піти на зустріч з друзями/кататися на велосипеді/дивитися кіно — загалом, розпоряджатися часом за власним розсудом. Так і вночі вони повинні відпочивати. Також ми зрозуміли, що інженерам постарше і сімейним людям такий режим в принципі не підходить.

У той же час ми усвідомлювали, що «черговими» не можуть бути сторонні спеціалісти, так як необхідно розуміти, як працює той або інший сервіс в продукті. Виходить, що на зв'язку все-таки повинні бути окремі розробники з команди. Ми дізналися, кому з хлопців цікаво взятися за це завдання і раз на півтора-два місяці «чергувати» протягом тижня з гарним інтернет-з'єднанням і ноутбуком завжди під рукою (за чергування 24/7, до речі, покладаються певні грошові бонуси).

Приблизно половина людей, що погодилися брати участь у процесі, і з початку 2019 року ми працюємо в такому режимі. Зазначу, що під час зміни у інженерів виходить жити звичайним життям, без особливо жорстких обмежень. Головне — у разі аварії бути доступним практично миттєво.

Як працює система управління аваріями

Як я вже згадував, для автоматизації процесу управління аваріями клієнт вибрав сервіс Opsgenie . Всі приклади, які я буду приводити, ставляться до нього.

Opsgenie дозволяє створити команду, для якої ви можете скласти розклад чергувань. Якщо з якихось причин потрібно точково змінити розклад, то немає необхідності переробляти його повністю, можна просто оновити деякі дати і сервіс сам адаптує розклад і правки і видасть фінальний варіант. Приклад — на картинці нижче.

Далі, ми налаштовуємо правила ескалації: скільки часу виділяється на підтвердження того, що команда знає про проблему і працює над її усуненням; що робити, якщо працівник на зміну не підтвердив початок роботи над проблемою. У наведеному нижче прикладі після 30 хвилин очікування система подзвонить адміністратору групи, а якщо проблема не буде вирішена за дві години, то по тривозі піднімається вже вся команда.

Після того як в Opsgenie внесені команда, розклад і правила ескалації, треба налаштовувати його інтеграцію з вашими сервісами в промисловому середовищі експлуатації. У обраного нами сервісу управління аваріями є можливість інтегруватися з кількома сотнями систем і сервісів. Для вивантаження микросервисов на стенди ми використовуємо публічна хмара AWS.

Як ми інтегрували микросервисы і Opsgenie

Для прикладу пропоную розглянути конфігурацію реакції системи управління аваріями на зупинку одного з сервісів (наприклад, в Java-додатку закінчилася пам'ять в контейнері), запущеному в ECS-кластері AWS. Така конфігурація працює на нашому проекті, але деякі деталі змінені в силу політики конфіденційності компанії.

Перший крок — створення інтеграційної посилання в системі управління аваріями в розділі інтеграції. Вона включає в себе унікальний ключ, за яким сервіс визначить наш микросервис. Ніяких параметрів вводити не потрібно, система все зробить сама.

Для інтеграції з Opsgenie з боку микросервиса створюємо SNS Topic і прописуємо посилання, яку ми згенерували на попередньому кроці.

Resources:
MicroserviceECSAlarmTopic:
 Type: AWS:: SNS::Topic
 Condition: InLive
Властивості:
 TopicName: "MicroserviceECSAlarmsTopic"
Subscription:
 - Endpoint: https://api.opsgenie.com/v1/json/amazonsns?apiKey=eeeeeeee-cccc-ffff-bbbb-aaaaaaaaaaaa
 Protocol: https

Далі, створюємо правило, за яким ми будемо слухати певний тип повідомлень від ECS-кластера і відправляти на створений нами SNS Topic повідомлення про те, що Docker-контейнер з нашим микросервисом зупинився.

ECSStoppedRule:
 Type: "AWS::Events::Rule"
 Condition: InLive
Властивості:
 Name: 'MicroserviceECSStoppedRule'
 Description: "Notify when the microservice goes down"
EventPattern:
 source: ["aws.ecs"]
 detail-type: ["ECS Task State Change", "ECS Container Instance State Change"]
detail:
 clusterArn: #############
 lastStatus: [ "STOPPED" ]
 stoppedReason: [ "Essential container in task exited", "Task stopped by user" ]
 group: #############
 State: "ENABLED"
Targets:
 - Arn: !Ref MicroserviceECSAlarmTopic
 Id: "MicroserviceECSAlarmTopic "
InputTransformer:
InputPathsMap:
 detail: "$.detail"
 InputTemplate: '"The microservice has stopped working with the following details: <detail>"

Тут в секції EventPattern ми описуємо повідомлення, які хочемо слухати. Для цього в параметрі source: [«aws.ecs»] вказуємо, що слухаємо повідомлення від ECS-кластера в хмарі AWS; в параметрі detail-type ми ставимо конкретні типи повідомлень: запуск/зупинка завдання нашого микросервиса або зміна стану Docker-контейнера з нашим микросервисом. Із зазначених повідомлень ми вибираємо лише ті, що призвели до зупинки Docker-контейнера з нашим микросервисом; це робиться через параметр detail, в якому ми прописали останній статус і причини зупинки.

Далі, в секції Targets вказуємо, що ми хочемо зробити у разі отримання вищеописаних повідомлень. У наведеному прикладі ми готуємо нове повідомлення на основі отриманої інформації з отриманого. Вона витягується в параметрі InputPathsMaps, де ми оголошуємо нову змінну detail і заносимо в неї значення параметра detail отриманого повідомлення. У параметрі InputTemplate ми формуємо тіло нового повідомлення і використовуємо змінні InputPathsMaps.

Тепер нам потрібно вивантажити описаний CloudFormation-шаблон на стенд в хмарі Amazon і сподіватися, що вночі нас турбувати не будуть :) У нашої команди, до речі, в перший місяць роботи за такою системою було 26 критичних ситуацій, у другій — 5, а далі максимум одна в місяць. Тобто активними чергування бувають нечасто. Все завдяки тому, що код інженери стали писати якісніше.

До речі, про нічний неспокій. На старті роботи у нас була кумедна історія. Коли ми з проектним менеджером і технічним лідером займалися PoC, то створили тестове розклад і розподілили між собою тренувальні чергування. Обговорили, що можемо отримувати SMS і дзвінки вночі у разі збоїв, були готові. PoC пройшло успішно, ми впровадили систему, почали працювати і благополучно про це забули.

І ось одного разу проектному менеджеру вночі надійшов дзвінок. Він подумав, що ескалація на той сервіс, який ми нещодавно відправили у production (в нашому звичайному флоу менеджер отримує повідомлення, якщо команда довго не може вирішити проблему), і став дзвонити черговому інженеру, з'ясовувати, чому той не займається питанням. В онлайн-режимі серед ночі вони зайшли в Opsgenie і переконалися, що ніякої проблеми немає. Але у нас хороший, відповідальний менеджер: він вирішив докопатися до істини, упевнитися, що все в порядку. Так що серед ночі розбудили і архітектора, який спросоння теж не зрозумів, що сталося, і подзвонив у свою чергу тимлиду.

В результаті до світанку сонні менеджер, черговий інженер, архітектор і технічний лідер нарешті вирішили ще раз прочитати SMS і побачили, що тривогу підняв тестовий сервіс із старого PoC, який система видалила з середовища розробки за непотрібністю. Після цього всі заспокоїлися, видалили тестове розклад і спокійно пішли досипати решту годинник. Висновок: будьте уважні, щоб не прокидатися помилкової тривоги :)

Вивчені уроки

Подумайте заздалегідь, хто у вашій команді погодиться на чергування. Молодь більш охоче береться за періодичну роботу у форматі 24/7, людей сімейних і тих, хто постарше, бонуси не завжди мотивують.

Сформуйте повний список виняткових ситуацій і обговоріть його з клієнтом. Це непростий процес, який вимагає ітеративної роботи. При цьому саме замовник допоможе зрозуміти, які з потенційних проблем критичні для бізнесу та потребують негайного вирішення, а які, незважаючи на технічну важливість, можуть почекати (наприклад, відмова обслуговування одного з примірників микросервиса через закінченню пам'яті — технічно істотний дефект, але він не є критичним для бізнесу, так як хмарна микросервисная платформа просто запустить новий примірник іншого сервісу або використовує механізми повторних запитів).

Приділяйте час тестування . На нашому проекті крос-функціональні команди. Тобто розробники пишуть unit-, компонентні, інтеграційні і end-to-end-тести. Вони не завжди люблять це робити, але після впровадження техпідтримки 24/7 усвідомили всю важливість процесу і стали ставитися до нього більш відповідально. Зрештою, від якісного тестування багато в чому залежить їх спокій на чергуванні.

Поясніть команді, чому не варто грати в пінг-понг (фігурально висловлюючись). Якщо під час чергування виникла проблема в чужому коді або на чужому «ділянку роботи», це не привід переводити стрілки. В екстрених випадках треба не перекидати відповідальність, а засукавши рукави виправляти ситуацію. Індивідуалізму в такому процесі не місце, і менеджерам варто звернути на це увагу команди. Залучати колег бажано тільки в разі ескалації або особливої складності завдання.

Висновки

За час роботи з Opsgenie і техпідтримкою микросервисов 24/7 ми переконалися, що цей підхід дозволяє значно поліпшити якість коду в системі (до речі, однією з перших застосувала Amazon). Зазначу, що технічна сторона питання не вимагає багато часу: щоб прописати одну виняткову ситуацію на одному микросервисе, вистачить одного-двох днів. У нашому випадку найбільш складними у запуску техпідтримки 24/7 були все ж нетехнічні моменти.

Особливих зусиль потребувало формування розкладу та обговорення фінансових питань з клієнтом так, щоб і процес працював, і хлопці, які погодилися страхувати продукт позмінно, були задоволені. На це у нас пішло близько півроку — від підписання контракту та бюджетування до написання коду та виходу хлопців на новий режим. Зате зараз клієнт задоволений результатами і швидкістю реакції, а команда адаптувалася до такого графіком. Початковий контракт був підписаний на рік, але ми вже знаємо, що продовжимо його.

Якщо ви робите продукт з микросервисной архітектурою або на проекті багато релізів і клієнт хоче мати можливість виправлення неполадок у режимі 24/7, подумайте про використання Opsgenie або іншої системи управління аваріями для якісної налагодження процесу. Але головне — слухайте команду і приділяйте увагу людському фактору.

Опубліковано: 24/09/19 @ 10:00
Розділ Сервіси

Рекомендуємо:

Країна, де доречний торг на співбесіді. Як живеться програмісту в Ізраїлі
Ruby дайджест #32: Rails 6.0 і Sidekiq 6.0, подкасти з DHH
PM дайджест #20: база знань для лідерів, гайди Мартіна Фаулера
Як GlobalLogic створювала EcoHike — додаток для туристів, які хочуть очистити Карпати від сміття
Подорож на планету Java. Мій досвід проходження сертифікації Java Developer 11