ΠΡΠΈΠ²Π΅Ρ, Π₯Π°Π±Ρ.
ΠΠ΅Π΄Π°Π²Π½ΠΎ Ρ
Π‘ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΡΠ°Π±ΠΎΡΠ°ΡΡ Π² ΠΎΡΠ΅Π½Ρ ΡΠ»ΠΎΠΆΠ½ΠΎΠΉ ΡΡΠ΅Π΄Π΅. ΠΠΈΠ·Π½Π΅Ρ-Π»ΠΎΠ³ΠΈΠΊΠ°, ΠΎΠ±Π΅ΡΠ½ΡΡΠ°Ρ Π² ΡΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΉ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΈΠΉ ΡΡΠ΅ΠΊ, ΡΠ°Π±ΠΎΡΠ°ΡΡΠ°Ρ Π² Docker-ΠΎΠ±ΡΠ°Π·Π΅, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΏΡΠ°Π²Π»ΡΠ΅ΡΡΡ ΠΎΡΠΊΠ΅ΡΡΡΠ°ΡΠΎΡΠΎΠΌ Π²ΡΠΎΠ΄Π΅ Kubernetes ΠΈΠ»ΠΈ OpenShift, ΠΈ ΠΊΠΎΠΌΠΌΡΠ½ΠΈΡΠΈΡΡΡΡΠ°Ρ Ρ Π΄ΡΡΠ³ΠΈΠΌΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡΠΌΠΈ ΠΈΠ»ΠΈ enterprise-ΡΠ΅ΡΠ΅Π½ΠΈΡΠΌΠΈ ΡΠ΅ΡΠ΅Π· ΡΠ΅ΠΏΠΎΡΠΊΡ ΡΠΈΠ·ΠΈΡΠ΅ΡΠΊΠΈΡ ΠΈ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΡΡ ΠΌΠ°ΡΡΡΡΡΠΈΠ·Π°ΡΠΎΡΠΎΠ². Π ΡΠ°ΠΊΠΎΠΌ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠΈ Π²ΡΠ΅Π³Π΄Π° ΡΡΠΎ-ΡΠΎ ΠΌΠΎΠΆΠ΅Ρ ΡΠ»ΠΎΠΌΠ°ΡΡΡΡ, ΠΏΠΎΡΡΠΎΠΌΡ ΠΏΠΎΠ²ΡΠΎΡΠ½Π°Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΡΠΎΠ±ΡΡΠΈΠΉ Π² ΡΠ»ΡΡΠ°Π΅ Π½Π΅Π΄ΠΎΡΡΡΠΏΠ½ΠΎΡΡΠΈ ΠΎΠ΄Π½ΠΎΠΉ ΠΈΠ· Π²Π½Π΅ΡΠ½ΠΈΡ ΡΠΈΡΡΠ΅ΠΌ β Π²Π°ΠΆΠ½Π°Ρ ΡΠ°ΡΡΡ Π½Π°ΡΠΈΡ Π±ΠΈΠ·Π½Π΅Ρ-ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ².
ΠΠ°ΠΊ Π±ΡΠ»ΠΎ Π΄ΠΎ Kafka
Π Π°Π½Π΅Π΅ Π² ΠΏΡΠΎΠ΅ΠΊΡΠ΅ ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΠΈ IBM MQ Π΄Π»Ρ Π°ΡΠΈΠ½Ρ ΡΠΎΠ½Π½ΠΎΠΉ Π΄ΠΎΡΡΠ°Π²ΠΊΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ. ΠΡΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ ΠΎΡΠΈΠ±ΠΊΠΈ Π² ΠΏΡΠΎΡΠ΅ΡΡΠ΅ ΡΠ°Π±ΠΎΡΡ ΡΠ΅ΡΠ²ΠΈΡΠ° ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΠΎΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠ³Π»ΠΎ Π±ΡΡΡ ΠΏΠΎΠΌΠ΅ΡΠ΅Π½ΠΎ Π² dead-letter-queue (DLQ) Π΄Π»Ρ Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅Π³ΠΎ ΡΡΡΠ½ΠΎΠ³ΠΎ ΡΠ°Π·Π±ΠΎΡΠ°. DLQ ΡΠΎΠ·Π΄Π°Π²Π°Π»ΡΡ ΡΡΠ΄ΠΎΠΌ Ρ Π²Ρ ΠΎΠ΄ΡΡΠ΅ΠΉ ΠΎΡΠ΅ΡΠ΅Π΄ΡΡ, ΠΏΠ΅ΡΠ΅ΠΊΠ»Π°Π΄ΡΠ²Π°Π½ΠΈΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΠ»ΠΎ Π²Π½ΡΡΡΠΈ IBM MQ.
ΠΡΠ»ΠΈ ΠΎΡΠΈΠ±ΠΊΠ° ΠΈΠΌΠ΅Π»Π° Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΉ Ρ Π°ΡΠ°ΠΊΡΠ΅Ρ ΠΈ ΠΌΡ ΠΌΠΎΠ³Π»ΠΈ ΡΡΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ResourceAccessException ΠΏΡΠΈ HTTP-Π²ΡΠ·ΠΎΠ²Π΅ ΠΈΠ»ΠΈ MongoTimeoutException ΠΏΡΠΈ Π·Π°ΠΏΡΠΎΡΠ΅ Π² MongoDb), ΡΠΎ Π² ΡΠΈΠ»Ρ Π²ΡΡΡΠΏΠ°Π»Π° ΡΡΡΠ°ΡΠ΅Π³ΠΈΡ ΠΏΠΎΠ²ΡΠΎΡΠ½ΡΡ Π²ΡΠ·ΠΎΠ²ΠΎΠ². ΠΠ½Π΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ Π²Π΅ΡΠ²Π»Π΅Π½ΠΈΡ Π»ΠΎΠ³ΠΈΠΊΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΏΠ΅ΡΠ΅ΠΊΠ»Π°Π΄ΡΠ²Π°Π»ΠΎΡΡ ΠΈΠ»ΠΈ Π² ΡΠΈΡΡΠ΅ΠΌΠ½ΡΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ Π΄Π»Ρ ΠΎΡΠ»ΠΎΠΆΠ΅Π½Π½ΠΎΠΉ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ, ΠΈΠ»ΠΈ Π² ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΊΠΎΠ³Π΄Π°-ΡΠΎ Π΄Π°Π²Π½ΠΎ Π±ΡΠ»ΠΎ ΡΠ΄Π΅Π»Π°Π½ΠΎ Π΄Π»Ρ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠΉ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ. ΠΡΠΈ ΡΡΠΎΠΌ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Π·Π°ΠΏΠΈΡΡΠ²Π°Π΅ΡΡΡ Π½ΠΎΠΌΠ΅Ρ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠΉ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠΈΠ²ΡΠ·Π°Π½ ΠΊ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π»Ρ Π·Π°Π΄Π΅ΡΠΆΠΊΠΈ ΠΈΠ»ΠΈ ΠΊ ΠΊΠΎΠ½ΡΡ ΡΡΡΠ°ΡΠ΅Π³ΠΈΠΈ Π½Π° ΡΡΠΎΠ²Π½Π΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΡΠ»ΠΈ ΠΌΡ Π΄ΠΎΡΡΠΈΠ³Π»ΠΈ ΠΊΠΎΠ½ΡΠ° ΡΡΡΠ°ΡΠ΅Π³ΠΈΠΈ, Π½ΠΎ Π²Π½Π΅ΡΠ½ΡΡ ΡΠΈΡΡΠ΅ΠΌΠ° Π²ΡΠ΅ Π΅ΡΠ΅ Π½Π΅Π΄ΠΎΡΡΡΠΏΠ½Π°, ΡΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠΌΠ΅ΡΠ΅Π½ΠΎ Π² DLQ Π΄Π»Ρ ΡΡΡΠ½ΠΎΠ³ΠΎ ΡΠ°Π·Π±ΠΎΡΠ°.
ΠΠΎΠΈΡΠΊ ΡΠ΅ΡΠ΅Π½ΠΈΡ
ΠΠ΅ΡΠΌΠΎΡΡΡ Π½Π° Π±ΠΎΠ»ΡΡΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΏΠΎΠ»ΠΎΠΆΠΈΡΠ΅Π»ΡΠ½ΡΡ ΠΎΡΠ·ΡΠ²ΠΎΠ², ΠΎΠ½ΠΎ ΠΊΠ°ΠΆΠ΅ΡΡΡ ΠΌΠ½Π΅ Π½Π΅ ΡΠΎΠ²ΡΠ΅ΠΌ ΡΠ΄Π°ΡΠ½ΡΠΌ. Π ΠΏΠ΅ΡΠ²ΡΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΠΏΠΎΡΠΎΠΌΡ, ΡΡΠΎ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΡ, ΠΊΡΠΎΠΌΠ΅ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π±ΠΈΠ·Π½Π΅Ρ-ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ, ΠΏΡΠΈΠ΄Π΅ΡΡΡ ΠΏΠΎΡΡΠ°ΡΠΈΡΡ ΠΌΠ½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ Π½Π° ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΎΠΏΠΈΡΠ°Π½Π½ΠΎΠ³ΠΎ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌΠ°.
ΠΡΠΎΠΌΠ΅ ΡΠΎΠ³ΠΎ, Π΅ΡΠ»ΠΈ Π½Π° Kafka-ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ Π²ΠΊΠ»ΡΡΠ΅Π½ΠΎ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ Π΄ΠΎΡΡΡΠΏΠ°ΠΌΠΈ, ΡΠΎ ΠΏΡΠΈΠ΄Π΅ΡΡΡ ΠΏΠΎΡΡΠ°ΡΠΈΡΡ ΠΊΠ°ΠΊΠΎΠ΅-ΡΠΎ Π²ΡΠ΅ΠΌΡ Π½Π° Π·Π°Π²Π΅Π΄Π΅Π½ΠΈΠ΅ ΡΠΎΠΏΠΈΠΊΠΎΠ² ΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠ΅Π½ΠΈΠ΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΡ Π΄ΠΎΡΡΡΠΏΠΎΠ² ΠΊ Π½ΠΈΠΌ. Π Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊ ΡΡΠΎΠΌΡ Π½ΡΠΆΠ½ΠΎ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠ΄Π±ΠΈΡΠ°ΡΡ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΡΠΉ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ retention.ms Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ· ΡΠ΅ΡΡΠ°ΠΉ-ΡΠΎΠΏΠΈΠΊΠΎΠ², ΡΡΠΎΠ±Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΡΡΠΏΠ΅Π²Π°Π»ΠΈ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΡΡ ΠΈ Π½Π΅ ΠΏΡΠΎΠΏΠ°Π΄Π°Π»ΠΈ ΠΈΠ· Π½Π΅Π³ΠΎ. Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΈ Π·Π°ΠΏΡΠΎΡ Π΄ΠΎΡΡΡΠΏΠΎΠ² ΠΏΡΠΈΠ΄Π΅ΡΡΡ ΠΏΠΎΠ²ΡΠΎΡΡΡΡ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠ΅Π³ΠΎ ΠΈΠ»ΠΈ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΡΠ΅ΡΠ²ΠΈΡΠ°.
ΠΠ°Π²Π°ΠΉΡΠ΅ ΡΠ΅ΠΏΠ΅ΡΡ ΠΏΠΎΡΠΌΠΎΡΡΠΈΠΌ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌΡ Π΄Π»Ρ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ Π½Π°ΠΌ spring Π² ΡΠ΅Π»ΠΎΠΌ ΠΈ spring-kafka Π² ΡΠ°ΡΡΠ½ΠΎΡΡΠΈ. Spring-kafka ΠΈΠΌΠ΅Π΅Ρ ΡΡΠ°Π½Π·ΠΈΡΠΈΠ²Π½ΡΡ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΡ Π½Π° spring-retry, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ Π°Π±ΡΡΡΠ°ΠΊΡΠΈΠΈ Π΄Π»Ρ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΡΠ°Π·Π½ΡΠΌΠΈ BackOffPolicy. ΠΡΠΎ Π΄ΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ Π³ΠΈΠ±ΠΊΠΈΠΉ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ, Π½ΠΎ Π΅Π³ΠΎ Π·Π½Π°ΡΠΈΡΠ΅Π»ΡΠ½ΡΠΌ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΊΠΎΠΌ ΡΠ²Π»ΡΠ΅ΡΡΡ Ρ ΡΠ°Π½Π΅Π½ΠΈΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ Π΄Π»Ρ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠΉ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ Π² ΠΏΠ°ΠΌΡΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΡΠΎ Π·Π½Π°ΡΠΈΡ, ΡΡΠΎ ΠΏΠ΅ΡΠ΅Π·Π°ΠΏΡΡΠΊ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΈΠ·-Π·Π° ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ ΠΈΠ»ΠΈ ΠΎΡΠΈΠ±ΠΊΠΈ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΠΊΡΠΏΠ»ΡΠ°ΡΠ°ΡΠΈΠΈ ΠΏΡΠΈΠ²Π΅Π΄Π΅Ρ ΠΊ ΠΏΠΎΡΠ΅ΡΠ΅ Π²ΡΠ΅Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ, ΠΎΠΆΠΈΠ΄Π°ΡΡΠΈΡ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ. Π’Π°ΠΊ ΠΊΠ°ΠΊ ΡΡΠΎΡ ΠΏΡΠ½ΠΊΡ ΠΊΡΠΈΡΠΈΡΠ΅Π½ Π΄Π»Ρ Π½Π°ΡΠ΅ΠΉ ΡΠΈΡΡΠ΅ΠΌΡ, ΠΌΡ Π½Π΅ ΡΡΠ°Π»ΠΈ ΡΠ°ΡΡΠΌΠ°ΡΡΠΈΠ²Π°ΡΡ Π΅Π³ΠΎ Π΄Π°Π»ΡΡΠ΅.
Π‘Π°ΠΌΠ° spring-kafka ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΉ ContainerAwareErrorHandler, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ
ΠΡΠΎΡ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΠΌΡΠΌ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌ ΠΏΠ΅ΡΠ΅ΠΆΠΈΠ²Π°ΡΡ ΡΠ΅ΡΡΠ°ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, Π½ΠΎ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌ DLQ ΠΏΠΎ-ΠΏΡΠ΅ΠΆΠ½Π΅ΠΌΡ ΠΎΡΡΡΡΡΡΠ²ΡΠ΅Ρ. ΠΠΌΠ΅Π½Π½ΠΎ ΡΡΠΎΡ Π²Π°ΡΠΈΠ°Π½Ρ ΠΌΡ Π²ΡΠ±ΡΠ°Π»ΠΈ Π² Π½Π°ΡΠ°Π»Π΅ 2019 Π³ΠΎΠ΄Π°, ΠΎΠΏΡΠΈΠΌΠΈΡΡΠΈΡΠ½ΠΎ ΠΏΠΎΠ»Π°Π³Π°Ρ, ΡΡΠΎ DLQ Π½Π΅ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡ (Π½Π°ΠΌ ΠΏΠΎΠ²Π΅Π·Π»ΠΎ ΠΈ ΠΎΠ½ Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎ Π½Π΅ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΠ»ΡΡ Π·Π° Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΌΠ΅ΡΡΡΠ΅Π² ΡΠΊΡΠΏΠ»ΡΠ°ΡΠ°ΡΠΈΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Ρ ΡΠ°ΠΊΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΠΎΠΉ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ). ΠΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΠ»ΠΈ ΠΊ ΡΡΠ°Π±Π°ΡΡΠ²Π°Π½ΠΈΡ SeekToCurrentErrorHandler. ΠΡΡΠ°Π»ΡΠ½ΡΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ ΠΏΠ΅ΡΠ°ΡΠ°Π»ΠΈΡΡ Π² Π»ΠΎΠ³, ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΠ»ΠΈ ΠΊ ΡΠΌΠ΅ΡΠ΅Π½ΠΈΡ offset, ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ°Π»Π°ΡΡ ΡΠΎ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΠΌ.
ΠΡΠΎΠ³ΠΎΠ²ΠΎΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅
Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ, ΠΎΡΠ½ΠΎΠ²Π°Π½Π½Π°Ρ Π½Π° SeekToCurrentErrorHandler, ΠΏΠΎΠ΄ΡΠΎΠ»ΠΊΠ½ΡΠ»Π° Π½Π°Ρ ΠΊ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ΅ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΠΎΠ³ΠΎ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌΠ° Π΄Π»Ρ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠΉ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ.
ΠΡΠ΅ΠΆΠ΄Π΅ Π²ΡΠ΅Π³ΠΎ ΠΌΡ Ρ ΠΎΡΠ΅Π»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΆΠ΅ ΠΈΠΌΠ΅ΡΡΠΈΠΉΡΡ ΠΎΠΏΡΡ ΠΈ ΡΠ°ΡΡΠΈΡΠΈΡΡ Π΅Π³ΠΎ Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ Π»ΠΎΠ³ΠΈΠΊΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΠ»Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Ρ Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠΉ Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ ΠΎΠΏΡΠΈΠΌΠ°Π»ΡΠ½ΡΠΌ Π±ΡΠ»ΠΎ Π±Ρ ΠΏΡΠ΅ΠΊΡΠ°ΡΠΈΡΡ ΡΡΠΈΡΡΠ²Π°Π½ΠΈΠ΅ Π½ΠΎΠ²ΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ Π² ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π½Π΅Π±ΠΎΠ»ΡΡΠΎΠ³ΠΎ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΊΠ° Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ, Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π² ΡΠ°ΠΌΠΊΠ°Ρ ΡΡΡΠ°ΡΠ΅Π³ΠΈΠΈ ΠΏΠΎΠ²ΡΠΎΡΠ½ΡΡ Π²ΡΠ·ΠΎΠ²ΠΎΠ². ΠΠ»Ρ ΠΎΡΡΠ°Π»ΡΠ½ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Ρ ΠΎΡΠ΅Π»ΠΎΡΡ ΠΈΠΌΠ΅ΡΡ Π΅Π΄ΠΈΠ½ΡΡ ΡΠΎΡΠΊΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π±Ρ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π»Π° Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΡΡΡΠ°ΡΠ΅Π³ΠΈΠΈ ΠΏΠΎΠ²ΡΠΎΡΠ½ΡΡ Π²ΡΠ·ΠΎΠ²ΠΎΠ². Π Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΡΡΠ° Π΅Π΄ΠΈΠ½Π°Ρ ΡΠΎΡΠΊΠ° Π΄ΠΎΠ»ΠΆΠ½Π° ΠΎΠ±Π»Π°Π΄Π°ΡΡ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΡΡ DLQ Π΄Π»Ρ ΠΎΠ±ΠΎΠΈΡ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΠΎΠ².
Π‘Π°ΠΌΠ° ΡΡΡΠ°ΡΠ΅Π³ΠΈΡ ΠΏΠΎΠ²ΡΠΎΡΠ½ΡΡ Π²ΡΠ·ΠΎΠ²ΠΎΠ² Π΄ΠΎΠ»ΠΆΠ½Π° Ρ ΡΠ°Π½ΠΈΡΡΡΡ Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΎΡΠ²Π΅ΡΠ°Π΅Ρ Π·Π° ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π³ΠΎ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π»Π° ΠΏΡΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΎΡΠΈΠ±ΠΊΠΈ.
ΠΡΡΠ°Π½ΠΎΠ²ΠΊΠ° Consumerβa Π΄Π»Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Ρ Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠΉ Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ
ΠΡΠΈ ΡΠ°Π±ΠΎΡΠ΅ Ρ spring-kafka ΠΊΠΎΠ΄ Π΄Π»Ρ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ Consumerβa ΠΌΠΎΠΆΠ΅Ρ Π²ΡΠ³Π»ΡΠ΄Π΅ΡΡ ΠΏΡΠΈΠΌΠ΅ΡΠ½ΠΎ ΡΠ°ΠΊ:
public void pauseListenerContainer(MessageListenerContainer listenerContainer,
Instant retryAt) {
if (nonNull(retryAt) && listenerContainer.isRunning()) {
listenerContainer.stop();
taskScheduler.schedule(() -> listenerContainer.start(), retryAt);
return;
}
// to DLQ
}
Π ΠΏΡΠΈΠΌΠ΅ΡΠ΅ retryAt β ΡΡΠΎ Π²ΡΠ΅ΠΌΡ, ΠΊΠΎΠ³Π΄Π° Π½ΡΠΆΠ½ΠΎ Π·Π°Π½ΠΎΠ²ΠΎ Π·Π°ΠΏΡΡΡΠΈΡΡ MessageListenerContainer, Π΅ΡΠ»ΠΈ ΠΎΠ½ Π΅ΡΠ΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ. ΠΠΎΠ²ΡΠΎΡΠ½ΡΠΉ Π·Π°ΠΏΡΡΠΊ ΠΏΡΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ Π² ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΠΌ ΠΏΠΎΡΠΎΠΊΠ΅, Π·Π°ΠΏΡΡΠ΅Π½Π½ΠΎΠΌ Π² TaskScheduler, ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΡΠΎΠΆΠ΅ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ spring.
ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ retryAt ΠΌΡ Π½Π°Ρ ΠΎΠ΄ΠΈΠΌ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΡΠΏΠΎΡΠΎΠ±ΠΎΠΌ:
- ΠΡΠ΅ΡΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΡΠ΅ΡΡΠΈΠΊΠ° ΠΏΠΎΠ²ΡΠΎΡΠ½ΡΡ Π²ΡΠ·ΠΎΠ²ΠΎΠ².
- Π ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠΈ ΡΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ ΡΡΠ΅ΡΡΠΈΠΊΠ° ΠΈΡΠ΅ΡΡΡ ΡΠ΅ΠΊΡΡΠΈΠΉ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π» Π·Π°Π΄Π΅ΡΠΆΠΊΠΈ Π² ΡΡΡΠ°ΡΠ΅Π³ΠΈΠΈ ΠΏΠΎΠ²ΡΠΎΡΠ½ΡΡ Π²ΡΠ·ΠΎΠ²ΠΎΠ². Π‘ΡΡΠ°ΡΠ΅Π³ΠΈΡ ΠΎΠ±ΡΡΠ²Π»ΡΠ΅ΡΡΡ Π² ΡΠ°ΠΌΠΎΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ, Π΄Π»Ρ Π΅Π΅ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ ΠΌΡ Π²ΡΠ±ΡΠ°Π»ΠΈ ΡΠΎΡΠΌΠ°Ρ JSON.
- ΠΠ°ΠΉΠ΄Π΅Π½Π½ΡΠΉ Π² JSON-ΠΌΠ°ΡΡΠΈΠ²Π΅ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π» ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π² ΡΠ΅Π±Π΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠ΅ΠΊΡΠ½Π΄, ΡΠ΅ΡΠ΅Π· ΠΊΠΎΡΠΎΡΠΎΠ΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠ²ΡΠΎΡΠΈΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ. ΠΡΠΎ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠ΅ΠΊΡΠ½Π΄ ΠΏΡΠΈΠ±Π°Π²Π»ΡΠ΅ΡΡΡ ΠΊ ΡΠ΅ΠΊΡΡΠ΅ΠΌΡ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ, ΠΎΠ±ΡΠ°Π·ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ retryAt.
- ΠΡΠ»ΠΈ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π» Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½, ΡΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ retryAt ΡΠ°Π²Π½ΠΎ null ΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΎΡΠΏΡΠ°Π²ΠΈΡΡΡ Π² DLQ Π΄Π»Ρ ΡΡΡΠ½ΠΎΠ³ΠΎ ΡΠ°Π·Π±ΠΎΡΠ°.
ΠΡΠΈ ΡΠ°ΠΊΠΎΠΌ ΠΏΠΎΠ΄Ρ ΠΎΠ΄Π΅ ΠΎΡΡΠ°Π΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΠΎΡ ΡΠ°Π½ΠΈΡΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΏΠΎΠ²ΡΠΎΡΠ½ΡΡ Π²ΡΠ·ΠΎΠ²ΠΎΠ² Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ ΡΠ΅ΠΉΡΠ°Ρ Π½Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ΅, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ Π² ΠΏΠ°ΠΌΡΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. Π‘ΠΎΡ ΡΠ°Π½Π΅Π½ΠΈΠ΅ ΡΡΠ΅ΡΡΠΈΠΊΠ° ΠΏΠΎΠΏΡΡΠΎΠΊ Π² ΠΏΠ°ΠΌΡΡΠΈ Π½Π΅ ΠΊΡΠΈΡΠΈΡΠ½ΠΎ Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ ΠΎΠ΄Π°, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠΉ Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ Π²ΡΠΏΠΎΠ»Π½ΡΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ Π² ΡΠ΅Π»ΠΎΠΌ. Π ΠΎΡΠ»ΠΈΡΠΈΠ΅ ΠΎΡ spring-retry ΠΏΠ΅ΡΠ΅Π·Π°ΠΏΡΡΠΊ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΏΡΠΈΠ²Π΅Π΄Π΅Ρ Π½Π΅ ΠΊ ΠΏΠΎΡΠ΅ΡΠ΅ Π²ΡΠ΅Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ Π΄Π»Ρ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ, Π° ΠΏΡΠΎΡΡΠΎ ΠΊ ΠΏΠ΅ΡΠ΅Π·Π°ΠΏΡΡΠΊΡ ΡΡΡΠ°ΡΠ΅Π³ΠΈΠΈ.
ΠΡΠΎΡ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ ΡΠ½ΡΡΡ Π½Π°Π³ΡΡΠ·ΠΊΡ Ρ Π²Π½Π΅ΡΠ½Π΅ΠΉ ΡΠΈΡΡΠ΅ΠΌΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π½Π΅Π΄ΠΎΡΡΡΠΏΠ½Π° ΠΈΠ·-Π·Π° ΠΎΡΠ΅Π½Ρ Π±ΠΎΠ»ΡΡΠΎΠΉ Π½Π°Π³ΡΡΠ·ΠΊΠΈ. ΠΡΡΠ³ΠΈΠΌΠΈ ΡΠ»ΠΎΠ²Π°ΠΌΠΈ, Π² Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ΅ ΠΌΡ Π΄ΠΎΠ±ΠΈΠ»ΠΈΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΏΠ°ΡΡΠ΅ΡΠ½Π°
Π Π½Π°ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΏΠΎΡΠΎΠ³ ΠΎΡΠΈΠ±ΠΊΠΈ ΡΠ°Π²Π΅Π½ Π²ΡΠ΅Π³ΠΎ 1, Π° ΡΡΠΎΠ±Ρ ΠΌΠΈΠ½ΠΈΠΌΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΠΏΡΠΎΡΡΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΡ ΠΈΠ·-Π·Π° Π²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΠ΅ΡΠ΅Π²ΠΎΠ³ΠΎ ΠΏΠ΅ΡΠ΅Π±ΠΎΡ, ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΠΎΡΠ΅Π½Ρ Π³ΡΠ°Π½ΡΠ»ΡΡΠ½ΡΡ ΡΡΡΠ°ΡΠ΅Π³ΠΈΡ ΠΏΠΎΠ²ΡΠΎΡΠ½ΡΡ Π²ΡΠ·ΠΎΠ²ΠΎΠ² Ρ Π½Π΅Π±ΠΎΠ»ΡΡΠΈΠΌΠΈ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π»Π°ΠΌΠΈ Π·Π°Π΄Π΅ΡΠΆΠΊΠΈ. ΠΡΠΎ ΠΌΠΎΠΆΠ΅Ρ Π½Π΅ ΠΏΠΎΠ΄ΠΎΠΉΡΠΈ Π΄Π»Ρ Π²ΡΠ΅Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π³ΡΡΠΏΠΏΡ ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΉ, ΠΏΠΎΡΡΠΎΠΌΡ ΡΠΎΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρ ΠΏΠΎΡΠΎΠ³ΠΎΠΌ ΠΎΡΠΈΠ±ΠΊΠΈ ΠΈ Π²Π΅Π»ΠΈΡΠΈΠ½ΠΎΠΉ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π»Π° Π½ΡΠΆΠ½ΠΎ ΠΏΠΎΠ΄Π±ΠΈΡΠ°ΡΡ, ΠΎΠΏΠΈΡΠ°ΡΡΡ Π½Π° ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΠΈ ΡΠΈΡΡΠ΅ΠΌΡ.
ΠΡΠ΄Π΅Π»ΡΠ½ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΎΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Ρ Π½Π΅Π΄Π΅ΡΠ΅ΡΠΌΠΈΠ½ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ
ΠΠΎΡ ΠΏΡΠΈΠΌΠ΅Ρ ΠΊΠΎΠ΄Π°, ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΠ΅Π³ΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π² ΡΠ°ΠΊΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ (Retryer), ΠΊΠΎΡΠΎΡΠΎΠ΅ Π²ΡΠΏΠΎΠ»Π½ΠΈΡ ΠΏΠΎΠ²ΡΠΎΡΠ½ΡΡ ΠΎΡΠΏΡΠ°Π²ΠΊΡ Π² ΡΠΎΠΏΠΈΠΊ DESTINATION ΠΏΡΠΈ Π΄ΠΎΡΡΠΈΠΆΠ΅Π½ΠΈΠΈ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ RETRY_AT:
public <K, V> void retry(ConsumerRecord<K, V> record, String retryToTopic,
Instant retryAt, String counter, String groupId, Exception e) {
Headers headers = ofNullable(record.headers()).orElse(new RecordHeaders());
List<Header> arrayOfHeaders =
new ArrayList<>(Arrays.asList(headers.toArray()));
updateHeader(arrayOfHeaders, GROUP_ID, groupId::getBytes);
updateHeader(arrayOfHeaders, DESTINATION, retryToTopic::getBytes);
updateHeader(arrayOfHeaders, ORIGINAL_PARTITION,
() -> Integer.toString(record.partition()).getBytes());
if (nonNull(retryAt)) {
updateHeader(arrayOfHeaders, COUNTER, counter::getBytes);
updateHeader(arrayOfHeaders, SEND_TO, "retry"::getBytes);
updateHeader(arrayOfHeaders, RETRY_AT, retryAt.toString()::getBytes);
} else {
updateHeader(arrayOfHeaders, REASON,
ExceptionUtils.getStackTrace(e)::getBytes);
updateHeader(arrayOfHeaders, SEND_TO, "backout"::getBytes);
}
ProducerRecord<K, V> messageToSend =
new ProducerRecord<>(retryTopic, null, null, record.key(), record.value(), arrayOfHeaders);
kafkaTemplate.send(messageToSend);
}
ΠΠ· ΠΏΡΠΈΠΌΠ΅ΡΠ° Π²ΠΈΠ΄Π½ΠΎ, ΡΡΠΎ ΠΌΠ½ΠΎΠ³ΠΎ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΡΡΡ Π² Ρ Π΅Π΄Π΅ΡΠ°Ρ . ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ RETRY_AT Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ ΡΠ°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΈ Π΄Π»Ρ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌΠ° ΠΏΠΎΠ²ΡΠΎΡΠ° ΡΠ΅ΡΠ΅Π· ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΡ Consumerβa. ΠΠΎΠΌΠΈΠΌΠΎ DESTINATION ΠΈ RETRY_AT ΠΌΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΠΌ:
- GROUP_ID, ΠΏΠΎ ΠΊΠΎΡΠΎΡΠΎΠΌΡ Π³ΡΡΠΏΠΏΠΈΡΡΠ΅ΠΌ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Π΄Π»Ρ ΡΡΡΠ½ΠΎΠ³ΠΎ Π°Π½Π°Π»ΠΈΠ·Π° ΠΈ ΡΠΏΡΠΎΡΠ΅Π½ΠΈΡ ΠΏΠΎΠΈΡΠΊΠ°.
- ORIGINAL_PARTITION, ΡΡΠΎΠ±Ρ ΠΏΠΎΡΡΠ°ΡΠ°ΡΡΡΡ ΡΠΎΡ ΡΠ°Π½ΠΈΡΡ ΡΠΎΡ ΠΆΠ΅ Consumer Π΄Π»Ρ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ. ΠΡΠΎΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΠ°Π²Π΅Π½ null, Π² ΡΠ°ΠΊΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Π½ΠΎΠ²Π°Ρ partition Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½Π° ΠΏΠΎ ΠΊΠ»ΡΡΡ record.key() ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ.
- ΠΠ±Π½ΠΎΠ²Π»Π΅Π½Π½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ COUNTER, ΡΡΠΎΠ±Ρ ΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΡ ΡΡΡΠ°ΡΠ΅Π³ΠΈΠΈ ΠΏΠΎΠ²ΡΠΎΡΠ½ΡΡ Π²ΡΠ·ΠΎΠ²ΠΎΠ².
- SEND_TO β ΠΊΠΎΠ½ΡΡΠ°Π½ΡΠ°, ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°ΡΡΠ°Ρ, ΠΎΡΠΏΡΠ°Π²ΠΈΡΡ Π»ΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π½Π° ΠΏΠΎΠ²ΡΠΎΡΠ½ΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ ΠΏΠΎ Π΄ΠΎΡΡΠΈΠΆΠ΅Π½ΠΈΠΈ RETRY_AT ΠΈΠ»ΠΈ ΠΏΠΎΠΌΠ΅ΡΡΠΈΡΡ Π² DLQ.
- REASON β ΠΏΡΠΈΡΠΈΠ½Π°, ΠΏΠΎ ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Π±ΡΠ»Π° ΠΏΡΠ΅ΡΠ²Π°Π½Π°.
Retryer ΡΠΎΡ ΡΠ°Π½ΡΠ΅Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Π΄Π»Ρ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠΉ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΠΈ ΡΡΡΠ½ΠΎΠ³ΠΎ ΡΠ°Π·Π±ΠΎΡΠ° Π² PostgreSQL. ΠΠΎ ΡΠ°ΠΉΠΌΠ΅ΡΡ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΡΡΡ Π·Π°Π΄Π°ΡΠ°, ΠΊΠΎΡΠΎΡΠ°Ρ Π½Π°Ρ ΠΎΠ΄ΠΈΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Ρ Π½Π°ΡΡΡΠΏΠΈΠ²ΡΠΈΠΌ RETRY_AT ΠΈ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅Ρ ΠΈΡ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ Π² ΠΏΠ°ΡΡΠΈΡΠΈΡ ORIGINAL_PARTITION ΡΠΎΠΏΠΈΠΊΠ° DESTINATION Ρ ΠΊΠ»ΡΡΠΎΠΌ record.key().
ΠΠΎΡΠ»Π΅ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΡΠ΄Π°Π»ΡΡΡΡΡ ΠΈΠ· PostgreSQL. Π ΡΡΠ½ΠΎΠΉ ΡΠ°Π·Π±ΠΎΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ Π² ΠΏΡΠΎΡΡΠΎΠΌ UI, ΠΊΠΎΡΠΎΡΡΠΉ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΡΠ΅Ρ Ρ Retryer ΠΏΠΎ REST API. ΠΡΠ½ΠΎΠ²Π½ΡΠΌΠΈ Π΅Π³ΠΎ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΡΠΌΠΈ ΡΠ²Π»ΡΡΡΡΡ ΠΏΠ΅ΡΠ΅ΠΎΡΠΏΡΠ°Π²ΠΊΠ° ΠΈΠ»ΠΈ ΡΠ΄Π°Π»Π΅Π½ΠΈΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΈΠ· DLQ, ΠΏΡΠΎΡΠΌΠΎΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ ΠΎΠ± ΠΎΡΠΈΠ±ΠΊΠ΅ ΠΈ ΠΏΠΎΠΈΡΠΊ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ ΠΎΡΠΈΠ±ΠΊΠΈ.
Π’Π°ΠΊ ΠΊΠ°ΠΊ Π½Π° Π½Π°ΡΠΈΡ ΠΊΠ»Π°ΡΡΠ΅ΡΠ°Ρ Π²ΠΊΠ»ΡΡΠ΅Π½ΠΎ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ Π΄ΠΎΡΡΡΠΏΠΎΠΌ, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎ Π·Π°ΠΏΡΠ°ΡΠΈΠ²Π°ΡΡ Π΄ΠΎΡΡΡΠΏΡ ΠΊ ΡΠΎΠΏΠΈΠΊΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠ»ΡΡΠ°Π΅Ρ Retryer, ΠΈ Π΄Π°ΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ RetryerβΡ ΠΏΠΈΡΠ°ΡΡ Π² DESTINATION ΡΠΎΠΏΠΈΠΊ. ΠΡΠΎ Π½Π΅ΡΠ΄ΠΎΠ±Π½ΠΎ, Π½ΠΎ, Π² ΠΎΡΠ»ΠΈΡΠΈΠ΅ ΠΎΡ ΠΏΠΎΠ΄Ρ ΠΎΠ΄Π° Ρ ΡΠΎΠΏΠΈΠΊΠΎΠΌ Π½Π° ΠΈΠ½ΡΠ΅ΡΠ²Π°Π», Ρ Π½Π°Ρ ΠΏΠΎΡΠ²Π»ΡΠ΅ΡΡΡ ΠΏΠΎΠ»Π½ΠΎΡΠ΅Π½Π½Π°Ρ DLQ ΠΈ UI Π΄Π»Ρ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Π΅Ρ.
ΠΡΠ²Π°ΡΡ ΡΠ»ΡΡΠ°ΠΈ, ΠΊΠΎΠ³Π΄Π° Π²Ρ ΠΎΠ΄ΡΡΠΈΠΉ ΡΠΎΠΏΠΈΠΊ ΡΠΈΡΠ°ΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ°Π·Π½ΡΡ consumer-Π³ΡΡΠΏΠΏ, ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΊΠΎΡΠΎΡΡΡ ΡΠ΅Π°Π»ΠΈΠ·ΡΡΡ ΡΠ°Π·Π½ΡΡ Π»ΠΎΠ³ΠΈΠΊΡ. ΠΠΎΠ²ΡΠΎΡΠ½Π°Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΡΠ΅ΡΠ΅Π· Retryer Π΄Π»Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· ΡΠ°ΠΊΠΈΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΏΡΠΈΠ²Π΅Π΄Π΅Ρ ΠΊ Π΄ΡΠ±Π»ΠΈΠΊΠ°ΡΡ Π½Π° Π΄ΡΡΠ³ΠΎΠΌ. Π§ΡΠΎΠ±Ρ Π·Π°ΡΠΈΡΠΈΡΡΡΡ ΠΎΡ ΡΡΠΎΠ³ΠΎ, ΠΌΡ Π·Π°Π²ΠΎΠ΄ΠΈΠΌ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΡΠΎΠΏΠΈΠΊ Π΄Π»Ρ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ. ΠΡ ΠΎΠ΄ΡΡΠΈΠΉ ΠΈ retry-ΡΠΎΠΏΠΈΠΊ ΠΌΠΎΠΆΠ΅Ρ ΡΠΈΡΠ°ΡΡ ΠΎΠ΄ΠΈΠ½ ΠΈ ΡΠΎΡ ΠΆΠ΅ Consumer Π±Π΅Π· ΠΊΠ°ΠΊΠΈΡ -Π»ΠΈΠ±ΠΎ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠΉ.
ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ΡΡΠΎΡ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ Π½Π΅ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ circuit breakerβa, ΠΎΠ΄Π½Π°ΠΊΠΎ Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ
ΠΡΠ²ΠΎΠ΄
Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ Ρ Π½Π°Ρ ΠΏΠΎΠ»ΡΡΠΈΠ»ΠΎΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΏΠΎΠ²ΡΠΎΡΠΈΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΏΡΠΈ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π½Π΅Π΄ΠΎΡΡΡΠΏΠ½ΠΎΡΡΠΈ ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ Π²Π½Π΅ΡΠ½Π΅ΠΉ ΡΠΈΡΡΠ΅ΠΌΡ.
ΠΠ΄Π½ΠΈΠΌ ΠΈΠ· Π³Π»Π°Π²Π½ΡΡ ΠΏΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΎ, ΡΡΠΎ ΠΈΠΌ ΠΌΠΎΠ³ΡΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π²Π½Π΅ΡΠ½ΠΈΠ΅ ΡΠΈΡΡΠ΅ΠΌΡ, ΡΠ°Π±ΠΎΡΠ°ΡΡΠΈΠ΅ Π½Π° ΡΠΎΠΌ ΠΆΠ΅ Kafka-ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅, Π±Π΅Π· Π·Π½Π°ΡΠΈΡΠ΅Π»ΡΠ½ΡΡ Π΄ΠΎΡΠ°Π±ΠΎΡΠΎΠΊ Π½Π° ΡΠ²ΠΎΠ΅ΠΉ ΡΡΠΎΡΠΎΠ½Π΅! Π’Π°ΠΊΠΎΠΌΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π±ΡΠ΄Π΅Ρ ΡΠΎΠ»ΡΠΊΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊ retry-ΡΠΎΠΏΠΈΠΊΡ, Π·Π°ΠΏΠΎΠ»Π½ΠΈΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Kafka-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² ΠΈ ΠΎΡΠΏΡΠ°Π²ΠΈΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π² Retryer. ΠΠ΅ Π½ΡΠΆΠ½ΠΎ ΠΏΠΎΠ΄Π½ΠΈΠΌΠ°ΡΡ Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎΠΉ ΠΈΠ½ΡΡΠ°ΡΡΡΡΠΊΡΡΡΡ. Π ΡΡΠΎΠ±Ρ ΡΠΌΠ΅Π½ΡΡΠΈΡΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΏΠ΅ΡΠ΅ΠΊΠ»Π°Π΄ΡΠ²Π°Π΅ΠΌΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΈΠ· ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π² Retryer ΠΈ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ, ΠΌΡ Π²ΡΠ΄Π΅Π»ΠΈΠ»ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Ρ Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠΉ Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ ΠΈ ΡΠ΄Π΅Π»Π°Π»ΠΈ Π² Π½ΠΈΡ ΠΏΠΎΠ²ΡΠΎΡΠ½ΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ ΡΠ΅ΡΠ΅Π· ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΡ Consumer.
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com