Kafka、MongoDB和反应式编程的增量价值
很抱歉标题不好,但我想不出任何描述性的 我有一种设计问题,因此我需要增加我文档中关于上一条记录的字段的值,我的意思是,假设我有以下模型:Kafka、MongoDB和反应式编程的增量价值,mongodb,apache-kafka,architecture,spring-data,reactive,Mongodb,Apache Kafka,Architecture,Spring Data,Reactive,很抱歉标题不好,但我想不出任何描述性的 我有一种设计问题,因此我需要增加我文档中关于上一条记录的字段的值,我的意思是,假设我有以下模型: @Document data class Example( @Id var id: String?=null, val count: Long, @Indexed(unique = true) val type: Enum(YES,NO) ) 这是我的存储库 interface ExampleRepository :
@Document
data class Example(
@Id
var id: String?=null,
val count: Long,
@Indexed(unique = true)
val type: Enum(YES,NO)
)
这是我的存储库
interface ExampleRepository : ReactiveSortingRepository<Example, String> {
fun findOneByType(type: Enum): Mono<Example>
}
基本上,我有一个Kafka侦听器,它从主题获取请求并调用createOrIncrease方法,然后检查是否存在,增加计数如果不存在,它将创建一个默认值
现在,我的问题发生在我用Kafka多次发送同一个文档并从不同线程读取它时,所以在同一时间,所有人都试图找到他们无法找到的文档,因为这是第一次,然后他们尝试使用默认文档,MongoDB抛出重复错误。我正在努力寻找更好的方法来实现相同的功能,但在分布式系统中,这是在微服务体系结构中,多个微服务可以同时从不同的Kafka分区获取相同的文档
你知道我如何解决这个问题吗
我可以想出两种可能的解决办法:
@Service
class ExampleService(private val repository: ExampleRepository) {
private val logger = LoggerFactory.getLogger(javaClass)
fun createOrIncrease(type: Enum) = repository
.findOneByType(type)
.map { item ->
logger.info("TEST - Found item $item")
Example(item.id, item.count+1, item.type)
}
.defaultIfEmpty(Example(null, 1, NO))
.flatMap { item ->
logger.info("TEST - Saving item $item")
repository
.save(item)
.retryWhen(Retry.backoff(3, Duration.ofSeconds(5)))
}
}