Швидкі релізи величезного масштабу
З часом у софтверній індустрії придумали кілька способів більш швидкого і безпечного випуску якісного коду. Багато хто базується на ідеях на зразок безперервної інтеграції, безперервного постачання ПЗ, гнучкої методології розробки, DevOps і розробки через тестування. Всі ці методології об'єднує одне: вони дозволяють розробникам швидко випускати код безпечними, невеликими, послідовними кроками.
Процеси розробки у Facebook органічно зросли з цих методологій і включили в себе багато етапів швидких ітерацій без жорсткого прямування якоїсь конкретної зі схем. Такий гнучкий, прагматичний підхід дозволив нам успішно випускати веб- і мобільні продукти за швидким графіком.
Протягом багатьох років ми оновлювали фронтенд Facebook тричі на день, використовуючи просту стратегію гілок master і release. Інженери вибірково вибирали з гілки master зміни в коді, які пройшли ряд автоматизованих тестів, для включення в гілку release, звідки відбувалися щоденні оновлення. В цілому, таким способом вибиралося від 500 до 700 змін на день. Раз на тиждень ми відрізали нову гілку release і збирали зміни, які не відібралися протягом тижня.
Така система непогано масштабувалася, починаючи з декількох розробників у 2007 році до декількох тисяч сьогодні. Хороша новина в тому, що в міру збільшення кількості програмістів збільшився обсяг зробленої роботи - швидкість випуску коду масштабувалася разом з розміром команди. Однак для щоденних і щотижневих релізів знадобилися певні зусилля, призначення відповідальних за релізи розробників, на додачу до наявних інструментів і автоматизованих систем. Ми розуміли, що накопичення все великих і великих порцій коду для випуску не може тривати вічно, оскільки кількість розробників продовжувала зростати.
До 2016 року ми дійшли висновку, що модель двох гілок з ручним вибором фрагментів досягла межі. У master-гілку вносилося понад 1000 змін на день, а щотижневий стяг досягав 10 000 змін. Кількість зусиль для координування і випуску такого великого релізу щотижня стала нежиттєздатною.
У квітні 2016 року ми вирішили перевести facebook.com на майже безперервну систему «лід з гілки master». Протягом наступного року ми поступово викочували її, спочатку для половини співробітників, потім від 0,1% до 1% веб-трафіку в продакшні, потім для 10%. Кожне з цих просувань допомагало перевірити можливості наших інструментів і процесів працювати з більш високою частотою пушей і отримувати зворотний зв'язок з реального світу. Основною метою було переконатися, що нова система покращує сприйняття сайту користувачами - ну, принаймні, не псує його. Після майже року планування і розробки протягом трьох днів у квітні 2017 року ми розгорнули 100% наших продакшн-серверів на запуск коду безпосередньо з гілки master.
Безперервне постачання коду у великому масштабі
Хоча істинно безперервна система постачання ПЗ означає, що кожна окрема зміна швидко йде в продакшн, швидкість розробки в Facebook зажадала створення своєї системи, яка пушить тисячі змін кожні кілька годин. Зміни в цій квазі-безперервній системі поставки ПО зазвичай маленькі і поступові, і дуже деякі з них реально видимі для кінцевого користувача. Кожен реліз викочується на 100% серверів продакшну в кілька етапів за кілька годин, так що ми можемо зупинити оріг, якщо помітимо якісь проблеми.
Зміни, які пройшли низку внутрішніх автоматизованих тестів і потрапили в гілку master, викочуються для співробітників Facebook. На цьому етапі передбачені оповіщення про блокування пуша, якщо ми внесли регресію, а кнопка екстреної зупинки швидко зупиняє подальше поширення релізу. Якщо все в порядку, ми викочуємо зміни для 2% продакшн-серверів, де знову збираємо зворотний відгук і відстежуємо попередження, особливо для крайніх випадків, які при тестуванні на власних співробітниках могли пройти непоміченими. Зрештою, ми викочуємо зміни для 100% продакшну, а наш інструмент Flytrap збирає звіти користувачів і інформує про будь-які аномалії.
Багато змін спочатку утримуються в системі Gatekeeper, щоб викочувати релізи веб- і мобільної версії незалежно від нових функцій. Це допомагає знизити ризик, що якесь конкретне оновлення викличе проблеми. Якщо ми знаходимо проблему, то просто відключаємо Gatekeeper замість того, щоб повертатися на попередню версію або вносити виправлення в наступній.
У квазі-безперервного циклу релізів є деякі переваги:
Не потрібні латки. У системі з трьома пушами на день, якщо терміново була потрібна критична зміна, яка не вписувалася в графік, то доводилося застосовувати заплатку. Ці позапланові пуші шкідливі, тому що вимагають певних зусиль з боку розробників і можуть конфліктувати з наступним плановим пушем. З новою системою в абсолютній більшості випадків зміни, яким потрібна заплатка, просто вносяться в гілку master і накочуються з найближчим релізом.
Найкраща підтримка глобальної групи розробки. Ми намагалися пристосувати три щоденні пуші до графіка роботи офісів розробки в різних частинах світу, але навіть в таких умовах один щотижневий реліз все одно вимагав уваги всіх розробників в конкретну дату і час, що не завжди зручно в їх часових поясах. Нова квазі-безперервна система означає, що всі розробники в будь-яких часових поясах можуть писати і поставляти свій код тоді, коли їм зручно.
Стимул для створення нових інструментів, автоматизації та процесів, необхідних для масштабування. Коли ми беремося за такі проекти, то вони як випробування тиском для багатьох наших груп розробників і систем. В результаті ми поліпшили push-інструменти, інструменти огляду змін, інфраструктуру тестування, систему управління потужностями, системи маршрутизації трафіку і внесли поліпшення в багатьох інших областях. Розробники всіх цих систем хотіли, щоб проект швидких релізів завершився успіхом. У підсумку, зроблені поліпшення допоможуть компанії краще підготуватися до майбутнього зростання.
Зручність для користувачів. Якщо для вивчення, як веде себе новий код, потрібні дні і тижні, то розробник може вже перейти до іншої роботи. З безперервним постачанням ПЗ інженерам не потрібно чекати тиждень або більше, щоб отримати зворотний зв'язок щодо внесених змін. Вони швидше отримують інформацію, що не працює, і оперативно викочують невеликі зміни по мірі готовності, а не очікують наступного великого релізу. З точки зору інфраструктури нова система набагато зручніша при реагуванні на рідкісні події, які можуть вплинути на людей. Зрештою, інженери стали ближче до користувачів сайту, покращилася і якість розробки, і надійність продукту.
Застосування безперервного постачання для мобільної платформи
Перехід на квазі-безперервну систему у вебі стало можливим частково тому, що ми контролюємо весь технологічний стек, можемо створити або поліпшити необхідні інструменти. Поставка на мобільні платформи - більш складне завдання, оскільки багато існуючих інструментів для розробки і впровадження на мобільній платформі не підтримують швидкі ітерації для безперервного випуску ПЗ.
Facebook постарався поліпшити ситуацію в цій області і випустив ряд вільних інструментів, які спеціально заточені на швидку мобільну розробку. Серед них Nuclide, Buck, Phabricator, різні бібліотеки для iOS, React Native і Infer. Всі разом ці інструменти для складання та тестування дозволяють випускати якісний код, готовий для швидкого постачання на мобільні платформи.
Наш стек безперервної інтеграції складається з трьох рівнів: білди, статичний аналіз і тестування.
Як тільки код надходить з гілки розробки в наші мобільні master-гілки, його спочатку збирають для всіх продуктів, до яких він може відноситися. На мобільній платформі це відноситься до білдів Facebook, Messenger, Pages Manager, Instagram та інших додатків при кожному кімміті. Ми також збираємо кілька варіантів кожного додатку для гарантії, що покрили всі мікропроцесорні архітектури і симулятори, які підтримує ця програма.
Поки надходять білди, ми запускаємо лінтери і наш інструмент для статичного аналізу коду Infer. Це допомагає виявити винятки з null-покажчиком, витоку ресурсів і пам'яті, невикористовувані змінні і ризиковані системні виклики, а також позначити проблеми невідповідності правилам програмування Facebook.
Третя паралельна система, мобільне автоматизоване тестування, містить тисячі юніт-тестів, інтеграційні тести і нерозривні тести (end-to-end), які проводяться за допомогою інструментів на зразок Robolectric, XCTest, Junit і WebDriver.
Цей набір інструментів для складання та тестування не тільки запускається на кожному кімміті, а й кілька разів запускається протягом життєвого циклу кожної зміни в коді. Тільки під Android ми збираємо від 50 000 до 60 000 білдів на день.
Використовуючи традиційні методи безперервного постачання ПЗ на нашому мобільному стеку, ми перейшли від релізів кожні чотири тижні до двотижневого, а потім щотижневого циклу. Сьогодні на мобільній платформі ми використовуємо ту ж модель ручного відбору змін, яку раніше використовували у вебі. Хоча ми викочуємо зміни в продакшн тільки раз на тиждень, як і раніше важливо заздалегідь тестувати код в реальних умовах, щоб інженери заздалегідь отримали відгуки від користувачів. Ми щодня випускаємо реліз-кандидати для бета-тестерів, серед яких близько 1 мільйона тестерів під Android.
У той час як ми збільшили частоту випуску релізів, чисельність наших розробників для мобільних платформ збільшилася в 15 разів, а швидкість розробки теж значно зросла. Незважаючи на це, дані з 2012 по 2016 роки показують, що продуктивність праці інженерів залишилася незмінною під Android і iOS, як за кількістю рядків коду, так і за кількістю пушів. Також і кількість критичних проблем у мобільних додатках майже не змінилася, незалежно від кількості релізів, тобто якість коду не постраждала в результаті масштабування.
Дуже приємно працювати в області проектування релізів на тлі таких поліпшень у доступних інструментах і методологіях. Я дуже гордий за групи розробки в Facebook, які працювали спільно, щоб створити, на мій погляд, найбільш просунуті в світі системи впровадження веб- і мобільних додатків подібного масштабу. Таке було б неможливим без сильної групи проектування релізів, яка була на перших ролях у відділі розробки інфраструктури. Ця група в Facebook продовжить просувати ініціативи, які покращують для розробників і користувачів процес випуску релізів, і продовжить ділитися своїм досвідом, інструментарієм і кращими практиками.












