áá±áž áá¬á
áááŒá¬áá±ážáá®á áá»áœááºáá±á¬áº
áá±ááºáá®á¡ááºááºáá®áá±ážááŸááºážáá»á¬ážááẠá¡ááœááºááŸá¯ááºááœá±ážáá±á¬áááºáááºážáá»ááºááœáẠáá¯ááºáá±á¬ááºáááºá Kubernetes ááá¯á·ááá¯áẠOpenShift áá²á·ááá¯á·áá±á¬ áá¶á á¯á¶áá®ážááá¯ááºážá០á á®áá¶ááá·áºááœá²áá±á¬ Docker áá¯á¶ááœáẠáá¯ááºáá±á¬ááºáá±ááá·áº áá±ááºáá®áááºážááá¬á¡á á¯á¡áá±ážáá áºáá¯ááœáẠá á®ážááœá¬ážáá±ážááá¯ááºáᬠáá¯áá¹áááá±áááá¯ááºáᬠáá¯áá¹áááá±áááŒáá·áº áá¯ááºááá¯ážáá¬ážááŒá®áž áá¯ááºááá¯ááºážááá¯ááºáá¬ááŸáá·áº á¡áá¯á¡áá±á¬áẠrouter áá»á¬ážá ááœááºážáááºáá»á¬ážááŸáá áºááá·áº á¡ááŒá¬ážáá±á¬ á¡ááá®áá±ážááŸááºážáá»á¬ážááŸáá·áº áá¯ááºáááºážááŒá±ááŸááºážáá»ááºáá»á¬ážááŸáá·áº áááºááœááºááŒááºážá ááá¯ááá¯á·áá±á¬áááºáááºážáá»ááºááœááºá áá áºá á¯á¶áá áºáá¯ááẠá¡ááŒá²áááºážááŒáá¯ááœá²ááœá¬ážááá¯ááºáááºá ááá¯á·ááŒá±á¬áá·áº ááŒááºáá áá áºáá»á¬ážáá²ááŸáá áºáá¯ááááŸáááá¯ááºáá«á ááŒá áºáááºáá»á¬ážááᯠááŒááºáááºáá¯ááºáá±á¬ááºááŒááºážááẠáá»áœááºá¯ááºááá¯á·ááá¯ááºáááºážáá¯ááºáááºážá ááºáá»á¬ážá á¡áá±ážááŒá®ážáá±á¬á¡á áááºá¡ááá¯ááºážáá áºáá¯ááŒá áºáááºá
Kafka áááá¯ááºáááºá áááºááá¯áá²á
ááá±á¬áá»ááºááœáẠá¡á á±á¬ááá¯ááºážááœáẠáá»áœááºá¯ááºááá¯á·ááẠá¡ááŒáá¯ááºá¡ááá¯áẠáááºáá±á·áá»áºáá±ážááá¯á·áááºá¡ááœáẠIBM MQ ááᯠá¡áá¯á¶ážááŒá¯áá²á·áááºá áááºáá±á¬ááºááŸá¯áá¯ááºáá±á¬ááºáá±á ááºá¡ááœááºáž á¡ááŸá¬ážá¡ááœááºážáá áºá á¯á¶áá áºáᬠááŒá áºáá±á«áºáá²á·áá«áá áááºáá¶áááŸááá¬ážáá±á¬ áááºáá±á·áá»áºááᯠáá±á¬ááºáááºáá°ááá¯ááºááá¯áẠááœá²ááŒááºážá áááºááŒá¬áááºá¡ááœáẠdead-letter-queue (DLQ) ááœáẠáá¬ážááŸáááá¯ááºáá«áááºá DLQ ááᯠáááºáá¬ááá·áº áááºážá á®áá±ážááœáẠáááºáá®ážáá¬ážááŒá®ážá áááºáá±á·áá»áºááᯠIBM MQ á¡ááœááºážááá¯á· ááœáŸá²ááŒá±á¬ááºážáá¬ážáááºá
á¡ááŸá¬ážá¡ááœááºážááẠáá¬áá®ááŒá áºááŒá®áž áááºážááᯠáá»áœááºá¯ááºááá¯á· áá¯á¶ážááŒááºááá¯ááºáááºááá¯áá«á (á¥ááá¬á HTTP áá±á«áºááá¯ááŸá¯ááœáẠResourceAccessException ááá¯á·ááá¯áẠMongoDb áá±á¬ááºážááá¯ááŸá¯áá áºáá¯áá±á«áºááŸá MongoTimeoutException)á ááá¯á·áá±á¬áẠááŒááºáááºááŒáá¯ážá á¬ážááŸá¯áá»á°áá¬ááẠá¡áááºáááºáááºááŒá áºáááºá á¡ááá®áá±ážááŸááºážá á¡ááá¯ááºážá¡ááẠáá¯áá¹áááááœá²ááŒá¬ážáá² áá°áááºážáááºáá±á·áá»áºááᯠááŸá±á¬áá·áºááŸá±ážáá±ážááá¯á·ááŒááºážá¡ááœáẠá áá áºáááºážá á® ááá¯á·ááá¯áẠáááºáá±á·áá»áºáá»á¬áž ááŒááºáááºáá±ážááá¯á·áááºá¡ááœáẠááááºá ááŒá¯áá¯ááºáá¬ážááá·áº áá®ážááŒá¬ážá¡ááºááºáá áºáá¯ááá¯á· ááœáŸá±á·áá¬ážáááºá áááºážááœáẠááŸá±á¬áá·áºááŸá±ážááá·áºááŒá¬ážáá¬á ááá¯á·ááá¯áẠá¡ááºááºá¡ááá·áºáááºážáá»á°áá¬áá¡áá¯á¶ážááŸáá·áº áá»áááºáááºáá¬ážááá·áº áááºáá±á·áá»áºáá±á«ááºážá á®ážááœáẠááŒááºáááºáá±ážááá¯á·ááá·áºáá¶áá«ááºáá áºáᯠáá«áááºáááºá áá»áœááºá¯ááºááá¯á·ááẠáááºážáá»á°áá¬áá¡áá¯á¶ážááá¯á·áá±á¬ááºááŸáááœá¬ážáá±á¬áºáááºáž ááŒááºáá áá áºááẠááááŸáááá¯ááºáá±ážáá«áá áááºážááᯠááá¯ááºááá¯ááºááœá²ááŒááºážá áááºááŒá¬áááºá¡ááœáẠDLQ ááœáẠáááºáá±á·áá»áºááᯠáá¬ážááŸááááºááŒá áºáááºá
á¡ááŒá±ááŸá¬ááŒááºáž
á¡ááŒá¯ááá±á¬áá±á¬ááºáá±á¬ áá¯á¶ážáááºáá»ááºáá»á¬áž á¡áá»á¬ážá¡ááŒá¬ážááŸááá±á¬áºáááºážá áá»áœááºá¯ááºááẠáá¯á¶ážá áá¡á±á¬ááºááŒááºáᯠáá°ááá«áááºá ááááŠážá áœá¬á á¡áááºááŒá±á¬áá·áºááá¯áá±á¬áº developer ááẠáá¯ááºáááºážááá¯á¡ááºáá»ááºáá»á¬ážááᯠá¡áá±á¬ááºá¡ááẠáá±á¬áºááŒááºážá¡ááŒáẠáá±á¬áºááŒáá¬ážáá±á¬ ááá¹ááá¬ážá¡á¬áž á¡áá±á¬ááºá¡áááºáá±á¬áºáá¬ááœáẠá¡áá»áááºáá»á¬ážá áœá¬ áá¯á¶ážá áœá²ááá±á¬ááŒá±á¬áá·áº ááŒá áºáááºá
ááá¯á·á¡ááŒááºá Kafka á¡á á¯á¡áá±ážááœáẠáááºáá±á¬ááºááááºážáá»á¯ááºááŸá¯ááᯠááœáá·áºáá¬ážáá«áá áááºááẠá¡ááŒá±á¬ááºážá¡áá¬áá»á¬ážáááºáá®ážááŒááºážááŸáá·áº áááºážááá¯á·áᶠááá¯á¡ááºáá±á¬áááºáá±á¬ááºááœáá·áºááᯠáá±ážá¡ááºááẠá¡áá»áááºá¡áááºážáááºáá°ááááºááŒá áºáá«áááºá áááºážá¡ááŒááºá áááºááẠááŒááºá ááºážááŒáá·áºááá·áºá¡ááŒá±á¬ááºážá¡áá¬áá áºáá¯á á®á¡ááœáẠááŸááºáááºáá±á¬ retention.ms áá«áá¬áá®áá¬ááᯠááœá±ážáá»ááºááẠááá¯á¡ááºáááºááŒá áºáááºá ááá¯á·ááŸáᬠáááºáá±á·áá»áºáá»á¬áž ááŒááºáááºáá¬áááºáááẠá¡áá»áááºááŸáááŒá®áž áááºážá០áá»á±á¬ááºááœááºááœá¬ážááŒááºážáááŸáá á±ááá«á áááºááŸá ááá¯á·ááá¯áẠá¡áá áºáááºáá±á¬ááºááŸá¯áá áºáá¯á á®á¡ááœáẠá¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááŸáá·áº á¡áá¯á¶ážááŒá¯ááœáá·áºáá±á¬ááºážááá¯ááŸá¯ááá¯á·ááᯠáááºáá«ááá²áá² ááŒá¯áá¯ááºááááºááŒá áºáááºá
áá±áá°áá»á¡á¬ážááŒáá·áº ááœááºáá±á«áºáá¬ááá·áº ááá¹ááá¬ážáá»á¬ážááŸáá·áº á¡áá°ážáááŒáá·áº áááºáá±á·áá»áºááŒááºáááºáá¯ááºáá±á¬ááºááŒááºážá¡ááœáẠáá»áœááºá¯ááºááá¯á·ááᯠá¡áá°ážá¡á¬ážááŒáá·áº Spring-kafka áá±ážáá±á¬ááºáááºááᯠááá¯ááŒáá·áºááŒáá«á áá¯á·á Spring-kafka ááœáẠááá°áá®áá±á¬ BackOffPolicies áá»á¬ážááᯠá á®áá¶ááá·áºááœá²áááºá¡ááœáẠabstractions áá»á¬ážááᯠáá¶á·ááá¯ážáá±ážáá±á¬ spring-retry ááœáẠá¡áá°ážá¡ááŒá±á¬ááºáž ááŸá®ááá¯ááŸá¯ááŸááá«áááºá áááºážááẠáá»áŸáá»áŸáá ááŒá±á¬ááºážááœááºááŒááºááœááºááŸááá±á¬ áá°ážááºáá áºáá¯ááŒá áºáá±á¬áºáááºáž áááºážá áááá¬áááºááŸá¬ážáá±á¬ á¡á¬ážáááºážáá»ááºááŸá¬ á¡ááá®áá±ážááŸááºážááŸááºáá¬ááºááœáẠááŒááºáááºáá±ážááá¯á·áááºá¡ááœáẠá á¬áá»á¬ážááᯠááááºážáááºážááŒááºážááŒá áºáááºá ááá¯ááá¯áááºááŸá¬ á¡ááºááááºáá áºáᯠááá¯á·ááá¯áẠáá¯ááºáááºážáááºáááºááŸá¯ááá¯ááºáᬠá¡ááŸá¬ážáá áºáá¯ááŒá±á¬áá·áº á¡ááá®áá±ážááŸááºážááᯠááŒááºáááºá áááºááŒááºážááŸá¬ ááŒááºáááºáá¯ááºáá±á¬ááºááŒááºážááᯠááá¯ááºážáá¶á·áá¬ážááá·áº áááºáá±á·áá»áºáá»á¬ážá¡á¬ážáá¯á¶áž áá¯á¶ážááŸá¯á¶ážááœá¬ážáááºááŒá áºáááºá á€á¡áá»ááºááẠáá»áœááºá¯ááºááá¯á·áá áá áºá¡ááœáẠá¡áá±ážááŒá®ážáá±á¬ááŒá±á¬áá·áºá áá»áœááºá¯ááºááá¯á·ááẠáááºážááᯠáá±á¬ááºáááºáá ááºážá á¬ážáá²á·áá«á
spring-kafka ááá¯ááºááá¯ááºá ContainerAwareErrorHandler á á¡áá±á¬ááºá¡áááºáá±á¬áºáá±á¬ááºááœááºááŸá¯áá»á¬ážá
áœá¬ááᯠá¥ááá¬áá±ážáá«áááºá
á€áááºážáááºážááẠá¡ááá®áá±ážááŸááºážááŒááºáááºá áááºááŒááºážáá»á¬ážááᯠááŒááºáááºáá¯ááºáá±á¬ááºááŒá®áž áááºáá±á·áá»áºáá»á¬ážááᯠááŒááºáááºáá¯ááºáá±á¬ááºááá¯ááºá á±áá±á¬áºáááºáž DLQ ááá¹ááá¬ážáááŸááá±ážáá«á DLQ áááá¯á¡ááºáᯠá¡áá±á¬ááºážááŒááºá áááºááŒáá·áº 2019 áá¯ááŸá áºá¡á ááœáẠá€ááœá±ážáá»ááºááŸá¯ááᯠááœá±ážáá»ááºáá²á·ááẠ(áá»áœááºá¯ááºááá¯á·ááẠáá¶áá±á¬ááºážáá²á·ááŒá®áž áááºážáá²á·ááá¯á· ááŒááºáááºáá¯ááºáá±á¬ááºááá·áºá áá áºááŒáá·áº á¡ááá®áá±ážááŸááºážááᯠáá¡áá±á¬áºááŒá¬áááºáááºááŒá®ážáá±á¬áẠáááºážááᯠáááá¯á¡ááºáá±á¬á·áá«)á SeekToCurrentErrorHandler ááᯠáá®ážáá±á¬ááºá á±ááá·áº áá¬áá®á¡ááŸá¬ážáá»á¬ážá áá»ááºá¡ááŸá¬ážá¡ááœááºážáá»á¬ážááᯠááŸááºáááºážááœáẠááá¯ááºááŸáááºáᬠá¡á±á¬á·ááºáááºááŒá áºáá¬ááŒá®áž áá±á¬ááºá á¬ááá¯ááŒáá·áº áááºáááºáá¯ááºáá±á¬ááºáá±áá«áááºá
áá±á¬ááºáá¯á¶ážáá¯á¶ážááŒááºáá»ááº
SeekToCurrentErrorHandler ááá¯á¡ááŒá±áá¶á á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááẠáááºáá±á·áá»áºáá»á¬áž ááŒááºáááºáá±ážááá¯á·ááŒááºážá¡ááœáẠáá»áœááºá¯ááºááá¯á·áááá¯ááºááá¯ááºááá¹ááá¬ážááᯠáá®ááœááºááẠááŸá¯á¶á·áá±á¬áºáá±ážáá²á·áááºá
ááááŠážá áœá¬á áá»áœááºá¯ááºááá¯á·ááẠááŸáááŒá®ážáá¬áž á¡ááœá±á·á¡ááŒá¯á¶ááᯠá¡áá¯á¶ážááŒá¯ááŒá®áž á¡ááá®áá±ážááŸááºáž áá¯áá¹áááá±á«áºáá°áááºá áááºážááᯠáá»á²á·ááœááºááá¯áá«áááºá linear logic á¡ááá®áá±ážááŸááºážá¡ááœááºá ááŒááºá ááºážááŒáá·áºááá·áºáááºážáá»á°áá¬á០áááºááŸááºáá¬ážáá±á¬ á¡áá»áááºááá¯á¡ááœááºáž áááºáá±á·ááºá»á¡áá áºáá»á¬ážáááºááŒááºážááᯠáááºááẠá¡áá±á¬ááºážáá¯á¶ážááŒá áºáááá·áºáááºá á¡ááŒá¬ážá¡ááá®áá±ážááŸááºážáá»á¬ážá¡ááœááºá ááŒááºáááºááŒáá¯ážá á¬ážááŸá¯áá»á°áá¬ááᯠáá»áá·áºáá¯á¶ážááá·áº á¡áá»ááºáá áºáá»ááºááŸááá»ááºáá«áááºá ááá¯á·á¡ááŒááºá á€á¡áá»ááºáá áºáá¯áááºážááẠáááºážáááºážááŸá áºáá¯áá¯á¶ážá¡ááœáẠDLQ áá¯ááºáá±á¬ááºááá¯ááºá áœááºážááŸáááá«áááºá
ááŒááºáááºááŒáá¯ážá á¬ážááŸá¯áá»á°áá¬ááᯠá¡ááá®áá±ážááŸááºážááœáẠááááºážáááºážáá¬ážááááºááŒá áºááŒá®áž áá¬áá®á¡ááŸá¬ážá¡ááœááºážáá áºáá¯ááŒá áºáá±á«áºáá¬áá±á¬á¡áá« áá±á¬ááºáá¬áááᯠááŒááºáááºááá°áááºá¡ááœáẠáá¬áááºááŸááááºá
Linear Logic á¡ááá®áá±ážááŸááºážá¡ááœáẠá á¬ážáá¯á¶ážáá°ááᯠáááºááá·áºááŒááºážá
spring-kafka áá²á· á¡áá¯ááºáá¯ááºáá²á·á¡áá«á Consumer ááᯠáááºááá·áºááá¯á· áá¯ááºá áá®ááá¯áá»áá¯áž ááŒá áºááá¯ááºáá«áááºá
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 ááœááºááœááºááŸááá±á¬ áá®ážááŒá¬ážá á¬ááœá²áá áºáá¯ááœáẠááŒá áºáá±á«áºáááºááŒá áºááŒá®ážá ááœá±áŠážááŸáááºáž áá¶á·ááá¯ážáá±ážáá¬ážááá·áº á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááŒá áºáááºá
áá»áœááºá¯ááºááá¯á·ááẠá¡á±á¬ááºáá«áááºážáááºážááŒáá·áº retryAt áááºááá¯ážááᯠááŸá¬ááœá±á·ááẠá
- ááŒááºáá±á«áºááá·áºáá±á¬ááºáá¬ááááºááá¯ážááᯠáá»áŸá±á¬áºááŒáá·áºáááºá
- áááºááŒááºáááºááá¯ážá¡áá±á«áºá¡ááŒá±áá¶á ááŒááºáááºááŒáá¯ážá á¬ážááŸá¯áá»á°áá¬ááŸá áááºááŸáááŸá±á¬áá·áºááŸá±ážááŸá¯ááŒá¬ážáá¬áááᯠááŸá¬ááœá±áááºá áááºážáá»á°áá¬ááᯠá¡ááá®áá±ážááŸááºážááœáẠááŒá±áá¬áá¬ážááŒá®ážá áááºážááᯠááááºážáááºážááẠJSON áá±á¬áºáááºááᯠáá»áœááºá¯ááºááá¯á· ááœá±ážáá»ááºáá²á·áááºá
- JSON á¡áááºážá¡áá»ááºážááœáẠááœá±á·áááá·áº ááŒá¬ážáá¬áááẠáá¯ááºáá±á¬ááºááŒá®ážááá·áºáá±á¬áẠáááºáá«ááá²áá² áá¯ááºáá±á¬ááºáááá·áº á áá¹ááá·áºá¡áá±á¡ááœáẠáá«áááºáááºá retryAt á¡ááœáẠáááºááá¯ážááᯠááœá²á·á ááºážááẠá€á áá¹ááá·áºá¡áá±á¡ááœááºááᯠáááºááŸáá¡áá»áááºááá¯á· áá±á«ááºážááá·áºáááºá
- ááŒá¬ážáá¬áááᯠááŸá¬áááœá±á·áá«áá retryAt ááááºááá¯ážááẠnull ááŒá áºááŒá®áž áá°ááá¯ááºááá¯áẠááœá²ááŒááºážá áááºááŒá¬áááºá¡ááœáẠDLQ ááá¯á· áááºáá±á·áá»áºááᯠáá±ážááá¯á·áááºááŒá áºáá«áááºá
á€áááºážáááºážááŒáá·áºá áá»ááºááŸááá±á¬á¡áá¬á¡á¬ážáá¯á¶ážááẠáááºááŸááá¯ááºáá±á¬ááºáá±ááá·áº áááºáá±á·áá»áºáá áºáá¯á á®á¡ááœáẠáááºáá«ááá²áá²áá±á«áºááá¯ááŸá¯á¡áá±á¡ááœááºááᯠááááºážáááºážáááºááŒá áºáááºá á¥ááá¬á á¡ááá®áá±ážááŸááºážááŸááºáá¬ááºááœááºááŒá áºáááºá áá»ááºážáá¬áž áá¯áá¹áááá±á á¡ááá®áá±ážááŸááºážááẠáá¯ááºáááºážá ááºáá áºáá¯áá¯á¶ážááᯠáááá¯ááºááœááºááá¯ááºáááŒáá·áº ááŒááºáááºááŒáá¯ážá á¬ážááŸá¯ á¡áá±á¡ááœááºááᯠááŸááºáá¬ááºááœáẠáá¬ážááŸáááŒááºážááẠá€áá»ááºážáááºááŸá¯á¡ááœáẠá¡áá±ážáá«áááºááá¯ááºáá«á ááœá±áŠážáá¬áá®ááœáẠááŒááºáááºááŒáá¯ážá á¬ážááŒááºážááŸáá·áºááá°áá²á á¡ááá®áá±ážááŸááºážááᯠááŒááºáááºá áááºááŒááºážááẠáááºáá±á·áá»áºá¡á¬ážáá¯á¶ážááᯠááŒááºáááºáá¯ááºáá±á¬ááºááẠáá¯á¶ážááŸá¯á¶ážááœá¬ážáááºááá¯ááºáá±á¬áºáááºáž áá»á°áá¬ááᯠááá¯ážááá¯ážááŸááºážááŸááºáž ááŒááºáááºá áááºáááºááŒá áºáááºá
á€áá»ááºážáááºááŸá¯ááẠá¡ááœááºáá±ážáá¶áá±á¬áááºááŒá±á¬áá·áº ááááŸáááá¯ááºááá·áº ááŒááºáá
áá
áºá០áááºááᯠáááºááŸá¬ážááẠáá°áá®áá±ážáááºá áá
áºáááºážááá¯ááá±á¬áº ááŒááºáááºáá¯ááºáá±á¬ááºááŒááºážá¡ááŒááºá áá»áœááºá¯ááºááá¯á·ááẠáá¯á¶á
á¶ááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááá¯ááºáá²á·áááºá
áá»áœááºá¯ááºááá¯á·áá¡ááŒá±á¡áá±ááœááºá á¡ááŸá¬ážá¡ááœááºážá¡ááá·áºááẠ1 áá¬ááŸáááŒá®áž áá¬áá®ááœááºáááºááŒááºáá±á¬ááºááŸá¯áá»á¬ážááŒá±á¬áá·áº á áá áºáááºááá·áºáá»áááºááᯠáá»áŸá±á¬á·áá»áááºá áá»áœááºá¯ááºááá¯á·ááẠá¡ááœááºáá±ážáááºáá±á¬ latency ááŒá¬ážáá¬ááá»á¬ážááŸáá·áºá¡áá° á¡ááœááºá¡áá±ážá áááºáááºá ááºážááŒááºážáá»á°áá¬ááᯠá¡áá¯á¶ážááŒá¯áá«áááºá áááºážááẠá¡á¯ááºá á¯á¡ááá®áá±ážááŸááºážá¡á¬ážáá¯á¶ážá¡ááœáẠáááá·áºáá»á±á¬áºááá¯ááºáá«á ááá¯á·ááŒá±á¬áá·áº error threshold ááŸáá·áº interval value á¡ááŒá¬áž áááºááœááºááŸá¯ááᯠá áá áºá áááá±áááá¹ááá¬áá»á¬ážáá±á«áºáá°áááºá ááœá±ážáá»ááºááá«áááºá
á¡áá¯á¶ážá¡ááŒááºáááŸááá±á¬ áá¯áá¹áááá±áááŒáá·áº á¡ááá®áá±ážááŸááºážáá»á¬ážá០áááºáá±á·áá»áºáá»á¬ážááᯠáá¯ááºáá±á¬ááºáááºá¡ááœáẠáá®ážááŒá¬ážá¡ááá®áá±ážááŸááºážáá áºáá¯
á€áááºááŸá¬ RETRY_AT á¡áá»áááºáá±á¬ááºáá±á¬á¡áá« DESTINATION áá±á«ááºážá ááºááá¯á· ááŒááºáááºáá±ážááá¯á·ááá·áº ááá¯áá²á·ááá¯á·áá±á¬ á¡ááá®áá±ážááŸááºáž (Retryer) ááá¯á· áááºáá±á·áá»áºáá±ážááá¯á·ááá·áº áá¯ááºááá°áá¬áá áºáá¯ááŒá áºáááºá
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 ááááºááá¯ážááᯠá á¬ážáá¯á¶ážáá°áááºááá·áºááŸá¯ááŸáá áºááá·áº ááŒááºáááºááŒáá¯ážá á¬ážááá·áºááá¹ááá¬ážá¡ááœááºáá²á·ááá¯á·ááẠááœá±á·ááŸáááááºá DESTINATION ááŸáá·áº RETRY_AT á¡ááŒáẠáá»áœááºá¯ááºááá¯á· ááŒááºáááºážáááº-
- GROUP_IDá áá»áœááºá¯ááºááá¯á·ááẠáá°ááá¯ááºááá¯áẠááœá²ááŒááºážá áááºááŒá¬ááŒá®áž ááá¯ážááŸááºážáá±á¬ ááŸá¬ááœá±ááŸá¯á¡ááœáẠáááºáá±á·áá»áºáá»á¬ážááᯠá¡á¯ááºá á¯ááœá²á·áá±ážáá«áááºá
- ORIGINAL_PARTITION ááẠááŒááºáááºáá¯ááºáá±á¬ááºááŒááºážá¡ááœáẠáá°áá®áá±á¬ á á¬ážáá¯á¶ážáá°ááᯠááááºážááááºážáá¬ážááẠááŒáá¯ážá á¬ážáá«á á€ááá·áºáááºáá»ááºááẠnull ááŒá áºááá¯ááºáááºá áááºážá¡ááŒá±á¡áá±ááœááºáá°áááºážáááºáá±á·áá»áºá record.key() áá±á¬á·ááᯠá¡áá¯á¶ážááŒá¯á á¡áááºážááá·áºá¡áá áºááᯠáááŸááááºááŒá áºáááºá
- áááºá ááºážááŒáá·áºáá« áá»á°áá¬ááᯠááá¯ááºáá¬ááẠCOUNTER áááºááá¯ážááᯠá¡ááºááááºáá¯ááºáá¬ážáááºá
- SEND_TO ááẠRETRY_AT ááá¯á·áá±á¬ááºááŸáááá·áºá¡áá« ááŒááºáááºáá¯ááºáá±á¬ááºáááºá¡ááœáẠáááºáá±á·áá»áºááᯠáá±ážááá¯á·ááŒááºážááŸááááŸá á ááºáááºáááŒááºáá±á¬áºááŒááŒááºáž ááá¯á·ááá¯áẠDLQ ááœáẠáá¬ážááŸáááŒááºážááŒá áºáááºá
- á¡ááŒá±á¬ááºážááŒáá»áẠ- áááºáá±á·áá»áºáá¯ááºáá±á¬ááºááŸá¯ á¡ááŸá±á¬áá·áºá¡ááŸááºááŒá áºáááá·áº á¡ááŒá±á¬ááºážáááºážá
Retryer ááẠPostgreSQL ááœáẠááŒááºáááºáá±ážááá¯á·ááŒááºážááŸáá·áº ááá¯ááºááá¯ááºááœá²ááŒááºážá áááºááŒá¬ááŒááºážá¡ááœáẠáááºáá±á·áá»áºáá»á¬ážááᯠááááºážáááºážáá¬ážáááºá á¡áá»áááºááá¯ááºážáááááá¬ááẠRETRY_AT ááŒáá·áº áááºáá±á·áá»áºáá»á¬ážááᯠááŸá¬ááœá±á·ááá·áº áá¯ááºáááºážáá áºáá¯ááᯠá áááºááŒá®áž DESTINATION áá±á«ááºážá ááºá ORIGINAL_PARTITION á¡áááºážááá·áºááá¯á· áá±á¬á·ááŸááºáááºáž.key() ááŒáá·áº ááŒááºááá¯á·áá±ážáááºá
ááá¯á·ááŒá®ážáááºááŸáá·áº PostgreSQL á០á á¬ááá¯áá»á¬ážááᯠáá»ááºááá¯ááºáá«áááºá áááºáá±á·áá»áºáá»á¬ážááᯠááá¯ááºááá¯ááºááœá²ááŒááºážá áááºááŒá¬ááŒááºážááẠREST API ááŸáá áºááá·áº Retryer ááŸáá·áº á¡ááŒááºá¡ááŸááºáá¯á¶á·ááŒááºááá·áº ááá¯ážááŸááºážáá±á¬ UI ááœáẠááŒá áºáá±á«áºáá«áááºá áááºážá á¡áááá¡ááºá¹áá«áááºáá»á¬ážááŸá¬ DLQ á០áááºáá±á·áá»áºáá»á¬ážááᯠááŒááºáááºáá±ážááá¯á·ááŒááºáž ááá¯á·ááá¯áẠáá»ááºááŒááºážá á¡ááŸá¬ážá¡ááœááºážá¡áá»ááºá¡áááºáá»á¬ážááᯠááŒáá·áºááŸá¯ááŒááºážááŸáá·áº á¥ááá¬á¡á¬ážááŒáá·áº á¡ááŸá¬ážá¡áááºááŒáá·áº áááºáá±á·áá»áºáá»á¬ážááᯠááŸá¬ááœá±ááŒááºážááá¯á·ááŒá áºáááºá
áá»áœááºá¯ááºááá¯á·á á¡á á¯á¡áá±ážáá»á¬ážááœáẠáááºáá±á¬ááºááááºážáá»á¯ááºááŸá¯ááᯠááœáá·áºáá¬ážáá±á¬ááŒá±á¬áá·áºá Retryer áá¬ážáá±á¬ááºáá±ááá·áº á¡ááŒá±á¬ááºážá¡áá¬ááᯠáááºáá±á¬ááºážáááºáá±á¬ááºááœáá·áº áá±á¬ááºážááá¯áááºááŸáá·áº Retryer á¡á¬áž DESTINATION áá±á«ááºážá ááºááá¯á· áá±ážááœáá·áºááŒá¯ááẠááá¯á¡ááºáá«áááºá áááºážááẠá¡áááºáááŒá±áá±á¬áºáááºáž ááŒá¬ážáá¬áá¡ááŒá±á¬ááºážá¡áá¬áá»ááºážáááºáááºážááŸáá·áºááá°áá²á áá»áœááºá¯ááºááá¯á·ááœáẠáááºážááá¯á á®áá¶ááá·áºááœá²ááẠááŒáá·áºá á¯á¶áá±á¬ DLQ ááŸáá·áº UI ááŸááááºá
ááœá²ááŒá¬ážááŒá¬ážáá¬ážáá±á¬ áá¯áá¹áááá±áááᯠá¡áá¯á¶ážáá»ááá·áº á¡ááá®áá±ážááŸááºážáá»á¬ážááẠááá°áá®áá±á¬ áá¯áá¹áááá±áááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááá·áº ááá°áá®áá±á¬ á á¬ážáá¯á¶ážáá°á¡á¯ááºá á¯áá»á¬ážá áœá¬á០áááºáá¬áá±á¬ á¡ááŒá±á¬ááºážá¡áá¬áá áºáá¯ááᯠáááºááá·áºá¡áá« ááŒá áºáááºáá»á¬ážááŸááá«áááºá á€á¡ááá®áá±ážááŸááºážáá»á¬ážáá²á០áá áºáá¯á¡ááœáẠRetryer ááŸáá áºááá·áº áááºáá±á·áá»áºááᯠááŒááºáááºáá¯ááºáá±á¬ááºááŒááºážááẠá¡ááŒá¬ážáá áºáá¯ááœáẠáááá¹áá°ááœá¬ážááŒááºážááᯠááŒá áºáá±á«áºá á±áááºááŒá áºáááºá áááºážááá¯áá¬ááœááºáááºá ááŒááºáááºáá¯ááºáá±á¬ááºááŒááºážá¡ááœáẠáá®ážááŒá¬ážáá±á«ááºážá ááºáá áºáᯠáááºáá®ážáá«áááºá á¡áááºááŸáá·áº áááºáá«ááá²áá² á¡ááŒá±á¬ááºážá¡áá¬áá»á¬ážááᯠááá·áºáááºáá»ááºáááŸááá² á á¬ážáá¯á¶ážáá°áá áºáŠážáááºážá áááºááá¯ááºáááºá
áá°áááºážá¡á¬ážááŒáá·áº á€áá»ááºážáááºááŸá¯ááẠcircuit breaker áá¯ááºáá±á¬ááºááá¯ááºá
áœááºážááᯠááá±ážáá±á¬ááºáá±á¬áºáááºáž áááºážááᯠá¡áá¯á¶ážááŒá¯á á¡ááá®áá±ážááŸááºážááœáẠááá·áºááœááºážááá¯ááºáááºá
áá±á¬ááºáá»ááº
ááááºá¡áá±ááŒáá·áºá áá»áœááºá¯ááºááá¯á·ááœáẠááŒááºáá áá áºáá áºáá¯á០áá¬áá®ááááŸáááá¯ááºáá«á áááºáá±á·áá»áºááŒááºáááºáá¯ááºáá±á¬ááºááŒááºážááᯠáááºáá«ááá²áá² áá¯ááºáá±á¬ááºááá¯ááºá á±ááá·áº áá®ážááŒá¬ážá¡ááá®áá±ážááŸááºážáá áºáá¯ááŸááááºá
á¡ááá®áá±ážááŸááºážáá¡áááá¡á¬ážáá¬áá»ááºáá»á¬ážáá²ááŸáá áºáá¯ááŸá¬áááºážááá¯á·ááááºááœááºáááá¬áááºááŸá¬ážáá±á¬ááŒá¯ááŒááºááœááºážáá¶ááŸá¯áá»á¬ážáááŸááá²áá°áá®áá±á¬ Kafka á¡á á¯á¡áá±ážáá±á«áºááœááºáááºáááºáá±áá±á¬ááŒááºáá áá áºáá»á¬ážááŸá¡áá¯á¶ážááŒá¯ááá¯ááºáááºá ááá¯ááá¯á·áá±á¬á¡ááá®áá±ážááŸááºážáá áºáá¯ááẠááŒááºáááºááŒáá¯ážá á¬ážááá·áºá¡ááŒá±á¬ááºážá¡áá¬ááá¯áááºáá±á¬ááºáááºá Kafka áá±á«ááºážá á®ážá¡áááºážáááºááá¯ááŒáá·áºááŒá®áž Retryer ááá¯á· áááºáá±á·áá»áºááá¯á·áááºáᬠááá¯á¡ááºáááºááŒá áºáááºá áááºááá·áºá¡ááŒá±áá¶á¡áá±á¬ááºá¡á¡á¯á¶ááá¯áá»áŸ ááŒáŸáá·áºáááºáááºáááá¯á¡ááºáá«á á¡ááá®áá±ážááŸááºážá០Retryer ááŸáá·áº back ááá¯á· ááœáŸá²ááŒá±á¬ááºážáá±ážááá·áº áááºáá±á·áá»áºá¡áá±á¡ááœááºááᯠáá»áŸá±á¬á·áá»áááºá¡ááœááºá áá»áœááºá¯ááºááá¯á·ááẠá¡ááá®áá±ážááŸááºážáá»á¬ážááᯠlinear logic ááŒáá·áº ááŸá¬ááœá±áá±á¬áºáá¯ááºááŒá®áž á á¬ážáá¯á¶ážáá°áááºááá·áºáá±ážááŸáá áºááá·áº áááºážááá¯á·ááᯠááŒááºáááºáá¯ááºáá±á¬ááºáá«áááºá
source: www.habr.com