Use kafka transactions to make spring-kafka tests more stable (#4024)
* Use kafka transactions to make spring-kafka tests more stable * manual acks * another approach: batch error handler that immediately recovers * another try * yet another try * do nothing error handler * spotless
This commit is contained in:
parent
0f9308b4fb
commit
01ea967d67
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecords
|
||||||
|
import org.springframework.kafka.listener.BatchErrorHandler
|
||||||
|
|
||||||
|
class DoNothingBatchErrorHandler implements BatchErrorHandler {
|
||||||
|
@Override
|
||||||
|
void handle(Exception thrownException, ConsumerRecords<?, ?> data) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,8 +41,11 @@ class SpringKafkaInstrumentationTest extends AgentInstrumentationSpecification {
|
||||||
"spring.jmx.enabled" : false,
|
"spring.jmx.enabled" : false,
|
||||||
"spring.main.web-application-type" : "none",
|
"spring.main.web-application-type" : "none",
|
||||||
"spring.kafka.bootstrap-servers" : kafka.bootstrapServers,
|
"spring.kafka.bootstrap-servers" : kafka.bootstrapServers,
|
||||||
"spring.kafka.consumer.auto-offset-reset": "earliest",
|
"spring.kafka.consumer.auto-offset-reset" : "earliest",
|
||||||
"spring.kafka.consumer.linger-ms" : 10,
|
"spring.kafka.consumer.linger-ms" : 10,
|
||||||
|
// wait 1s between poll() calls
|
||||||
|
"spring.kafka.listener.idle-between-polls" : 1000,
|
||||||
|
"spring.kafka.producer.transaction-id-prefix": "test-",
|
||||||
])
|
])
|
||||||
applicationContext = app.run()
|
applicationContext = app.run()
|
||||||
}
|
}
|
||||||
|
@ -58,9 +61,11 @@ class SpringKafkaInstrumentationTest extends AgentInstrumentationSpecification {
|
||||||
|
|
||||||
when:
|
when:
|
||||||
runWithSpan("producer") {
|
runWithSpan("producer") {
|
||||||
kafkaTemplate.send("testTopic", "10", "testSpan1")
|
// wrapping in a transaction is needed to remove the possibility of messages being picked up separately by the consumer
|
||||||
kafkaTemplate.send("testTopic", "20", "testSpan2")
|
kafkaTemplate.executeInTransaction({ ops ->
|
||||||
kafkaTemplate.flush()
|
ops.send("testTopic", "10", "testSpan1")
|
||||||
|
ops.send("testTopic", "20", "testSpan2")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
then:
|
then:
|
||||||
|
@ -152,8 +157,9 @@ class SpringKafkaInstrumentationTest extends AgentInstrumentationSpecification {
|
||||||
|
|
||||||
when:
|
when:
|
||||||
runWithSpan("producer") {
|
runWithSpan("producer") {
|
||||||
kafkaTemplate.send("testTopic", "10", "error")
|
kafkaTemplate.executeInTransaction({ ops ->
|
||||||
kafkaTemplate.flush()
|
ops.send("testTopic", "10", "error")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
then:
|
then:
|
||||||
|
@ -240,6 +246,8 @@ class SpringKafkaInstrumentationTest extends AgentInstrumentationSpecification {
|
||||||
ConcurrentKafkaListenerContainerFactory<String, String> batchFactory(
|
ConcurrentKafkaListenerContainerFactory<String, String> batchFactory(
|
||||||
ConsumerFactory<String, String> consumerFactory) {
|
ConsumerFactory<String, String> consumerFactory) {
|
||||||
ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>()
|
ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>()
|
||||||
|
// do not retry failed records
|
||||||
|
factory.setBatchErrorHandler(new DoNothingBatchErrorHandler())
|
||||||
factory.setConsumerFactory(consumerFactory)
|
factory.setConsumerFactory(consumerFactory)
|
||||||
factory.setBatchListener(true)
|
factory.setBatchListener(true)
|
||||||
factory.setAutoStartup(true)
|
factory.setAutoStartup(true)
|
||||||
|
|
Loading…
Reference in New Issue