Учения
Обычно написание кода подразумевает обработку ошибок. Тут запрос вернул 500, и мы подставили дефолтное значение; там ошибка при попытке записать на диск, и мы показали пользователю сообщение итд.
Код обработки ошибок, как и любой другой код, имеет свойство ломаться и устаревать, если он не работает. Я часто встречаюсь с тем, что код, который должен был спокойно обрабатывать ошибку приводит к каким-нибудь сегфолтам. При каких-то минорных неполадках в системе, которые должны легко парироваться, может прилечь весь бизнес.
Конечно, отличным решением может быть покрытие тестами вроде: если сервис А отвечает Б, то должно происходить В. Но если ресурсов на имплементацию таких вещей нет, то можно обойтись минимумом - учения.
Учения в этом случае - ручные тесткейсы интеграционного тестирования, которые можно провести прям на продакшн сервисе с целью понять, что ваша обработка ошибок работает так, как должна.
Что можно сделать и что проверяем:
— Гасить отдельные сервисы
проверяем: что пользователи этих сервисов умеют работать без них (graceful degradation)
— Гасить часть машин, отдельные ДЦ
проверяем: что сервис продолжает жить при таких вещах, как выход из строя оборудования (например, пожар), что остальные машины справляются с возросшей нагрузкой
— Отключать функциональность
проверяем: что функциональность, которая должна быть отключаемой - остается отключаемой.
#reliability #practices #ru
Обычно написание кода подразумевает обработку ошибок. Тут запрос вернул 500, и мы подставили дефолтное значение; там ошибка при попытке записать на диск, и мы показали пользователю сообщение итд.
Код обработки ошибок, как и любой другой код, имеет свойство ломаться и устаревать, если он не работает. Я часто встречаюсь с тем, что код, который должен был спокойно обрабатывать ошибку приводит к каким-нибудь сегфолтам. При каких-то минорных неполадках в системе, которые должны легко парироваться, может прилечь весь бизнес.
Конечно, отличным решением может быть покрытие тестами вроде: если сервис А отвечает Б, то должно происходить В. Но если ресурсов на имплементацию таких вещей нет, то можно обойтись минимумом - учения.
Учения в этом случае - ручные тесткейсы интеграционного тестирования, которые можно провести прям на продакшн сервисе с целью понять, что ваша обработка ошибок работает так, как должна.
Что можно сделать и что проверяем:
— Гасить отдельные сервисы
проверяем: что пользователи этих сервисов умеют работать без них (graceful degradation)
— Гасить часть машин, отдельные ДЦ
проверяем: что сервис продолжает жить при таких вещах, как выход из строя оборудования (например, пожар), что остальные машины справляются с возросшей нагрузкой
— Отключать функциональность
проверяем: что функциональность, которая должна быть отключаемой - остается отключаемой.
#reliability #practices #ru
Consistent hashing
Когда наступает пара масштабироваться, встает вопрос "как" делить пользовательские запросы между несколькими инстансами. Если у вас stateless сервисы, то от запроса к запросу одного и того же пользователя можно направлять на разные инстансы - никаких проблем нет.
Проблемы появляются, когда у вас есть какой-то state (например, кэш авторизаций пользователей). Ну ничего, можно приземлить пользователей на какой-то один инстанс, если взять его id по модулю количества этих инстансов (instance_id = user_id % instances_count - 1).
Но что, если вам требуется добавить один новый инстанс? Если мы оставим нашу формулу, то большинство клиентов сменит инстанс, что приведет к потере state (и, например, валу перезапросов на сервис авторизации).
Особый вид хэширования Consistent hashing служит для того, чтобы бОльшая часть пользователей (будут переназначены только user_id_count/instances_count ключей) осталась "жить" на том же инстансе при добавлении нового.
В статье объясняется принцип его работы с картинками на основе кольцевого массива.
https://medium.com/better-programming/load-balancers-and-consistent-hashing-in-6-minutes-b5fc460aea4e
#practices #medium #en
Когда наступает пара масштабироваться, встает вопрос "как" делить пользовательские запросы между несколькими инстансами. Если у вас stateless сервисы, то от запроса к запросу одного и того же пользователя можно направлять на разные инстансы - никаких проблем нет.
Проблемы появляются, когда у вас есть какой-то state (например, кэш авторизаций пользователей). Ну ничего, можно приземлить пользователей на какой-то один инстанс, если взять его id по модулю количества этих инстансов (instance_id = user_id % instances_count - 1).
Но что, если вам требуется добавить один новый инстанс? Если мы оставим нашу формулу, то большинство клиентов сменит инстанс, что приведет к потере state (и, например, валу перезапросов на сервис авторизации).
Особый вид хэширования Consistent hashing служит для того, чтобы бОльшая часть пользователей (будут переназначены только user_id_count/instances_count ключей) осталась "жить" на том же инстансе при добавлении нового.
В статье объясняется принцип его работы с картинками на основе кольцевого массива.
https://medium.com/better-programming/load-balancers-and-consistent-hashing-in-6-minutes-b5fc460aea4e
#practices #medium #en
Medium
How Consistent Hashing Is Used by Load Balancers to Distribute Requests
Load balancers and consistent hashing in six minutes
Forwarded from Teamlead Good Reads – ежедневные советы про менеджмент людей и команд (Andrey Gomenyuk) via @like
Полагаю, все здесь знают, что такое 1-1 (или one on one, 1:1, один-один, тет-а-тет). Я считаю, что этот формат общения — один из самых важных инструментов в рукаве тимлида/руководителя, но очень недооценен. Про него обе сегодняшние статьи.
Мне 1:1 довольно долго не заходил, пока я где-то не наткнулся на хороший материал про этот формат (к сожалению, найти его уже не могу). Основная идея в том, что он предназначен не для получения статуса по задачам от подчиненного, а для обсуждения успехов, неудач, планов и т.д. Если сделать 1:1 откровенными, честными, открытыми, то можно будет узнавать о людях очень много такого, чего в обычной обстановке они бы не рассказали: свои взгляды на карьеру, чего хочется, что не нравится. Вам, как руководителю, остается только использовать эту информацию для роста человека и предотвращения кризисов. Статья уровня “сейчас я научу вас жизни”, но в ней есть интересные мысли. https://medium.com/@zackbloom/youre-doing-one-on-ones-wrong-dfc27f36f204
Наверное, не сильно ошибусь, если скажу, что большинство тимлидов и руководителей на этом канале так или иначе вышли из разработки/тестирования/администрирования, в общем, люди с техническим бэкграундом. По своему опыту, таким людям не всегда легко дается открытое общение с начальством/подчиненными. Следующая статья как раз про то, что хорошие 1:1 получаются тогда, когда вам “неловко”: вы перешагиваете через себя и рассказываете о своих мыслях, мечтах, планах, неудачах. В статье есть примеры вопросов/тем, которые подталкивают к открытому общению. https://medium.com/@mrabkin/the-art-of-the-awkward-1-1-f4e1dcbd1c5c (есть вторая часть про то, как получать честный фидбек о себе — тоже рекомендую).
От себя хочу добавить, что большинство менеджерских инструментов, включая 1:1, можно применять снизу вверх. Если вы считаете, что 1:1 с вашим руководителем могут проходить эффективнее, сами предложите поменять формат. Если вы видите, что вашему руководителю не о чем с вами поговорить, заведите разговор сами, например, расскажите, каким вы видите свой рост, как вы развиваетесь, спросите совета по застрявшим проектам/задачам и т.д.
А вы считаете 1:1 полезными? (Отвечайте отрицательно, если не проводите/с вами не проводят).
Мне 1:1 довольно долго не заходил, пока я где-то не наткнулся на хороший материал про этот формат (к сожалению, найти его уже не могу). Основная идея в том, что он предназначен не для получения статуса по задачам от подчиненного, а для обсуждения успехов, неудач, планов и т.д. Если сделать 1:1 откровенными, честными, открытыми, то можно будет узнавать о людях очень много такого, чего в обычной обстановке они бы не рассказали: свои взгляды на карьеру, чего хочется, что не нравится. Вам, как руководителю, остается только использовать эту информацию для роста человека и предотвращения кризисов. Статья уровня “сейчас я научу вас жизни”, но в ней есть интересные мысли. https://medium.com/@zackbloom/youre-doing-one-on-ones-wrong-dfc27f36f204
Наверное, не сильно ошибусь, если скажу, что большинство тимлидов и руководителей на этом канале так или иначе вышли из разработки/тестирования/администрирования, в общем, люди с техническим бэкграундом. По своему опыту, таким людям не всегда легко дается открытое общение с начальством/подчиненными. Следующая статья как раз про то, что хорошие 1:1 получаются тогда, когда вам “неловко”: вы перешагиваете через себя и рассказываете о своих мыслях, мечтах, планах, неудачах. В статье есть примеры вопросов/тем, которые подталкивают к открытому общению. https://medium.com/@mrabkin/the-art-of-the-awkward-1-1-f4e1dcbd1c5c (есть вторая часть про то, как получать честный фидбек о себе — тоже рекомендую).
От себя хочу добавить, что большинство менеджерских инструментов, включая 1:1, можно применять снизу вверх. Если вы считаете, что 1:1 с вашим руководителем могут проходить эффективнее, сами предложите поменять формат. Если вы видите, что вашему руководителю не о чем с вами поговорить, заведите разговор сами, например, расскажите, каким вы видите свой рост, как вы развиваетесь, спросите совета по застрявшим проектам/задачам и т.д.
А вы считаете 1:1 полезными? (Отвечайте отрицательно, если не проводите/с вами не проводят).
Medium
You’re Doing One-on-Ones Wrong
One-on-ones are a common management tool where you have a (wait for it) one on one meeting with a direct report who works with you. Like…
Saga Pattern
Большую головную боль в микросервисной архитектуре приносит с собой вопрос - как добиться согласованных изменений в нескольких микросервисах?
Паттерн Сага пытается решить этот вопрос. Он подразумевает, что каждый сервис выполняет транзакции (по ACID принципам) в той зоне, за которую он ответственен. Также сервис должен поддерживать компенсационную транзакцию, которая будет откатывать изменения, если что-то пошло не так.
Набор таких транзакций и есть "сага".
Есть два способа того, как вести сагу, отличающиеся тем, кто в схеме оркестрирует изменениями:
- Choreography, где каждый сервис сам тригерит следующую транзакцию
- Orchestration, при которой есть один общий оркестратор, который берет на себя ответственность за последовательность саги
https://microservices.io/patterns/data/saga.html
UPD: из чата посоветовали еще несколько полезных материалов по теме:
#en - https://medium.com/swlh/microservices-architecture-what-is-saga-pattern-and-how-important-is-it-55f56cfedd6b
#ru - https://habr.com/en/company/avito/blog/426101/
#en - https://speakerdeck.com/caitiem20/distributed-sagas-a-protocol-for-coordinating-microservices
#ru - https://habr.com/en/company/oleg-bunin/blog/418235/
#pattern #microservices #practices #doc #en #ru
Большую головную боль в микросервисной архитектуре приносит с собой вопрос - как добиться согласованных изменений в нескольких микросервисах?
Паттерн Сага пытается решить этот вопрос. Он подразумевает, что каждый сервис выполняет транзакции (по ACID принципам) в той зоне, за которую он ответственен. Также сервис должен поддерживать компенсационную транзакцию, которая будет откатывать изменения, если что-то пошло не так.
Набор таких транзакций и есть "сага".
Есть два способа того, как вести сагу, отличающиеся тем, кто в схеме оркестрирует изменениями:
- Choreography, где каждый сервис сам тригерит следующую транзакцию
- Orchestration, при которой есть один общий оркестратор, который берет на себя ответственность за последовательность саги
https://microservices.io/patterns/data/saga.html
UPD: из чата посоветовали еще несколько полезных материалов по теме:
#en - https://medium.com/swlh/microservices-architecture-what-is-saga-pattern-and-how-important-is-it-55f56cfedd6b
#ru - https://habr.com/en/company/avito/blog/426101/
#en - https://speakerdeck.com/caitiem20/distributed-sagas-a-protocol-for-coordinating-microservices
#ru - https://habr.com/en/company/oleg-bunin/blog/418235/
#pattern #microservices #practices #doc #en #ru
microservices.io
Microservices Pattern: Pattern: Saga
Implement transactions using a saga, which is sequence of local transactions
Graceful degradation
Должна ли какая-то функциональность ломать весь сервис? — Заданный таким образом вопрос, конечно же, получит ответ "нет".
А что, если сломается какая-то core функциональность? Например, в вашем сервисе пользователь получает какую-то услугу за деньги и ломается модуль, отвечающий за оплату. Отдавать пользователю при этом его покупку?
И, конечно, ответ на вопрос зависит от бизнес требований, но я бы сказал, что в большинстве случаев — ответ такой же — нет.
В случае, когда есть выбор — сломаться совсем или сделать хоть что-то (если это не приведет, конечно, к неконсистентному состоянию) почти всегда нужно выбирать сделать хоть что-то.
В такой парадигме мышления, любой сервис должен быть построен таким образом, чтобы без проблем отстреливалась любая функциональность.
Я где-то прочитал хороший пример, попробую воспроизвести:
Если вы показываете персонализированный топ фильмов пользователю и ...
... у вас отвалились персональные рекомендации — просто показывайте фильмы, которые пользователь еще не смотрел
... у вас отвалились пользователи — просто показывайте общий топ
... у вас сломалось совсем все — показывайте какой-нибудь статичный файл со списком фильмов
Сегодня доклад моего коллеги про Graceful degradation
https://habr.com/en/company/yandex/blog/438606/
#practices #speech #habr #ru
Должна ли какая-то функциональность ломать весь сервис? — Заданный таким образом вопрос, конечно же, получит ответ "нет".
А что, если сломается какая-то core функциональность? Например, в вашем сервисе пользователь получает какую-то услугу за деньги и ломается модуль, отвечающий за оплату. Отдавать пользователю при этом его покупку?
И, конечно, ответ на вопрос зависит от бизнес требований, но я бы сказал, что в большинстве случаев — ответ такой же — нет.
В случае, когда есть выбор — сломаться совсем или сделать хоть что-то (если это не приведет, конечно, к неконсистентному состоянию) почти всегда нужно выбирать сделать хоть что-то.
В такой парадигме мышления, любой сервис должен быть построен таким образом, чтобы без проблем отстреливалась любая функциональность.
Я где-то прочитал хороший пример, попробую воспроизвести:
Если вы показываете персонализированный топ фильмов пользователю и ...
... у вас отвалились персональные рекомендации — просто показывайте фильмы, которые пользователь еще не смотрел
... у вас отвалились пользователи — просто показывайте общий топ
... у вас сломалось совсем все — показывайте какой-нибудь статичный файл со списком фильмов
Сегодня доклад моего коллеги про Graceful degradation
https://habr.com/en/company/yandex/blog/438606/
#practices #speech #habr #ru
Habr
Graceful degradation. Доклад Яндекс.Такси
Сервисы необходимо писать так, чтобы минимальная функциональность сохранялась всегда — даже если откажут критически важные компоненты. Илья Сидоров, руководитель одной из команд продуктовой разработки...
Monolith to Event-Driven Microservices with Apache Kafka
Сегодняшняя статья интересна тем, что рассказывает не о том, как нужно строить правильную микросервисную архитектуру с самого начала, а о том, что, собственно, можно делать с такой штукой, как разросшийся монолит.
В статье с помощью последовательного применения кучки умных паттернов рассматривается метод преобразования монолита к микросервисной архитектуре, где в центре всей концепции находится хранилище событий вашей системы.
https://medium.com/swlh/monolith-to-event-driven-microservices-with-apache-kafka-6e4abe171cbb
#monolith #pattern #microservices #practices #en
Сегодняшняя статья интересна тем, что рассказывает не о том, как нужно строить правильную микросервисную архитектуру с самого начала, а о том, что, собственно, можно делать с такой штукой, как разросшийся монолит.
В статье с помощью последовательного применения кучки умных паттернов рассматривается метод преобразования монолита к микросервисной архитектуре, где в центре всей концепции находится хранилище событий вашей системы.
https://medium.com/swlh/monolith-to-event-driven-microservices-with-apache-kafka-6e4abe171cbb
#monolith #pattern #microservices #practices #en
Medium
Monolith to Event-Driven Microservices with Apache Kafka
Event-Driven Architecture refer to rather old concept of Software Engineering that gained a lot of relevancy recently due to the need for…
Ретроспектива
После окончания большого проекта правильно устраивать ретроспективу. Ретроспектива — попытка порефлексировать на тему того, что было сделано хорошо, что можно было бы сделать лучше и нагенерировать какие-то экшн-поинты на будущее. На какой-то конференции я слышал выражение "без рефлексии нет развития". По-моему, это подходит как для личности, так и для команды.
В статьях выделены плюсы проведения ретроспективы. Она помогает:
— увидеть необходимость постоянных улучшений в работе
— замотивировать участников на достижение будущих целей
— перенимать знания
— развивать участников команды
— управлять улучшениями и изменениями
— управлять знаниями, пополнять их
— повышать уровень сотрудников
https://donskih.ru/2016/09/retrospektiva-proekta/
https://tproger.ru/blogs/retrospective-analysis/
#practices #people #ru
После окончания большого проекта правильно устраивать ретроспективу. Ретроспектива — попытка порефлексировать на тему того, что было сделано хорошо, что можно было бы сделать лучше и нагенерировать какие-то экшн-поинты на будущее. На какой-то конференции я слышал выражение "без рефлексии нет развития". По-моему, это подходит как для личности, так и для команды.
В статьях выделены плюсы проведения ретроспективы. Она помогает:
— увидеть необходимость постоянных улучшений в работе
— замотивировать участников на достижение будущих целей
— перенимать знания
— развивать участников команды
— управлять улучшениями и изменениями
— управлять знаниями, пополнять их
— повышать уровень сотрудников
https://donskih.ru/2016/09/retrospektiva-proekta/
https://tproger.ru/blogs/retrospective-analysis/
#practices #people #ru
Консалтинговая группа Донских
Ретроспектива проекта
Ретроспектива проекта - собрание, встреча команды после завершения какого-либо проекта для того, чтобы подвести итоги, поделиться полученным опытом и составить планы на будущее. Это всегда очень важный шаг для развития компании, который направлен на повышении…
Microservices: don’t use them yet!
Микросервисы: пока не используйте их!
От теории к практике. В статье рассказывается про занимательный опыт быстрого роста проекта и команды. Автор делится своими выводами, полученными опытным путем:
— Количество микросервисов должно быть меньше, чем количество разработчиков
— Методы сервиса теперь обязательно должны иметь REST api и валидации
— Переключения контекста реально дороги
— Монорепозиторий - серебряная пуля
https://medium.com/teamzerolabs/micro-services-dont-use-them-yet-f58a2758d8f9
#monolith #microservices #practices #en
Микросервисы: пока не используйте их!
От теории к практике. В статье рассказывается про занимательный опыт быстрого роста проекта и команды. Автор делится своими выводами, полученными опытным путем:
— Количество микросервисов должно быть меньше, чем количество разработчиков
— Методы сервиса теперь обязательно должны иметь REST api и валидации
— Переключения контекста реально дороги
— Монорепозиторий - серебряная пуля
https://medium.com/teamzerolabs/micro-services-dont-use-them-yet-f58a2758d8f9
#monolith #microservices #practices #en
Medium
Microservices: don’t use them yet!
10 reasons to reconsider using microservices
Шардирование по географии - скорее всего, плохое решение для вас.
Достигая какой-то критической массы нагрузки своего сервиса, вы приходите к шардированию - осмысленному разделению обработки данных (для примера, клиентских запросов) по несвязанным кластерам.
Одна из самых простых вещей, которая приходит в голову - это разделить пользователей по географии, например, по городам: пользователи из города N будут всегда обрабатываться на кластере 1, пользователи из города M будут всегда будут приходить на кластер 2.
Но за простотой реализации такого подхода стоит достаточно сложная оркестрация (и, даже, жонглирование) нагрузки. У вас есть 2 кластера: на одном отправляются запросы из города N, на другой - из города M, нужно держать в голове:
— В какой кластер добавлять запросы из третьего нового города
— Что делать, если границы города N сильно меняются и этот кластер уже не выдерживает
— Как перераспределять ресурсы, если какой-то город выключается
Хотя преимущества тоже есть:
— Проблемы в кластере, который обрабатывает один набор городов не влияют на остальные
— Если вынос какого-то города подразумевает уменьшение требуемых на обработку ресурсов (например, если вы делаете роутинг и вам нужно держать в памяти граф. Географическое разделение поможет сэкономить ресурсы)
По теме шардирования, можно почитать неплохой доклад с конференции HighLoad:
https://habr.com/en/company/oleg-bunin/blog/433370/
Достигая какой-то критической массы нагрузки своего сервиса, вы приходите к шардированию - осмысленному разделению обработки данных (для примера, клиентских запросов) по несвязанным кластерам.
Одна из самых простых вещей, которая приходит в голову - это разделить пользователей по географии, например, по городам: пользователи из города N будут всегда обрабатываться на кластере 1, пользователи из города M будут всегда будут приходить на кластер 2.
Но за простотой реализации такого подхода стоит достаточно сложная оркестрация (и, даже, жонглирование) нагрузки. У вас есть 2 кластера: на одном отправляются запросы из города N, на другой - из города M, нужно держать в голове:
— В какой кластер добавлять запросы из третьего нового города
— Что делать, если границы города N сильно меняются и этот кластер уже не выдерживает
— Как перераспределять ресурсы, если какой-то город выключается
Хотя преимущества тоже есть:
— Проблемы в кластере, который обрабатывает один набор городов не влияют на остальные
— Если вынос какого-то города подразумевает уменьшение требуемых на обработку ресурсов (например, если вы делаете роутинг и вам нужно держать в памяти граф. Географическое разделение поможет сэкономить ресурсы)
По теме шардирования, можно почитать неплохой доклад с конференции HighLoad:
https://habr.com/en/company/oleg-bunin/blog/433370/
Habr
Теория шардирования
Кажется, мы так глубоко погрузились в дебри highload-разработки, что просто не задумываемся о базовых проблемах. Взять, например, шардирование. Чего в нем разбираться, если в настройках базы данных...
Forwarded from Teamlead Good Reads – ежедневные советы про менеджмент людей и команд (Egor Tolstoy)
Хорошая статья CTO Dodo Pizza про то, как меняется роль технического руководителя при росте команды в 4-14-40-140 человек.
https://medium.com/@alex4Zero/4-14-40-140-8ac3bc6c1fdd
https://medium.com/@alex4Zero/4-14-40-140-8ac3bc6c1fdd
Medium
4. 14. 40. 140.
Это не IP адрес. Это не случайный набор чисел. Это не координаты долготы и широты.Это логика роста лидеров в IT, которую я вижу по своему…
Event Sourcing
https://martinfowler.com/eaaDev/EventSourcing.html
Долго думал как подступиться к этой обширной теме. Сама идея кажется просто замечательной — вместо того, чтобы в stateful сервисе безвозвратно менять этот самый state (например, апдейтом в базу данных), можно вести event-log изменений. Этот лог изменений можно будет накатывать на ту же базу данных и иметь ее последнюю версию, можно полностью восстановить текущее состояние с нуля, можно получить снапшот на абсолютно любой момент времени в прошлом, можно даже сделать rollout (из предположения, что у эвента будет тривиальная обратная операция). Из практических целей стоит отдельно отметить возможность ретрансляции эвентов в другие системы, например, аналитические без каких-то специальных телодвижений.
Помимо очевидных плюсов, тако подход встречается в паре с CQRS, где подобный event-log будет единым источником правды.
Но самое интересное, это, конечно, минусы. В "каноническом описании" по ссылке ниже все очень подробно расписано, я лишь остановлюсь на некоторых:
— Дороговизна. Если эвентов очень много, нужно искать трейдофы на хранение, восстановление, сохранение снапшотов.
— Усложнение кода. Получить результат из системы с event-sourcing может быть сложной задачей.
— Интеграция с сервисами, не живущие в такой же идеологии (тут рекомендуют писать обертки для таких сервисов, что тоже своего рода усложнение).
Делитесь своими комментариями, ссылками и успешными примерами использования в чате.
https://martinfowler.com/eaaDev/EventSourcing.html
https://microservices.io/patterns/data/event-sourcing.html
#pattern #microservices #practices #doc #en
https://martinfowler.com/eaaDev/EventSourcing.html
Долго думал как подступиться к этой обширной теме. Сама идея кажется просто замечательной — вместо того, чтобы в stateful сервисе безвозвратно менять этот самый state (например, апдейтом в базу данных), можно вести event-log изменений. Этот лог изменений можно будет накатывать на ту же базу данных и иметь ее последнюю версию, можно полностью восстановить текущее состояние с нуля, можно получить снапшот на абсолютно любой момент времени в прошлом, можно даже сделать rollout (из предположения, что у эвента будет тривиальная обратная операция). Из практических целей стоит отдельно отметить возможность ретрансляции эвентов в другие системы, например, аналитические без каких-то специальных телодвижений.
Помимо очевидных плюсов, тако подход встречается в паре с CQRS, где подобный event-log будет единым источником правды.
Но самое интересное, это, конечно, минусы. В "каноническом описании" по ссылке ниже все очень подробно расписано, я лишь остановлюсь на некоторых:
— Дороговизна. Если эвентов очень много, нужно искать трейдофы на хранение, восстановление, сохранение снапшотов.
— Усложнение кода. Получить результат из системы с event-sourcing может быть сложной задачей.
— Интеграция с сервисами, не живущие в такой же идеологии (тут рекомендуют писать обертки для таких сервисов, что тоже своего рода усложнение).
Делитесь своими комментариями, ссылками и успешными примерами использования в чате.
https://martinfowler.com/eaaDev/EventSourcing.html
https://microservices.io/patterns/data/event-sourcing.html
#pattern #microservices #practices #doc #en
martinfowler.com
Event Sourcing
Capture all changes to an application state as a sequence of events.
Plug-in Architecture
Имплементируя фичу за фичей вы начинаете замечать, что компоненты начинают переплетаться между собой, создавай достаточно сложные для понимания и удержания в голове зависимости. Рано или поздно это приводит к проблемам — знакома ли вам ситуация, когда только написанный код в одном месте поломал вообще, с первого взгляда, несвязанную функциональность?
Еще пример: команда начинает "раздувать" текущий код, гонясь, в первую очередь, за быстрым продуктовым результатом, мы получаем лонгрид в функциях, в файлах с кодом, который тяжело читать, невозможно поддерживать и легко сломать.
Рецепт, о котором сегодняшняя статья, предлагает подумать над организацией архитектуры приложения таким образом, чтобы изолировать ваше ядро от добавляемой функциональности.
Здесь ядро — основная функциональность вашего приложения, предоставляющая интерфейсы для расширения с помощью концепции плагинов.
Плагины — расширения, которые by design не оказывают влияние на другие плагины, не могут повредить ядро, так как оказывают влияние через безопасные интерфейсы.
Вся концепция предоставляет ряд преимуществ:
— расширяемость — концепция позволяет достаточно легко подключать новую функциональность через плагины.
— безопасность — если считать, что каждый плагин можно легко отстрелить, если он по какой-то причине не работает, то модификация плагинов не будет влиять на основную функциональность приложения.
— изолированность — плагины изолированы друг от друга и связаны с ядром через определенный интерфейс, что предотвращает губительные зависимости.
https://medium.com/omarelgabrys-blog/plug-in-architecture-dec207291800
#practices #medium #article #en
Имплементируя фичу за фичей вы начинаете замечать, что компоненты начинают переплетаться между собой, создавай достаточно сложные для понимания и удержания в голове зависимости. Рано или поздно это приводит к проблемам — знакома ли вам ситуация, когда только написанный код в одном месте поломал вообще, с первого взгляда, несвязанную функциональность?
Еще пример: команда начинает "раздувать" текущий код, гонясь, в первую очередь, за быстрым продуктовым результатом, мы получаем лонгрид в функциях, в файлах с кодом, который тяжело читать, невозможно поддерживать и легко сломать.
Рецепт, о котором сегодняшняя статья, предлагает подумать над организацией архитектуры приложения таким образом, чтобы изолировать ваше ядро от добавляемой функциональности.
Здесь ядро — основная функциональность вашего приложения, предоставляющая интерфейсы для расширения с помощью концепции плагинов.
Плагины — расширения, которые by design не оказывают влияние на другие плагины, не могут повредить ядро, так как оказывают влияние через безопасные интерфейсы.
Вся концепция предоставляет ряд преимуществ:
— расширяемость — концепция позволяет достаточно легко подключать новую функциональность через плагины.
— безопасность — если считать, что каждый плагин можно легко отстрелить, если он по какой-то причине не работает, то модификация плагинов не будет влиять на основную функциональность приложения.
— изолированность — плагины изолированы друг от друга и связаны с ядром через определенный интерфейс, что предотвращает губительные зависимости.
https://medium.com/omarelgabrys-blog/plug-in-architecture-dec207291800
#practices #medium #article #en
Medium
Plug-in Architecture
and the story of the data pipeline framework
Все, что можно сделать на бэкенде — нужно делать на бэкенде
Несколько лет назад я придерживался следующей позиции разделения ответственности между клиентов и сервером. В клиенте должно программироваться все относящееся к визуализации и пользовательскому взаимодействию: экраны, переходы, лейблы, кнопки, тексты итп, тогда как бэкенд в клиент-серверном взаимодействии должен присылать структурированные данные, которые клиент должен как-то по-своему интерпретировать. Бэкенд ничего не знает про то, как эти данные будут отображаться.
Однако, огромный минус, который перевешивает плюсы, основан на времени деплоя клиентских приложений — это негибкость конфигурирования клиента.
Давайте возьмем противоположную позицию — бэкенд все знает про клиент и отвечает за всю визуализацию. Он присылает на клиент детальную информацию об экранах, текстах, кнопках — да вообще по-максимуму. Прямо из коробки это дает возможность быстрого изменения клиентов, нивелируя весь лаг деплоя приложения в сторы. Можно проводить А/Б тестирования, даже на лету менять часть какой-то функциональности, если это позволяет ваше АПИ.
С точки зрения бэкенда все еще не очень круто сервисам, которые занимаются, например, расчетом внутренней бизнез-логики, отвечать за отображение GUI на клиентах. Но это легко решить, поставив, еще один сервис, который будет отвечать именно за упаковку бизнес-логики в формат представления GUI, понятный клиенту.
В сегодняшней заметке ссылка на видео Highload++ 2017 по теме
https://www.youtube.com/watch?v=G-AiDkZLOIs
#practices #backend #client #video #highload #youtube #ru
Несколько лет назад я придерживался следующей позиции разделения ответственности между клиентов и сервером. В клиенте должно программироваться все относящееся к визуализации и пользовательскому взаимодействию: экраны, переходы, лейблы, кнопки, тексты итп, тогда как бэкенд в клиент-серверном взаимодействии должен присылать структурированные данные, которые клиент должен как-то по-своему интерпретировать. Бэкенд ничего не знает про то, как эти данные будут отображаться.
Однако, огромный минус, который перевешивает плюсы, основан на времени деплоя клиентских приложений — это негибкость конфигурирования клиента.
Давайте возьмем противоположную позицию — бэкенд все знает про клиент и отвечает за всю визуализацию. Он присылает на клиент детальную информацию об экранах, текстах, кнопках — да вообще по-максимуму. Прямо из коробки это дает возможность быстрого изменения клиентов, нивелируя весь лаг деплоя приложения в сторы. Можно проводить А/Б тестирования, даже на лету менять часть какой-то функциональности, если это позволяет ваше АПИ.
С точки зрения бэкенда все еще не очень круто сервисам, которые занимаются, например, расчетом внутренней бизнез-логики, отвечать за отображение GUI на клиентах. Но это легко решить, поставив, еще один сервис, который будет отвечать именно за упаковку бизнес-логики в формат представления GUI, понятный клиенту.
В сегодняшней заметке ссылка на видео Highload++ 2017 по теме
https://www.youtube.com/watch?v=G-AiDkZLOIs
#practices #backend #client #video #highload #youtube #ru
YouTube
Как мы поддерживаем 100 разных версий клиентов в Badoo / Ярослав Голуб (Badoo)
Приглашаем на конференцию Saint HighLoad++ 2025, которая пройдет 23 и 24 июня в Санкт-Петербурге!
Программа, подробности и билеты по ссылке: https://highload.ru/spb/2025
________
HighLoad++ 2017
Презентация и тезисы:
http://www.highload.ru/2017/abstracts/3023.html…
Программа, подробности и билеты по ссылке: https://highload.ru/spb/2025
________
HighLoad++ 2017
Презентация и тезисы:
http://www.highload.ru/2017/abstracts/3023.html…
Code review checklist for distributed systems
https://medium.com/swlh/code-review-checklist-for-distributed-systems-b3fb94be5bfa
Автор через призму многолетнего опыта пытается обобщить требования к коду, который будет работать в продакшене в распределенной системе. Получилось весьма сумбурно, обо всем сразу, но по чуть-чуть.
Ниже краткий конспект рекомендаций в виде чеклиста:
При межсервисных запросах:
Что делать, когда запросы во внешний сервис возвращают ошибку?
— иметь ветвь обработки ошибки
— иметь сценарии восстановления после ошибки
Что делать, когда внешний сервис недоступен?
— всегда ставить таймауты на запросы
— делать какое-то явно определенное число перезапросов
— использовать circuit breaker
— не обрабатывать таймауты как ошибки
При построении сервиса, который другие сервисы будут использовать:
— все интерфейсы API должны быть идемпотентными
— явно определить времена ответа и пропускную способность
— определить и лимитировать батчевые запросы
— думать о мониторингах сервисов без потребности смотреть внутрь самих сервисов
Общие рекомендации:
— более агрессивно кэшировать
— определить единицу сбоя при ошибках
— инкапсулировать внутренние структуры сервисов и не размазывать их по системе
https://medium.com/swlh/code-review-checklist-for-distributed-systems-b3fb94be5bfa
#practices #article #microservices #en
https://medium.com/swlh/code-review-checklist-for-distributed-systems-b3fb94be5bfa
Автор через призму многолетнего опыта пытается обобщить требования к коду, который будет работать в продакшене в распределенной системе. Получилось весьма сумбурно, обо всем сразу, но по чуть-чуть.
Ниже краткий конспект рекомендаций в виде чеклиста:
При межсервисных запросах:
Что делать, когда запросы во внешний сервис возвращают ошибку?
— иметь ветвь обработки ошибки
— иметь сценарии восстановления после ошибки
Что делать, когда внешний сервис недоступен?
— всегда ставить таймауты на запросы
— делать какое-то явно определенное число перезапросов
— использовать circuit breaker
— не обрабатывать таймауты как ошибки
При построении сервиса, который другие сервисы будут использовать:
— все интерфейсы API должны быть идемпотентными
— явно определить времена ответа и пропускную способность
— определить и лимитировать батчевые запросы
— думать о мониторингах сервисов без потребности смотреть внутрь самих сервисов
Общие рекомендации:
— более агрессивно кэшировать
— определить единицу сбоя при ошибках
— инкапсулировать внутренние структуры сервисов и не размазывать их по системе
https://medium.com/swlh/code-review-checklist-for-distributed-systems-b3fb94be5bfa
#practices #article #microservices #en
Medium
Code review checklist for distributed systems
Avoid these simple coding mistakes for a stable system
Runa Capital опубликовали анализ самых быстрорастущих open source стартапов по доступным данным из гитхаба.
https://medium.com/runacapital/open-source-growth-benchmarks-and-the-20-fastest-growing-oss-startups-d3556a669fe6
#medium #opensource #startup #en
(картинка кликабельна)
https://medium.com/runacapital/open-source-growth-benchmarks-and-the-20-fastest-growing-oss-startups-d3556a669fe6
#medium #opensource #startup #en
(картинка кликабельна)
Medium
Open Source Growth Benchmarks and the 20 Fastest-Growing OSS Startups
Introduction of open-source growth benchmarks for repositories and detection the fastest-growing open-source startups using Github data
Forwarded from Teamlead Good Reads – ежедневные советы про менеджмент людей и команд (Egor Tolstoy)
Пять универсальных принципов организации системы по управлению знаниями в команде.
http://www.nickmilton.com/2020/06/5-universal-principles-for-knowledge.html
http://www.nickmilton.com/2020/06/5-universal-principles-for-knowledge.html
Nickmilton
5 universal principles for Knowledge Management
There is no universal solution for Knowledge Management in an Organisation, but there is a set of universal principles. A Management ...
How Discord Handles Two and Half Million Concurrent Voice Users using WebRTC
https://blog.discord.com/how-discord-handles-two-and-half-million-concurrent-voice-users-using-webrtc-ce01c3187429
В сегодняшней статье от 2018 года команда мессенджер Discord рассказывает про архитектуру их сервиса. Интересно с точки зрения архитектурного кейса организации коммуникации между пользователями.
Статья тезисно:
— Для клиент-серверной коммуникации используется свой собственный фреймворк поверх WebRTC.
— Бэкенд построен на трех китах - Discord Gateway, Discord Guilds и Discord Voice. Клиенты общаются с бэкендом через Discord Gateway. Discord Guilds отвечает за оркестрацию каналов общения по Voice серверам, сам Discord Voice используется непосредственно для обмена контентом между клиентами.
— Guilds серверы для каждого нового пользовательского канала с помощью того же service discovery выбирают наименее загруженный ближайший к пользователю Voice сервер.
— Voice серверы с помощью service discovery репортят свой статус и текущую нагрузку на сервер (используется etcd).
— Клиентам, подключаемым к бэкенду сообщается адрес Voice сервера, на котором живет канал и к которому будут подключаться пользователи.
— Во время отказа Voice сервера, на котором живут каналы, он перестает отправлять свой статус в service discovery, клиенты при этом уведомляются, что сервер недоступен . Guilds сервер выбирает для канала новый Voice сервер, нотифицирует всех клиентов и канал успешно переезжает на другой хост.
— Такая архитектура позволяет достаточно неплохо масштабироваться и распределять нагрузку. На момент написания статьи Discord состоит из 850 Voice серверов в 13 регионах, которые передают более чем 220 Gbps.
#practices #article #startup #en
https://blog.discord.com/how-discord-handles-two-and-half-million-concurrent-voice-users-using-webrtc-ce01c3187429
В сегодняшней статье от 2018 года команда мессенджер Discord рассказывает про архитектуру их сервиса. Интересно с точки зрения архитектурного кейса организации коммуникации между пользователями.
Статья тезисно:
— Для клиент-серверной коммуникации используется свой собственный фреймворк поверх WebRTC.
— Бэкенд построен на трех китах - Discord Gateway, Discord Guilds и Discord Voice. Клиенты общаются с бэкендом через Discord Gateway. Discord Guilds отвечает за оркестрацию каналов общения по Voice серверам, сам Discord Voice используется непосредственно для обмена контентом между клиентами.
— Guilds серверы для каждого нового пользовательского канала с помощью того же service discovery выбирают наименее загруженный ближайший к пользователю Voice сервер.
— Voice серверы с помощью service discovery репортят свой статус и текущую нагрузку на сервер (используется etcd).
— Клиентам, подключаемым к бэкенду сообщается адрес Voice сервера, на котором живет канал и к которому будут подключаться пользователи.
— Во время отказа Voice сервера, на котором живут каналы, он перестает отправлять свой статус в service discovery, клиенты при этом уведомляются, что сервер недоступен . Guilds сервер выбирает для канала новый Voice сервер, нотифицирует всех клиентов и канал успешно переезжает на другой хост.
— Такая архитектура позволяет достаточно неплохо масштабироваться и распределять нагрузку. На момент написания статьи Discord состоит из 850 Voice серверов в 13 регионах, которые передают более чем 220 Gbps.
#practices #article #startup #en
Discord
Discord Blog
Discover the latest news and app updates, stories, company insights, and plenty more about Discord, all in one place.
API Composition
https://microservices.io/patterns/data/api-composition.html
Сегодня достаточно простой, но очень полезный паттерн.
Создавая микросервисную архитектуру и соблюдая стратегию database per service, вы оказываетесь в ситуации, где для того, чтобы собрать даже самый простой, скажем, ответ для клиента, вам требуется сделать запрос в 3, 5 или даже 7 микросервисов. Такую функциональность вам, возможно, нужно даже иметь не в одном месте в коде.
На помощь приходит API Composition pattern. Его цель - скрыть за микросервисом-прокси, называемым API Composer, реализацию сбора информации по нескольким другим микросервисам.
С одной стороны, с помощью дополнительного слоя абстракции, клиенты перестают думать о том разнообразие межсервисного взаимодействия под капотом. С другой стороны, это, хотя и очень легковесная, но все же дополнительная точка отказа.
#pattern #microservices #practices #doc #en
https://microservices.io/patterns/data/api-composition.html
Сегодня достаточно простой, но очень полезный паттерн.
Создавая микросервисную архитектуру и соблюдая стратегию database per service, вы оказываетесь в ситуации, где для того, чтобы собрать даже самый простой, скажем, ответ для клиента, вам требуется сделать запрос в 3, 5 или даже 7 микросервисов. Такую функциональность вам, возможно, нужно даже иметь не в одном месте в коде.
На помощь приходит API Composition pattern. Его цель - скрыть за микросервисом-прокси, называемым API Composer, реализацию сбора информации по нескольким другим микросервисам.
С одной стороны, с помощью дополнительного слоя абстракции, клиенты перестают думать о том разнообразие межсервисного взаимодействия под капотом. С другой стороны, это, хотя и очень легковесная, но все же дополнительная точка отказа.
#pattern #microservices #practices #doc #en
microservices.io
Microservices Pattern: Pattern: API Composition
Invoke the services that own the data and perform an in-memory join
Как мы в Dropbox перешли с Nginx на Envoy
В конце прошлой недели вышла статья о том, как Dropbox перешел с Nginx на Envoy и стал одним из самых больших пользователей Envoy в мире. Значимое событие в индустрии.
Оригинальная статья: https://dropbox.tech/infrastructure/how-we-migrated-dropbox-from-nginx-to-envoy
Перевод: https://habr.com/en/company/southbridge/blog/513504/
#practices #article #backend #highload #ru #en
В конце прошлой недели вышла статья о том, как Dropbox перешел с Nginx на Envoy и стал одним из самых больших пользователей Envoy в мире. Значимое событие в индустрии.
Оригинальная статья: https://dropbox.tech/infrastructure/how-we-migrated-dropbox-from-nginx-to-envoy
Перевод: https://habr.com/en/company/southbridge/blog/513504/
#practices #article #backend #highload #ru #en
dropbox.tech
How we migrated Dropbox from Nginx to Envoy