Scala 阿克卡休息投票

Scala 阿克卡休息投票,scala,rest,akka,polling,play2-mini,Scala,Rest,Akka,Polling,Play2 Mini,我正在尝试将一个大型Scala+Akka+PlayMini应用程序与一个外部restapi接口。其思想是定期轮询(基本上每1到10分钟一次)根URL,然后在子级别URL中爬行以提取数据,然后将数据发送到消息队列 我想出了两种方法: 第一路 创建参与者层次结构以匹配API的资源路径结构。在Google Latitude的案例中,这意味着 参与者“纬度/v1/currentLocation”轮询 参与者“纬度/v1/位置”轮询 参与者“纬度/v1/location/1”轮询 参与者“纬度/v1/l

我正在尝试将一个大型Scala+Akka+PlayMini应用程序与一个外部restapi接口。其思想是定期轮询(基本上每1到10分钟一次)根URL,然后在子级别URL中爬行以提取数据,然后将数据发送到消息队列

我想出了两种方法:

第一路 创建参与者层次结构以匹配API的资源路径结构。在Google Latitude的案例中,这意味着

  • 参与者“纬度/v1/currentLocation”轮询
  • 参与者“纬度/v1/位置”轮询
  • 参与者“纬度/v1/location/1”轮询
  • 参与者“纬度/v1/location/2”轮询
  • 演员“纬度/v1/location/3”投票
  • 等等
在这种情况下,每个参与者负责定期轮询其关联资源,以及为下一级路径资源创建/删除子参与者(即,参与者“纬度/v1/location”为其通过轮询了解的所有位置创建参与者1、2、3等)

第二条路 创建一个相同的轮询参与者池,这些参与者接收路由器负载平衡的轮询请求(包含资源路径),轮询URL一次,执行一些处理,并安排轮询请求(下一级资源和轮询URL)。例如,在Google Latitude中,这意味着:

1个路由器,n个轮询器。对Lead的初始轮询请求导致对等的多个新(立即)轮询请求和对同一资源的一个(延迟)轮询请求,即

我已经实现了这两种解决方案,无法立即观察到任何相关的性能差异,至少对于我感兴趣的API和轮询频率而言是如此。我发现第一种方法比第二种方法(在第二种方法中,我需要调度一次)更容易推理,并且可能更容易与system.scheduler.schedule(…)一起使用。此外,假设资源嵌套在多个级别上,并且寿命较短(例如,在每次轮询之间可以添加/删除多个资源),akka的生命周期管理使得在第一种情况下很容易杀死整个分支。第二种方法(理论上)应该更快,代码也更容易编写

我的问题是:

  • 哪种方法似乎是最好的(在性能、可扩展性、代码复杂性等方面)
  • 你认为这两种方法(特别是第一种)的设计有什么问题吗
  • 有没有人尝试过实现类似的功能?是怎么做到的

  • 谢谢

    为什么不创建一个主轮询器,然后将异步资源请求踢到时间表上

    我不是使用Akka的专家,但我尝试过:

    遍历要获取的资源列表的轮询器对象:

    import akka.util.duration._
    import akka.actor._
    import play.api.Play.current
    import play.api.libs.concurrent.Akka
    
    object Poller {
      val poller = Akka.system.actorOf(Props(new Actor {
        def receive = {
          case x: String => Akka.system.actorOf(Props[ActingSpider], name=x.filter(_.isLetterOrDigit)) ! x
        }
      }))
    
      def start(l: List[String]): List[Cancellable] =
        l.map(Akka.system.scheduler.schedule(3 seconds, 3 seconds, poller, _))
    
      def stop(c: Cancellable) {c.cancel()}
    }
    
    异步读取资源并触发更多异步读取的参与者。您可以将消息调度安排在一个时间表上,而不是立即呼叫(如果它更友好):

    import akka.actor.{Props, Actor}
    import java.io.File
    
    class ActingSpider extends Actor {
      import context._
      def receive = {
        case name: String => {
          println("reading " + name)
          new File(name) match {
            case f if f.exists() => spider(f)
            case _ => println("File not found")
          }
          context.stop(self)
        }
      }
    
      def spider(file: File) {
        io.Source.fromFile(file).getLines().foreach(l => {
          val k = actorOf(Props[ActingSpider], name=l.filter(_.isLetterOrDigit))
          k ! l
        })
      }
    }
    

    我会更担心错误路径。如果特定中间路径出现瞬时故障,会发生什么情况;是否重试?任何给定子参与者的失败是否也会导致父参与者的失败?在足够大的范围内,你几乎肯定会有孩子们的短暂失败。