Как стать автором
Обновить
4
0
Алексей Партилов @droppoint

Backend разработчик

Отправить сообщение
Конечно у нас в микросервисах есть обработка SIGTERM, высвобождение коннектов их повторная иницация в случае закрытия со стороны сервера и другие полезные вещи. Код для этого у нас тоже генерируется. Я думаю оригинальный вопрос был больше про то как погасить сервис перед этим перестав присылать на него запросы, чтобы они не падали в несуществующий upstream.
1. Получается, что все сервисы шарят общий базовый код? Ведь в литературе о микросервисах мы повсеместно находим что-то вроде этого:

В микросервисах написанных на python у нас была общая библиотека, которая шарилась между сервисами и мы на этом обожглись. Обслуживать эту библиотеку стало сложно, нужно постоянно следить за совместимостью версий, обновлять библиотеку в разных сервисах и при этом следить чтобы ничего не сломалось. Поэтому сейчас, в микросервисах на go у нас нет расшаренного кода. Весь код генерируется из OpenAPI спецификаций и сервисы независимы между собой. Шаблон микросервиса — это скорее история про эталон к которому должны подтягиваться проекты чтобы не сильно отличаться между собой. Он отрабатывает только на этапе генерации микросервиса и больше не является зависимостью. Можно сказать мы осознанно идем против принципа DRY здесь, чтобы не увеличивать связность между сервисами.
Если я ничего не упустил, у вас получается голый кубер, рассматривали ли какие-нибудь сервис меши для него? Чем закончились результаты рассмотрения, если были?

Очень хотим внедрить меши и скорее всего начнем какие-то движения в эту сторону уже в этом году. Насколько мне известно, наши DevOPS экспериментируют с Istio и Linkerd.
Вопрос авторизации и аутентификации в микросервисной архитектуре: долго ли мучались, на чем остановились?

У нас есть один сервис который занимается аутентификацией, к нему в основном обращаются 2 сервиса которые принимают трафик извне: наше мобильное API и сайт. Далее запросы от этих сервисов к микросервисам уже идут без повторной аутентификации. Авторизация при этом конечно остается. Мы обязательно проверяем, что пользователь запросил именно свои заказы, а не соседа) Насколько мне известно ощутимых болей при внедрении такого подхода никто особо не испытывал.
Для чего вы используете в названиях пакетов несколько слов и underscores ?)

Если речь про go пакеты, то подавляющее количество названий у нас — это отдельное слово. Названия в несколько слов встречаются, но редко. Обычно обусловлено предметной областью, например, «ограничители правил скидок по лояльности» тяжело впихнуть в одно слово.
Наш генератор кода, который мы ласково зовем gogi генерирует по OpenAPI спецификации в том числе и серверный код, в котором есть код отвечающий за инициализацию логера, передачу метрик и т.д. То есть в вашем случае, возможно вам стоит начать с обертки которая будет заниматься всеми вещами что вы перечислили.

Насчет инфраструктурных вещей. Для метрик у нас применяется Prometheus, для логов у нас применяется Elastic+Kibana, Graceful shutdown можно сказать встроен в Kubernetes, трафик внутри Kubernetes мы направляем через ingress либо напрямую между сервисами.

Consul, насколько мне известно, мы сейчас не применяем.
Идея монорепо у нас переодически всплывает в компании, но пока сторонников у нее сильно меньше, чем противников. Да, обновлять сервисы возможно станет проще. Одним коммитом ты можешь обновить все сервисы которые у тебя есть. Но это несет в себе дополнительные расходы в администрировании и целый пласт новых неизведанных проблем. Последнее пока перевешивает у нас в компании.
Пока никак, шаблон создали сравнительно недавно. В любом случае будем что-то добавлять, и да, не ожидается что это будет просто. Но у шаблона есть меинтейнеры, он открыт для Pull Request'ов со стороны любого разработчика в Lamoda, да и меинтейнеры всегда готовы помочь адаптировать существующие проекты под шаблон.
Если говорить про прод, и конкретно про наш опыт в этом вопросе, то у нас такие кейсы вылавливаются либо при мердже feature ветки в основную, либо при накатке миграций на продовую базу. Как я упоминал ранее у нас есть отдельная deploy'ная job'а для накатки миграций и при ее работе сразу видно что накатилось, а что нет. Мы правда еще обычно и руками проверяем на всякий.

Если говорить про локальную машину — то в нашем случае если в разных ветках разные миграции и ребейзиться прямо вот сейчас не хочется, то никто не мешает убить контейнер с базой, а потом поднять его снова чистым и накатить миграции. Если посмотреть на docker-compose файл в статье, то мы делаем
make dev-down
make dev-server

и живем дальше.
Насколько я знаю migrate тоже поддерживает «вшивание» миграций в бинарник, через go-bindata. http://https://github.com/golang-migrate/migrate#migration-sources Мы у себя правда используем вариант с docker образом migrate и монтируем в него папку с миграциями (примерно также как в docker-compose.yml в статье). Все это осуществляется в рамках отдельной deploy'ной job'ы, вроде хватает. Но ваш вариант обязательно изучу.
Как пример — django.

В Django мы ловим те же самые проблемы. Собственно там мы чаще всего и ловим) Там же тоже внутри каждой миграции описывается от какой миграции она зависит. И вот когда два разработчика завязываются на одну базовую миграцию — возникает конфликт и Django точно так же не дает их накатить.
Миграции должны иметь последовательность. Будет сложно предсказать результат если невыполненные миграции будут накатываться в произвольном порядке ибо одна миграция обычно зависит от другой. У нас бывает конечно такая проблема, что два и более разработчика работают в одном сервисе и пишут миграции. Но это случается очень редко и в таком случае у нас действует правило: «Кто первым встал — того и тапки». Касательно инструментов, некоторые команды в Lamoda еще используют goose, основное отличие только в том что миграции «вверх» и «вниз» описываются в одном файле.

Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Работает в
Дата рождения
Зарегистрирован
Активность