
рд╣реЗрд▓реЛ, рд╣реИрдмрд░ред
рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдореИрдВрдиреЗ рдЕрдкрдирд╛ рдЕрдиреБрднрд╡ рд╕рд╛рдЭрд╛ рдХрд┐рдпрд╛ рдХрд┐ рд╣рдо рдЯреАрдо рдореЗрдВ рдХрд┐рди рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рд╣рдо рдЕрдХреНрд╕рд░ рдХрд╛рдлреНрдХрд╛ рдкреНрд░реЛрдбреНрдпреВрд╕рд░ рдФрд░ рдХрдВрдЬреНрдпреВрдорд░ рдХреЗ рд▓рд┐рдП рдХрд░рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдЧрд╛рд░рдВрдЯреАрдХреГрдд рдбрд┐рд▓реАрд╡рд░реА рд╣реЛ рд╕рдХреЗред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдпрд╣ рдмрддрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдХреИрд╕реЗ рд╣рдордиреЗ рдХрд╛рдлреНрдХрд╛ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдПрдХ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЛ рдПрдХ рдмрд╛рд╣рд░реА рд╡реНрдпрд╡рд╕реНрдерд╛ рдХреА рдЕрд╕реНрдерд╛рдпреА рдЕрдиреБрдкрд▓рдмреНрдзрддрд╛ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдЖрдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ред
. -, , Docker-, Kubernetes OpenShift, enterprise- . - , тАФ -.
Kafka
IBM MQ . - dead-letter-queue (DLQ) . DLQ , IBM MQ.
(, ResourceAccessException HTTP- MongoTimeoutException MongoDb), . , , , - . , . , , DLQ .
, . , ConsumerтАЩ, .

, . , , -, .
, Kafka- , - . retention.ms -, . .
, spring spring-kafka . Spring-kafka spring-retry, BackOffPolicy. , . , - , . , .
spring-kafka ContainerAwareErrorHandler, SeekToCurrentErrorHandler, , offset , . spring-kafka 2.3 BackOffPolicy.
, 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;
}
}
retryAt тАФ , MessageListenerContainer, . , TaskScheduler, spring.
retryAt :
- .
- . , JSON.
- JSON- , . , retryAt.
- , retryAt null DLQ .
, , . , . spring-retry , .
, - . , circuit breaker.
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, spring-cloud-netflix spring cloud circuit breaker, . , bulkhead , . , spring-cloud-netflix thread pool .
, - .
, , Kafka-, ! retry-, Kafka- Retryer. . Retryer , Consumer.