Spring boot Spring Cloud Stream Kafka Producer事务性在反应式Spring Webflux应用程序中
我正在Spring Webflux应用程序中使用Spring Cloud Stream Binder Kafka 3.0.0,该应用程序公开一个API,该API接收一些数据并使用Spring boot Spring Cloud Stream Kafka Producer事务性在反应式Spring Webflux应用程序中,spring-boot,apache-kafka,project-reactor,spring-cloud-stream,spring-cloud-stream-binder-kafka,Spring Boot,Apache Kafka,Project Reactor,Spring Cloud Stream,Spring Cloud Stream Binder Kafka,我正在Spring Webflux应用程序中使用Spring Cloud Stream Binder Kafka 3.0.0,该应用程序公开一个API,该API接收一些数据并使用@输出将其发布到Kafka主题: @Autowired private lateinit var producer: Producer @PostMapping @ResponseStatus(CREATED) fun create(@RequestBody metrics: S
@输出将其发布到Kafka主题:
@Autowired
private lateinit var producer: Producer
@PostMapping
@ResponseStatus(CREATED)
fun create(@RequestBody metrics: SomeMetric): Mono<Void> {
producer.send(metrics)
return Mono.empty()
}
我已经将Kafka和Spring Boot应用程序配置为使用事务生产者(注意上面send方法上的@transactional
注释):
@配置
类KafkaProducer配置{
@豆子
fun transactionManager(绑定器:BinderFactory):PlatformTransactionManager{
val pf=(binders.getBinder(“卡夫卡”),
MessageChannel::class.java)作为KafCamessageChannelBinder)。transactionalProducerFactory
返回KafkaTransactionManager(pf)
}
@EnableTransactionManagement
@EnableBinding(值=[ProducerSources::class])
@SpringBoot应用程序
类MyApplication
趣味主线(args:Array){
运行应用程序(*args)
}
关键是,作为一个Spring Webflux应用程序,我不应该阻止http线程,所以我应该将(阻止)生产者包装在一个fromCallable块上,并在另一个线程池上执行它,比如:
@Component
class Producer(private val producerSources: ProducerSources) {
@Transactional
fun send(metrics: SomeMetric) : Mono<Unit> {
Mono.fromCallable {
producerSources.metrics().send(MessageBuilder.withPayload(metrics) .build())
}.subscribeOn(Schedulers.elastic())
}
}
@组件
类别制作人(私人val制作人来源:制作人来源){
@交易的
趣味发送(指标:sometric):单声道{
Mono.fromCallable{
producerSources.metrics().send(MessageBuilder.withPayload(metrics.build())
}.subscribeOn(Schedulers.elastic())
}
}
@PostMapping
@响应状态(已创建)
有趣的创建(@RequestBody metrics:sometric):Mono{
返回生产者。发送(度量)
}
我的问题是:
@Transactional
注释仍然可以使用这种方法吗?我想它不应该
- 在反应式SpringWebFlux+云流Kafka上下文中,支持事务性的推荐方法是什么
- 奖励:在Spring Cloud Stream中受支持吗?如果是,我们如何在这种情况下配置它
@Output
,事务支持
你看过这篇文章了吗-。有一些示例和细节。也许我们需要在我们的文档中对其进行改进。嗨,奥列格,是的,我已经读过那篇文章。重点是它关注数据库事务,但KafkaTransactionManager不是一个反应式事务管理器,所以它不应该工作。Reactor Kafka似乎支持事务处理发送KafkaSender.create(senderOptions).sendTransactionally
,但我不确定这是否适合Spring Cloud Stream…我也看过这个示例:但它有点半途而废,一方面它使用被动源,但另一方面,它仍然是一个webmvc应用程序。
interface ProducerSources {
@Output("metrics")
fun metrics(): MessageChannel
//Other...
}
@Configuration
class KafkaProducerConfiguration {
@Bean
fun transactionManager(binders: BinderFactory): PlatformTransactionManager {
val pf = (binders.getBinder("kafka",
MessageChannel::class.java) as KafkaMessageChannelBinder).transactionalProducerFactory
return KafkaTransactionManager<ByteArray, ByteArray>(pf)
}
@EnableTransactionManagement
@EnableBinding(value = [ProducerSources::class])
@SpringBootApplication
class MyApplication
fun main(args: Array<String>) {
runApplication<MyApplication>(*args)
}
@Component
class Producer(private val producerSources: ProducerSources) {
@Transactional
fun send(metrics: SomeMetric) : Mono<Unit> {
Mono.fromCallable {
producerSources.metrics().send(MessageBuilder.withPayload(metrics) .build())
}.subscribeOn(Schedulers.elastic())
}
}
@PostMapping
@ResponseStatus(CREATED)
fun create(@RequestBody metrics: SomeMetric): Mono<Void> {
return producer.send(metrics)
}