На текущий момент у нас нет проблем с продакшном (все работает), но я предвижу проблемы при большой нагрузке (в частности, из-за использования протокола http с большим оверхедом) и хотелось бы придти к решению лучшему.
В отпуске у меня появилось время подумать как лучше организовать взаимодействие между сервисами. Я изучил современные архитектуры и протоколы, сделал определенные выводы (незаполненную табличку я вам кидал по-моему, а может и нет :), в результате у меня родилась идея фреймворка со следующими характеристиками:
- максимально простой протокол чтобы его можно было реализовать под любой язык
- с поддержкой версионирования для возможности переключения между сервисами рабочими
- из коробки всякие балансировки, загрузки и прочее что требуется для современных сервисов
- обязательна работа в двух режимах: посылке команд напрямую другим сервисам ("вопрос-ответ") и подписка на события от других сервесов ("событийно-ориентированая система")
Основную идею я взял отсюда
https://runnable.com/blog/event-driven-microservices-using-rabbitmq но расширил добавив дополнительный транспорт (преимущества добавления транспорта опишу в конце):
В фреймворке существует три типа передачи данных:
1) Таски: действия которые модифицируют состояние, могут выполняться только внутри одного сервиса (важно: не в одном процессе, а в одном из процессов одного сервиса - они могут и будут размазаны по разным компьютерам). То есть, когда надо выполнить задачу она посылается в очередь и первый процесс сервиса который свободен берет ее и выполняет.
2) События: по факту выполнения таски генерируется событие на который может быть подписан _любой_ сервис.
3) Внешние запросы: когда сервису нужно получить данные от другого сервиса он генерирует внешний запрос к тому сервису. А тот сервис скорее всего запустит таску которая обработает этот запрос, но это необязательно.
Первые два типа реализуются через один из событийно-ориентированных протоколов: amqp, mqtt, или даже redis pub/sub. Третий тип может использовать gRPC, REST, graphQL, amqp и все что угодно. Все это выбирается плагинами (реализован будет только amqp для тасков/событий и gRPC для внешних запросов).
Специально не буду описывать почему выбраны эти транспорты, какие преимущества и недостатки, как будет достигаться версионность и прочее. Если дойдем до этого и будет интересно то распишу, пока лишь просто хочу узнать мнение об общей концепции.