我在春季靴中有kafka处理程序:
@KafkaListener(topics = "topic-one", groupId = "response")
public void listen(String response) {
myService.processResponse(response);
}
例如,生产者每秒发送一条消息。但是myService.processResponse
可以工作10秒。我需要处理每条消息并在新线程中启动myService.processResponse
。我可以创建我的执行器并将每个响应委派给它。但是我认为kafka中还有其他配置。我发现了2:
1)在concurrency = "5"
注释中添加@KafkaListener
-似乎可以正常工作。但是我不确定如何正确,因为我有第二种方法:
2)我可以创建ConcurrentKafkaListenerContainerFactory
并将其设置为ConsumerFactory
和concurrency
我不明白这些方法之间的区别吗?仅将concurrency = "5"
添加到@KafkaListener
注释就足够了吗?还是我需要创建ConcurrentKafkaListenerContainerFactory
?
或者我什么都不懂,还有另一种方法吗?
答案 0 :(得分:3)
在管理承诺的补偿方面,使用执行程序会使事情变得复杂。不推荐。
使用@KafkaListener
,框架为您创建一个ConcurrentKafkaListenerContainerFactory
。
concurrency
只是一种方便;它会覆盖出厂设置。
这使您可以将同一工厂与多个侦听器一起使用,每个侦听器具有不同的并发性。
您可以使用引导属性来设置容器并发性(默认)。该值被注释值覆盖;参见javadocs ...
/**
* Override the container factory's {@code concurrency} setting for this listener. May
* be a property placeholder or SpEL expression that evaluates to a {@link Number}, in
* which case {@link Number#intValue()} is used to obtain the value.
* <p>SpEL {@code #{...}} and property place holders {@code ${...}} are supported.
* @return the concurrency.
* @since 2.2
*/
String concurrency() default "";
答案 1 :(得分:0)
concurrency
选项与并发处理同一使用者接收到的消息无关。当您有多个使用者分别处理各自的分区时,它适用于使用者组。
将处理传递给单独的线程非常复杂,我相信Spring-Kafka团队决定不“按设计”执行该操作。您甚至无需深入研究Spring-Kafka即可了解原因。检查KafkaConsumer's 检测消费者失败 文档:
必须注意确保不会出现承诺的偏移量 领先于实际位置。通常,您必须禁用自动 提交并手动提交记录的处理过的偏移量 线程已完成处理(取决于交付情况) 您需要的语义)。另请注意,您需要暂停 分区,以便直到之后都不会从轮询中收到新记录 线程已完成对先前返回的内容的处理。
答案 2 :(得分:-1)
您需要myService.processResponse(response);
方法异步。
为此,您只需要这样做:
@Async
public void processResponse(String response) {
// Process here
}
此外,您需要通过在主类顶部添加@EnableAsync
来启用异步功能。
@SpringBootApplication
@EnableAsync
public class Application {
public static void main(String[] args) {
// close the application context to shut down the custom ExecutorService
SpringApplication.run(Application.class, args).close();
}
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("GithubLookup-");
executor.initialize();
return executor;
}
}
如果有任何问题,请检查link!