Когда наш сервис начинает пользоваться невероятной популярностью, то количество запросов к нему от пользователей вырастет и наш сервис начнёт прилегать под нагрузкой.
Что будем делать?
- Отмасштабируем количество инстансов offer-service
- Подключим кэш
Время обработки запроса будет включать в себя время, за которое база ответит нам, что всё OK.
Что будет:
- База, скорее всего, приляжет
- Данные будут неконсистентными
Наш сервис растёт и развивается и вот уже offer-service при наступлении какого-то события должен отправлять данные в другие сервисы, чтобы что-то там инициировать.
Что в итоге получаем:
- Под каждый сервис нужно писать свой собственный клиент и обрабатывать ответы от него
- Каждый внешний сервис будет отвечать со своей собственной задержкой, по итогу наш ответ клиенту будет включать в себя все эти ожидания (при асинхронных запросах - ориентируемся на самый долгий ответ от внешнего сервиса)
- Как следствие, отвечаем пользователю медленно
- Если мы начинаем очень часто ходить во внешние сервисы, то они могут лечь под нагрузкой
А давайте вы будете делать так:
- Все свои хотелки изложите в заказном письме
- Письмо положите в специальный почтовый ящик
- Адрес почтового ящика вам дадут
- Конечного адресата вы укажете на конверте
Отправка сообщений производится с помощью единого реализованного клиента для взаимодействия с RabbitMQ. Изменяются только параметры и содержимое самого сообщения.
За счёт того, что RabbitMQ может держать в себе огромное количество сообщений, а вычитывать и обрабатывать мы можем их с той скоростью, которая комфортна нашему сервису, то проблема с нагрузкой решена.
На самом деле, всё чуть сложнее. Сначала сообщение попадает в exchange, а оттуда перенаправляется в очередь с помощью параметра routing_key.
За счёт того что очереди могут хранить в себе сообщения до тех пор, пока их не вычитывают мы можем обеспечить персистентность системы. Простыми словами, мы будем ожидать, пока потребитель сообщений подключится и сможет прочитатть свои сообщения, сколько бы их там не нападало.
Выделяют четыре типа Exchange:
- Fanout
- Direct
- Topic
- Headers
Exchange типа Fanout публикует сообщения во все очереди, в которых есть binding, игнорируя любые настройки binding (routing keys или заголовки).
Exchange типа Direct публикует сообщения во все очереди, в которых Routing Key binding полностью совпадает с Routing Key Messages.
Exchange типа Topic, похож на Direct, но поддерживает в качестве параметров binding Wildcard * и #, где
-
"*" - совпадение одного слова (слова разделяются точкой)
-
# - любое количество слов
Exchange типа Headers наиболее гибкий, но наименее производительный тип. Оперирует не Routing key, а заголовками сообщений и binding. В binding указываются ожидаемые заголовки, а также признак x-match, где
- x-match=all - необходимы все совпадения для попадания сообщения
- x-match=any - необходимо хотя бы одно совпадение