You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// src/node_http2.ccintHttp2Session::OnStreamClose(nghttp2_session*handle,
int32_tid,
uint32_tcode,
void*user_data) {
Http2Session*session=static_cast<Http2Session*>(user_data);
Environment*env=session->env();
Isolate*isolate=env->isolate();
HandleScopescope(isolate);
Local<Context>context=env->context();
Context::Scopecontext_scope(context);
Debug(session, "stream %d closed with code: %d", id, code);
BaseObjectPtr<Http2Stream>stream=session->FindStream(id);
// Intentionally ignore the callback if the stream does not exist or has// already been destroyedif (!stream||stream->is_destroyed())
return0;
stream->Close(code);
// It is possible for the stream close to occur before the stream is// ever passed on to the javascript side. If that happens, the callback// will return false.Local<Value>arg=Integer::NewFromUnsigned(isolate, code);
MaybeLocal<Value>answer=stream->MakeCallback(env->http2session_on_stream_close_function(),
1, &arg);
if (answer.IsEmpty() ||answer.ToLocalChecked()->IsFalse()) {
// Skip to destroystream->Destroy();
}
return0;
}
问题背景
y 同学反映电脑换成 M2 后,使用 nopack 开发时经常会出现 CPU 占用 100% 的情况,已经严重影响到了开发效率
相比于 webpack 这样的 bundler 📦 打包后产物只有少量的文件,Vite 与 nopack 这样的 bundless ⚡️ 工具不会在开发模式下打包应用的源代码。 这两者是基于浏览器 native ES Modules,这样的模式让热更新无比的快速,因为只需编译转换一个文件,不用像 bundler 那样从头开始打包
所以 bundless 工具开发模式下往往会出现大量的小文件请求,对于性能较差的电脑 Google Chrome 进程出现短暂的 CPU 占用 100% 的情况还是比较常见
该同学使用的是最强 M2,问题表现是 nopack 进程偶现 CPU 占用 100% 且不会下降,这属实让人一下难以接受
问题排查
一开始只能要 y 同学通过 node --cpu-prof 选项去启动 nopack,当程序退出时希望够从自动生成的 .cpuprofile 文件中找到突破口
遗憾的是如上图 .cpuprofile 文件中未能发现 🔍 有占用 CPU 过高的函数,没有发现较大价值的线索。另一个问题是 10次退出程序中大概只有 1次会生成 .cpuprofile 文件 🥲,分析文件的生成也不稳定 ...
下一步的排查中我在 nopack 代码中加入了如下的心跳检测代码,确认进程是不是真瘫痪了
结果是当 CPU 占用到了 100% 时,setInterval 里面的 console 也停止了,此时基本确认了进程可能陷入了某种致命错误或者死循环中,这大概率是程序的 bug 了 🐛
最后只能寄希望于调试利器 lldb 了,来看看进程卡死后,最后运行的代码是什么
通过 lldb 线程的堆栈回溯,发现了最后堆栈的停留在了
node::http2::Http2Session::OnStreamClose
函数调用,这是一个很可疑的点因为对比一个正常运行的 nopack 进程的堆栈回溯时,已经运行结束的
node::http2::Http2Session::OnStreamClose
等函数就没有出现在如下的堆栈中前面说了 bundless 工具开发模式下往往会出现大量的小文件请求,所以 nopack 默认是 http2 协议启动,相比于 http1 协议能够大幅提升并发请求
而这里显示停留在了 Node.js http2 的 OnStreamClose 方法,如果尝试使用 http1 协议来启动没有问题就说明了 CPU 占用 100% 极有可能是 Node.js http2 在 M2 中的一个 bug
问题小结
使用 http1 协议后暂未能再复现 CPU 占用 100% 的问题,至于是不是 Node.js http2 的 bug,还需打个 Node.js debug 包来进行排查与确认,只能后续需求不忙再跟进了
The text was updated successfully, but these errors were encountered: