scala – REST(Squeryl / Akka / Spray) – 吞吐量极低
我目前正在构建我的第一个基于RSS聚合器的REST API.我使用MemoryBasedDB或PostgresDB这两个特性中的一个来实现它.在每次访问根URL时,它将对feed进行异步调用以获取最新文章,并将其作为
XML字符串返回以进行解析.解析后,它作为Article对象保存在数据库中.
从功能上讲,这对我来说都很好.但是,当使用weighttp或gatling进行负载测试时,使用Postgres的1k请求/ 1k concurent用户将使用以下内容进行负载测试: 在weighttp: error: read() failed: Connection reset by peer (104) 在我的服务器日志中: final [WARN] [09/21/2014 14:45:27.224] [on-spray-can-akka.actor.default-dispatcher-36] [akka://on-spray-can/user/IO-HTTP/listener-0/523] Configured registration timeout of 1 second expired,stopping 我认为这与我的查询布局方式有关.它们是阻塞的,并且每个参与者都必须等待响应,它们背后的负载越来越高地堆积到故障点(超时).但是,在我的研究中,我只能找到this异步驱动程序用于postgres,目前与Squeryl不相容(根据我的理解). 如何更快地访问数据库?目前我使用Postgres达到~10-15req / s,使用内存持久性达到~400req / s. 我的模特: case class Article(id: Option[String],idint: Option[Int],title: String,author: String,published: String,updated: String,`abstract`: Option[String],content: Option[String],link: Option[String]) 我的疑问: trait PostgresDB extends Schema { val articles = table[Article]("articles") on(articles)(e => declare(e.idint is(unique))) def create(x: Article) = inTransaction { articles.insert(x) } def getAll: Set[Article] = inTransaction { from(articles)(article => select(article)).toSet } def getArticle(x: Int) = inTransaction { from(articles)(article => where(article.idint === Some(x)) select(article)).toList(0) } def printy = transaction { articles.schema.printDdl(println(_)) } } 到目前为止,我尝试过: >为连接池实现C3P0.没有真正的改变. 相关信息: >内核: > Linux 3.13.0-33-generic#58-Ubuntu SMP Tue Jul 29 16:45:05 UTC 2014 x86_64 x86_64 x86_64 GNU / Linux > Postgres 9.3 解决方法
是的我同意@experquiste,给db actor他们自己的调度程序,并将其线程池大小和actor数量调整为数据库可以处理的并发请求数.在此前面放置一个路由器.您应该测量数据库服务器磁盘队列长度.这应该在持续的高负载下保持稳定,继续添加线程,直到队列开始增长.
另一种方法是为数据库访问层使用线程池和期货.它似乎更容易配置,但缺乏监督和错误恢复. 我从未使用过squeryl,inTransaction块是否创建了db事务?你显示的数据库特征似乎不需要交易,你试过没有它们. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |