【问题标题】:Delay in processing more requests/sec处理更多请求的延迟/秒
【发布时间】:2016-04-09 04:16:18
【问题描述】:

我有一个使用赛璐珞的 JRuby 应用程序。它通过 Zeromq 套接字接收请求并以 JSON 字符串响应。

所以,我的应用程序中有 2 个参与者,一个用于处理请求,另一个用于发送响应(Zeromq 中的推送套接字)。 应用程序以大约 30 个请求/秒的速度接收请求,未来会更多,例如 1000 个/秒。但是随着每秒请求数量的增加,处理需要更多时间。它开始使用更多的 CPU。

对于每个收到的请求,我都在 defer 块中处理它。

defer {
  response = ResponseHandler.new(socket,message).start
  send_response(response)
}

对于 20 个请求/秒,它可以正常工作,没有任何延迟。该服务器具有 15Gb RAM 和 4 个内核的配置。 它还连接到 Postgres DB 和 Redis DB。但这似乎不是问题。

这是我的基本结构, 有主角Service,

supervisor = Service.supervise

这会在内部创建具有 10 个池的 PushSock Actor 实例。

@pushsocket_actor = PushSock.pool(size: 10)

上面 defer 块中的 send_response 方法调用 pushsocket actor。在 defer 块中 ResponseHandler 不是 Actor。

所以对于 Service Actor,我没有使用池。

【问题讨论】:

  • 你是直接使用Celluliod::IO吗?你有任何代码要点吗?
  • 不,我没有使用 Celluliod::IO

标签: multithreading jruby celluloid


【解决方案1】:

使用游泳池。

现在您正在使用内部线程池...它不断产生新线程。相反,创建一个参与者池,然后使用async 调用...这实际上会减少一次运行的任务数量。这将加快响应时间,因为它将全速进行处理,而不仅仅是接受请求。

不过,您需要对自己的资源需求保持现实!您知道每个请求需要多少吗?您需要根据此计划制定演员策略。

不要使用太多或太少的演员。现在,我怀疑你使用了太多线程,因为使用defer {} 不会像async 那样设置限制,如果与实际大小的池一起使用的话。

【讨论】:

  • 我已经用应用程序的基本结构更新了我的问题。所以你的意思是我不应该使用 defer 而是使用 async 吗?
  • async 使用不同类型的代理——defer {} 调用使用Future 代理,并且不受限制。如果您使用池和async,它会将async 的调用次数限制为池中的参与者数量......这很重要。
  • 好的。我在这里观察到了另一种行为,最大活动线程数是 20 个线程,大约 30 个请求/秒。但是在一定时间后发现 CPU 峰值。 CPU使用率突然上升。这与您的答案有关吗?请求处理(延迟块)在几毫秒内完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-04
  • 1970-01-01
  • 1970-01-01
  • 2017-02-13
  • 1970-01-01
  • 2022-01-20
相关资源
最近更新 更多