ReplyingKafkaTemplate 严格要求每个请求一个回复;其他回复将被丢弃。
我们在 2.3 中添加了 AggregatingReplyingKafkaTemplate 正是针对这种类型的场景 - 等待多个回复或超时。
这是一个测试用例...
@KafkaListener(id = "def1", topics = { D_REQUEST, E_REQUEST, F_REQUEST })
@SendTo // default REPLY_TOPIC header
public String dListener1(String in) {
return in.toUpperCase();
}
@KafkaListener(id = "def2", topics = { D_REQUEST, E_REQUEST, F_REQUEST })
@SendTo // default REPLY_TOPIC header
public String dListener2(String in) {
return in.substring(0, 1) + in.substring(1).toUpperCase();
}
和
@Test
public void testAggregateNormal() throws Exception {
AggregatingReplyingKafkaTemplate<Integer, String, String> template = aggregatingTemplate(
new TopicPartitionOffset(D_REPLY, 0), 2);
try {
template.setDefaultReplyTimeout(Duration.ofSeconds(30));
ProducerRecord<Integer, String> record = new ProducerRecord<>(D_REQUEST, null, null, null, "foo");
RequestReplyFuture<Integer, String, Collection<ConsumerRecord<Integer, String>>> future =
template.sendAndReceive(record);
future.getSendFuture().get(10, TimeUnit.SECONDS); // send ok
ConsumerRecord<Integer, Collection<ConsumerRecord<Integer, String>>> consumerRecord =
future.get(30, TimeUnit.SECONDS);
assertThat(consumerRecord.value().size()).isEqualTo(2);
Iterator<ConsumerRecord<Integer, String>> iterator = consumerRecord.value().iterator();
String value1 = iterator.next().value();
assertThat(value1).isIn("fOO", "FOO");
String value2 = iterator.next().value();
assertThat(value2).isIn("fOO", "FOO");
assertThat(value2).isNotSameAs(value1);
assertThat(consumerRecord.topic()).isEqualTo(AggregatingReplyingKafkaTemplate.AGGREGATED_RESULTS_TOPIC);
}
finally {
template.stop();
template.destroy();
}
}