簡體   English   中英

Lagom。 限制外部服務

[英]Lagom. Throttling for external service

我正在玩Lagom,它看起來不錯,但我完全迷失了一個問題。

讓我說我依賴外部HTTP服務,它只允許10個請求/秒,在其他情況下甚至可以禁止:)我googled,但沒有找到任何工作的例子。 我可以在無類型的actor中包裝服務並為其添加速率限制器,但我不明白如何在Akka Typed或Lagom服務之上實現它。

也許有人已經解決了這個問題? 謝謝!

你想要一個令牌桶 Akka-Streams內置Flow.throttle,但聽起來你正在使用原始akka,所以不能使用它。 在Akka中存在令牌桶實現,但遺憾的是它沒有提供任何使用指導,我自己也沒有使用它。

對於我自己的用例(不是Akka而是使用Scala Futures),我編寫了自己的令牌桶。 它允許我根據指定的限制引用Future的觸發。 它是針對monix調度程序編碼的,但是為了這個目的,它與Akka調度非常相似:

import java.util.concurrent.ConcurrentLinkedQueue

import monix.execution.Scheduler.Implicits.global
import monix.execution.atomic.AtomicInt

import scala.concurrent.{Future, Promise}
import scala.concurrent.duration._

case class RateLimiter(duration: FiniteDuration, maxInvocations: Int) {

  @volatile var permits: Int = maxInvocations
  val queue = new ConcurrentLinkedQueue[() => Any]()

  global.scheduleAtFixedRate(duration, duration) {
    this synchronized {
      permits = maxInvocations

      while (!queue.isEmpty && permits > 0) {
        Option(queue.poll()).foreach { fun =>
          permits -= 1
          fun.apply()
        }
      }
    }
  }

  def apply[T](f: => Future[T]): Future[T] =
    this synchronized {
      if (permits > 0) {
        permits -= 1
        f
      } else {
        val res = Promise[T]()
        queue.add(() => { res.completeWith(f) })
        res.future
      }
    }
}

用法是

val limiter = RateLimiter(1.second, 10)

limiter {
  someWebService.asyncCall()
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM