上游非常快,然后是非常缓慢的下游和内存不足问题

时间:2017-09-27 04:22:11

标签: scala playframework akka slick

我一直把从摆弄akka溪流的经验带到实用的水平,我遇到了麻烦。 下面是我尝试编写一个流式管道,从一个非常大的数据库表读取特定的行,然后为每一行发送http调用到外部Web服务,而不是将收到的响应插入到另一个表:

(数据库库为slick,http客户端为播放框架)

val query = (catalogIndices joinLeft catalogSummeries on ((i, s) => i.productId === s.icecatId) filter (t => t._2.isEmpty) map (_._1)).result
val source = Source.fromPublisher(db.stream(query))
source
  .buffer(5, OverflowStrategy.backpressure)
  .mapAsync(5) { i =>
    icecatService.fetchCatalog(i.productId, Languages.en, IcecatService.Contents.all)
  }
  .map { r =>
    for {
      g <- (r.json \ "data" \ "GeneralInfo").validate[GeneralInfo]
      img <- (r.json \ "data" \ "Image").validate[Image]
    } yield (g, img)
  }
  .collect {
    case JsSuccess((g, img), _) => CatalogSummeryData(g.IcecatId, g.Title, g.Brand, g.ProductName, g.BrandPartCode,
      g.GTIN, g.Category.CategoryID, g.Category.Name.Value, img.LowPic, img.ThumbPic)
  }
  .grouped(100)
  .runForeach(s => db.run(catalogSummeries ++= s))

我可以说db作为上游非常快,而且那些Web服务调用真的很慢。如果我进一步增加mapAsync方法的并行数,我的所有期货都会超时。 当我将项目的整个平台从Vagrant虚拟机迁移到我的Windows 10时,我的问题就出现了。现在,我的代码中的每一件事都运行得更快,但是这段流总是导致GC错误或内存不足错误等等。 。回到虚拟机我曾经让这段代码运行并成功传输了4000个结果。我应该如何调整此代码以使其执行?

编辑:另外我必须提一下,在我的Windows机器上,绝对不会在所有行都关闭之前插回行。

编辑:我收到了很多类型的错误,但这里有一个常见错误:

[ERROR] [SECURITY][09/27/2017 07:23:33.046] [application-scheduler-1] 
[akka.actor.ActorSystemImpl(application)] Uncaught error from thread 
[application-scheduler-1]: GC overhead limit exceeded, shutting down 
ActorSystem[application]
java.lang.OutOfMemoryError: GC overhead limit exceeded
    at akka.dispatch.AbstractNodeQueue.<init>(AbstractNodeQueue.java:32)
    at akka.actor.LightArrayRevolverScheduler$TaskQueue.<init (LightArrayRevolverScheduler.scala:304)
    at akka.actor.LightArrayRevolverScheduler$$anon$4.nextTick(LightArrayRevolverScheduler.scala:269)
    at akka.actor.LightArrayRevolverScheduler$$anon$4.run(LightArrayRevolverScheduler.scala:235)
    at java.lang.Thread.run(Thread.java:748)

0 个答案:

没有答案