Previous Entry Share Next Entry
2016-01

on software

Ищу best practices по версионированию и интеропу версий.

Особенно интересны чеклисты или какие-то basics guides, чтобы не писать их самому.

Примеры вопросов, на которые оно должно отвечать:
- Есть кластер, хочется обновлять ноды постепенно, и не тушить при этом кластер. Как облегчить оверхед / сделать более надежные тесты / чтобы ничего не ломалось при апгрейде протокола?
- Есть БД, к ней коннектятся клиенты разных версий. Например, мобильные приложения, которые небыстро апдейтятся. Как правильно это всё поддерживать?
- Фронтенд ходит к нескольким backend services, которые пишутся разными командами. Хочется максимально отвязать друг от друга release cycles этих сервисов, ну и не ломать ничего, понятно.

Если говорить количественно, то хочется сократить
- время релиза новой фичи (вызывающей изменения в протоколах/схемах/форматах)
- время на согласование протоколов (чем больше можно автоматизировать/автоматически проверить - тем лучше)
- количество багов протекающих в продакшен
- время диагностики бага

Почему-то находятся всякие общие слова, но общие слова я и так знаю. Надо либо какие-то тупые и надежные гайды, которые можно пошагово исполнять и не думать про них, либо real-world experience, по которому можно сделать выводы и такие схемы написать.

This entry was originally posted at http://wizzard.dreamwidth.org/479299.html. It has comment count unavailable comments. Please comment there using OpenID.

  • 1
swamp_agr January 18th, 11:28
1. Не хочется. Надо планировать окно и гасить кластер. Обновить ноды и поднять. Иметь поднятую копию приложению и все скрипты миграции данных за период обновления, чтобы их перенести в момент Х.
2. Держать разные серверы БД для разных версий приложения. Минимизировать рассинхронизацию.
3. Консолидированная шина, через которую ходят все клиенты. Не позволять им стучаться на разные endpoint-ы.

wizzard0 January 20th, 7:32
1) См. ниже http://www.livejournal.com/manage/subscriptions/comments.bml?journal=wizzard0&talkid=6171126
2) Разные серверы БД кстати частично тоже уже да, и частично решается тем, что квери тупо гоняются по разным версиям и джойнятся. Машин только становится нужно до чертиков...

vit_r January 18th, 11:30
Какие могут быть "тупые и надежные гайды", если это всё зависит от процессов и опыта? Тем более, требование противоречивые. И времени на согласование протоколов жалко, и ошибки, возникшие от их несогласования искать не хочется.

Тут или серьёзно разрабатывается протокол, а потом все добавления идут просто дополнениями, игнорируемыми старой версией, или опять пляски с бубнами.

Для того, чтобы код сливался без проблем, нужны очень жёсткие правила кодирования, вплоть до того, сколько пробелов где отступом ставить. (Хотя, дурное форматирование и глупые правила, в свою очередь, будут множить ошибки, так что это тоже место очень серьёзных вложений и планирования)

wizzard0 January 20th, 7:27
Зависит, конечно. Только вот у Боинга во внутренней документации по кодописанию почему-то гайды есть, хоть это и тоже зависит от процессов и опыта.

metaclass January 18th, 11:56
Микросервисы это какие-то, причем в каждом апи придется добавить поле "версия апи" и поддерживать +-N версий. Если не поддерживается - жаловаться в мониторинг и дальше пусть умные разбираются.
Кроме тестов толком ничего не спасет. В стиле "выкатываем на 10% запросов новую версию и смотрим, как быстро она умрет". Умершие запросы перебалансируются на еще живые сервисы, мертвый откатывается до разборок и все в том же духе.
Короче, ломать все, пусть у роботов голова думает, они железные.

anonim_legion January 18th, 14:44
Вот, а говорили что ЖЖ не нужен.

alexeyk77 January 18th, 12:33
Все зависит от приложения. В банке как правило для центральных учетных системы плавная миграция не проканывает, система останавливаеся полностью и накатывается новая версия. Перед этим проводится тестирование на отдельной тестовой системе.
В одной из достаточно сложных SIEM-систем, которую эксплуатирую поддерживается разные версии API, т.е. реализован вариант metaclass-а. Даже процессинговые системы иногда приходится полностью останавливать и тогда все карточки не работают.
Но вообще конечно же использование MQ-шины как API-прослойки для передачи сообщений между разными системами сильно облегчает поддержку систем состоящей из разношерстных решений.

wizzard0 January 20th, 7:29
MQ уже есть, и да, помогает. Центральных учетных данных нет, их можно апгрейдить по частям. Т.е. доступ к данным оч хорошо разграничен. А вот условие сосуществования нескольких версий нод - обязательное.

