【发布时间】:2017-09-24 21:47:46
【问题描述】:
简而言之,我遇到了一个问题,即对我的 Node.js 服务器的多个并行 GET 请求导致服务器“阻塞”并挂起,从而导致客户端超时(503,服务不可用)。
经过大量性能分析后,我意识到这是 CPU 问题。具体请求(我们称之为GET /foo)通过HTTP从多个服务中查询数据,然后进行大量计算,并将结果返回给客户端,如下所示:
- 客户端请求
GET /foo -
/foo控制器通过 HTTP 从多个其他服务查询数据` -
/foo控制器然后对数据进行一系列迭代,为客户端编译一些输出
第 3 步大约需要 2 秒才能完成。但是,如果我向/foo 并行发送 2 个请求,每个客户端将在大约 4 秒内收到他们的响应。当我在使用更多内核的集群中运行应用程序时,请求运行得更快,但不是我想要的。
似乎我在这里有几个选择:
- 预先计算响应(最好暂时避免这种情况,因为它需要一个完整的“缓存失效”方案),或者
-
/foo将 CPU 阻塞计算异步发送到另一个进程(使用 Heroku,所以这将是另一个 dyno),然后我可以使用 websocket 或其他东西将结果推送到客户端(再次,对于我的情况非常复杂) , 或 - 以某种方式让出请求中的子进程并将结果返回给客户端
愿意做类似于选项 3 的事情。这样的事情:
get('/foo', function*(request) {
// I/O, so not blocking the event loop (I think)
let data = yield getData(request)
// make this happen in a different process
let response = yield doSomeHeavyProcessing(data)
return response
})
上面我省略了很多实现细节,但如果有必要知道,我使用的是Koa和Node.js 6。
理想情况下,doSomeHeavyProcessing 会在某个单独的进程中执行 CPU 密集型计算,完成后,仍以“同步”方式将结果发送回请求客户端。
我一直试图围绕子进程、网络工作者、纤维等进行思考,并且一直在用这些做一些基本的“hello world”,以使它们基本上完成上述操作,但无济于事。如有需要,可以发布更多详细信息。
【问题讨论】:
标签: javascript node.js heroku koa