У меня есть следующая архитектура:
- 3 docker узлов, работающих на docker рое
- один сервер rabbitmq в качестве службы, работающей на этом рое
- один процесс (Pro c N на рисунке) на каждом узле в качестве потребителя
- один процесс (Proc0 на рисунке), выполняющий функции массового производителя сообщений, которые должны быть использованы
Proc0 создает приблизительно 150 тыс. Сообщений и отправляет их в экземпляр rabbitmq, который используется в качестве стека или очереди. Каждый Pro c N прослушивает сообщения и обрабатывает их. В результате обработки получается в среднем 150-250 записей, которые хранятся в таблице базы данных (IBM DB / 2) и работают на выделенном хосте (AIX).
Я использую Spring Boot AMQP для обработки сообщений и JPA / hibernate для доступа к базе данных.
Конфигурация rabbitmq довольно проста
spring.rabbitmq.listener.type=direct
spring.rabbitmq.listener.direct.consumers-per-queue=15
Вот архитектурное изображение:
После запуска процесса (то есть запуска Proc0 для создания сообщений) все выглядит нормально, пропускная способность (измеряемая состоянием исполнительного механизма Springboot и прометеем) возрастает до определенной точки. Однако: после этой определенной точки пропускная способность снижается до скудной доли того, что было на старте:
Та же картина применяется с более / меньше сообщений и / или больше / меньше потребителей в очереди на хост.
В целевой базе данных есть столбец @Id
с его сгенерированными значениями из последовательности базы данных.
Для меня это Похоже, я страдаю от истощения потоков от каждого про c N .
У меня есть несколько вопросов:
- Как Hibernate обрабатывает генерирует ли последовательность значений идентификаторов (целевой таблицы) в многопоточной среде?
- Они синхронизированы (я так полагаю)?
И если да, то поможет ли использование идентификатора, сгенерированного базой данных?
Как получить метрики или меры для точного определения причины истощения потока?
- Существуют ли "лучшие практики", как решать такие проблемы?