我正在使用Akka Streams Kafka将 Kafka 消息通过管道传输到远程服务。我想保证该服务只接收一次每条消息(至少一次和最多一次传递)。
这是我想出的代码:
private def startFlow[T](implicit system: ActorSystem, config: Config, subscriber: ActorRef,
topicPattern: String,
mapCommittableMessageToSinkMessage: Function[CommittableMessage[String, String], T]) {
val groupId = config.getString("group-id")
implicit val materializer = ActorMaterializer()
val consumerSettings = ConsumerSettings(system, new StringDeserializer, new StringDeserializer)
.withGroupId(groupId)
.withProperty(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest")
implicit val timeout = Timeout(5 seconds) // timeout for reply message on ask call below
import system.dispatcher // the ExecutionContext that will be used in ask call below
Consumer.committableSource(consumerSettings, Subscriptions
.topicPattern(topicPattern))
.map(message => (message, mapCommittableMessageToSinkMessage(message)))
.mapAsync(1)(tuple => ask(subscriber, tuple._2).map(_ => tuple._1))
.mapAsync(1)(message => message.committableOffset.commitScaladsl())
.runWith(Sink.ignore)
}
如代码所示,它映射原始消息的元组,以及传递给订阅者(发送到远程服务的参与者)的转换消息。元组的目的是在订阅者完成处理后提交偏移量。
关于它的某些东西似乎是一种反模式,但我不确定是否有更好的方法来做到这一点。有什么更好的方法建议吗?
谢谢!