veremeenko_alex January 18th, 13:22
Вот ты и напишешь :)!

wizzard0 January 20th, 7:35
))

zealer January 18th, 18:40
eBay хранит все предыдущие версии АПИ..

В одной из предыдущих компаний мы поддерживали две версии АПИ с помощью хедера, который потом от рутера посылал на нужный сервер. Старая версия оставалась запущенной неделю. Для более старой версии просило обновить клиента на странице (и в телефоне).

vissarion January 19th, 6:48
SalesForce тоже
версию надо сразу заносить в урл API даже если "приложение простое, ничего никогда не будет меняться"
типа mystartup.com/api/v1/rest/...

jakobz January 19th, 11:29
Фейсбук вон graphql продвигает, он в частности, помогает с версионностью. Т.е. я думаю что правильный путь - строить более high-level API: не REST с методами на каждый чих, а что-то типа Query на входе, более-менее generic-формат на выходе.

Хотя сам GraphQL мне не нравится, мне кажется там опять наступают в ловушку Object-Relational Mismatch. С первого взгляда удобно - и запрос, и ответ - дерево, для UI попроще. Но когда ты с этим начинаешь хитрее работать - менять данные на клиенте, или делать посложнее запросы - все равно всё возвращается к реляционной модели.

Мне кажется что у Datomic наиболее прямая модель данных. С запросами я только пока не разобрался, непонятно можно ли там граф достать, или такой же треш как в SQL.

wizzard0 January 20th, 7:35
GraphQL совсем не в кассу, но схемохранилище, похоже, будем заводить... См. другие комменты.

А, и у нас к счастью нету обьектов ;)

Датомик совсем не пойдет, требования по перформансу очень жесткие, все кастомное.

ady_1981 January 19th, 20:01
В мире Erlang + OTP это все решено :).

wizzard0 January 20th, 7:26
Гайды, ссылки на гайды и дизайн-доки где?

egorfine January 24th, 23:30
сонные мысли

Когда я пишу какой-либо обмен данными, я всегда в начало добавляю поле для номера версий и его проверку на всех ендпоинтах. Кроме того, я ставлю номер желаемой версии и в запрос данных. Это все - единицы строчек кода в начале девелопмента, мясом они обрастают потом, и сильно облегчают жизнь.

Кроме того, во многие протоколы я с самого начала закладываю такие вещи:

* подожди братишка X секунд. В ответ на это запрашивающий код должен подождать не менее X секунд до второй попытки. Это очень полезный кусок: можно отложить всех клиентов на время апдейта кода, можно останавливать часть серверов во время пиковых нагрузок, и так далее.

* сообщение для человека: ZZZZ. Это в user-facing API полезно, чтобы пушить юзеру кастомные сообщения. Самый популярный use case: приходит древнючая версия приложения, API которой уже давно нет. Ему вместе с "подожди Infinity секунд" пихаем строчку "обнови софт, дурилка".

Что еще?.. ну, сбор данных делается по лекалу. То есть всё, что мы собираем от другого софта, мы не используем напрямую, а берем темплейт структуры данных с дефолтовыми значениями и заполняем значениями, полученными от источника. Так мы гарантируем на выходе всегда полную структуру со всеми полями, а источниками данных могут быть разные версии софта.

var resultData = Object.deepCopy(template);
Object.keys(incomingStats).forEach(key => { resultData[key] = incomingStats[key]; });
// упрощенно, конечно

Или, скажем, движение данных в обратном порядке: мы воркер, регулярно получаем апдейт данных с центрального сервера. Если мы смогли распарсить - окей, считаем транзакцию успешной, работаем дальше. Если не смогли - пользуемся предыдущей версией данных, работаем дальше. Если не смогли скачать свежую версию за время X - вот только тогда останавливаемся. Это позволяет в кластере одним быстрым движением обновлять центральные сервера с источником данных, в то время как сервера-воркеры продолжают работать независимо.

А вообще есть простая экономика. Что дороже:

1. простой в несколько минут на время апгрейда всего софта на кластере + риски неудачно накатиться ИЛИ
2. стоимость разработки совместимости версий + риски, связанные с такой сложностью кода?

Принимать решение надо case-by-case. Иной раз не надо стесняться аккуратно складывать систему и апгрейдить все целиком. В одной большой финансовой системе, которую мы разработали и поддерживаем на огромное количество юзеров, мы практически с самого начала решили, что у нас апдейты будут с простоем. Так мы избавили себя от целой кучи рисков и геморроя с кодом. По мере взросления системы время простоя падало, пока не дошло до секунд.

А вообще ты задал слишком широкий вопрос. На него не может быть конкретного ответа кроме потока сознания.

  • 1
?

Log in

No account? Create an account