【问题标题】:How to limit an Akka Stream to execute and send down one message only once per second?如何限制 Akka Stream 每秒仅执行一次并发送一条消息?
【发布时间】:2016-07-12 22:21:06
【问题描述】:

我有一个 Akka 流,我希望流大约每秒向下游发送消息。

我尝试了两种方法来解决这个问题,第一种方法是让流开始处的生产者在 Continue 消息进入此 Actor 时每秒只发送一次消息。

// When receive a Continue message in a ActorPublisher // do work then... if (totalDemand > 0) { import scala.concurrent.duration._ context.system.scheduler.scheduleOnce(1 second, self, Continue) }

这工作了一小会儿,然后大量的 Continue 消息出现在 ActorPublisher 演员中,我假设(猜测但不确定)来自下游通过背压请求消息,因为下游可以快速消耗但上游没有产生速度快。所以这个方法失败了。

我尝试的另一种方法是通过背压控制,我在流末尾的ActorSubscriber 上使用MaxInFlightRequestStrategy 将消息数量限制为每秒1 条。这很有效,但是一次大约有三个左右的消息进来,而不是一次只有一个。似乎背压控制并没有立即改变消息进入的速率,或者消息已经在流中排队等待处理。

所以问题是,我怎样才能拥有一个每秒只能处理一条消息的 Akka Stream?


我发现MaxInFlightRequestStrategy 是一种有效的方法,但我应该将批量大小设置为 1,它的批量大小默认为 5,这导致了我发现的问题。现在我正在查看提交的答案,这也是解决问题的一种过于复杂的方法。

【问题讨论】:

  • 你考虑过使用Source.tick吗?
  • 不,让我看看,谢谢。
  • 你也可以试试throttle

标签: akka rate rate-limiting akka-stream


【解决方案1】:

您可以将您的元素通过节流流,这将反压快速源,或者您可以使用tickzip 的组合。

第一个解决方案是这样的:

val veryFastSource =
  Source.fromIterator(() => Iterator.continually(Random.nextLong() % 10000))

val throttlingFlow = Flow[Long].throttle(
  // how many elements do you allow
  elements = 1,
  // in what unit of time
  per = 1.second,
  maximumBurst = 0,
  // you can also set this to Enforcing, but then your
  // stream will collapse if exceeding the number of elements / s
  mode = ThrottleMode.Shaping
)

veryFastSource.via(throttlingFlow).runWith(Sink.foreach(println))

第二种解决方案是这样的:

val veryFastSource =
  Source.fromIterator(() => Iterator.continually(Random.nextLong() % 10000))

val tickingSource = Source.tick(1.second, 1.second, 0) 

veryFastSource.zip(tickingSource).map(_._1).runWith(Sink.foreach(println))

【讨论】:

  • ...但这将保留上游元素...如果您想在节流的情况下删除上游元素怎么办?这有点棘手,因为您必须使用强制油门模式 - 然后处理阶段异常(油门不支持监督策略,因此您无法轻松恢复)
  • 嘿@ChristopherHunt,你可以在打勾后使用缓冲区,并像这样删除元素Source.tick(1 second, 3 seconds, Done).buffer(0, OverflowStrategy.dropNew).throttle(1, 1 second, 1, ThrottleMode.Shaping).runForeach { _ => }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-15
  • 1970-01-01
  • 2021-04-21
相关资源
最近更新 更多