国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

如何監(jiān)控 Node.js 線程的 CPU 負(fù)載?

開發(fā) 前端
為了更好地了解各個(gè)線程的 CPU 負(fù)載,需要提供線程級(jí)別的 CPU 負(fù)載數(shù)據(jù)。目前,Libuv 已經(jīng)支持該能力,在比較新的 Node.js 版本中也引入了該能力,本文介紹線程 CPU 負(fù)載獲取的相關(guān)內(nèi)容。

雖然 Node.js 本身是單線程應(yīng)用,但是也支持創(chuàng)建額外的線程。在一個(gè)單進(jìn)程多線程的應(yīng)用中,觀測(cè)線程的 CPU 負(fù)載是非常有意義且必要的,因?yàn)橥ㄟ^進(jìn)程 CPU 負(fù)載我們看到的只是進(jìn)程內(nèi)所有線程的 CPU 負(fù)載之和,但是無法知道每個(gè)線程的負(fù)載,這樣在 CPU 負(fù)載高時(shí),我們就無法知道是哪個(gè)線程導(dǎo)致的。為了更好地了解各個(gè)線程的 CPU 負(fù)載,需要提供線程級(jí)別的 CPU 負(fù)載數(shù)據(jù)。目前,Libuv 已經(jīng)支持該能力,在比較新的 Node.js 版本中也引入了該能力,本文介紹線程 CPU 負(fù)載獲取的相關(guān)內(nèi)容。

在做 Node.js APM 時(shí),我們已經(jīng)通過 Addon + getrusage 獲取了線程 CPU 負(fù)載,其原理很簡(jiǎn)單,getrusage 本身是支持獲取調(diào)用線程的 CPU 負(fù)載的,只不過之前因?yàn)槠脚_(tái)兼容性問題,Libuv 沒有支持該能力,現(xiàn)在 Libuv 兼容了更多平臺(tái)后,也是使用了類似的方式實(shí)現(xiàn)的。但是 Addon 一來比較麻煩,二來需要把代碼注入到目的線程,因?yàn)樵谀康木€程調(diào)用上面的函數(shù)才能獲取該線程的 CPU 負(fù)載,相對(duì)來說有一定的成本。

現(xiàn)在 Node.js 原生支持該能力后,首先解決了 Addon 的問題,我們只需要在目的線程調(diào)用 process.threadCpuUsage() 就能獲得當(dāng)前線程的 CPU 負(fù)載,但是問題二還是沒解決,還是需要進(jìn)行代碼注入,為了解決這個(gè)問題,我最近提交了一個(gè) PR,支持在主線程中獲取子線程的 CPU 負(fù)載,大致的用法如下。

const worker = new Worker(...);
await worker.cpuUsage();

這樣我們就可以通過 process 的 worker 事件獲取每個(gè) worker(或者通過 diagnostics_channel),從而獲取 worker 的 CPU 負(fù)載,不需要在每個(gè)線程里注入代碼。實(shí)現(xiàn)如下。

const { Worker } = require('worker_threads');

process.on('worker', (worker) => {
  setInterval(async () => {
   const data = await worker.cpuUsage();
   console.log(data);
  }, 1000);
});

new Worker("setInterval(() => {}, 10000)", { eval:true });

上面代碼就可以統(tǒng)一獲取所有線程的 CPU 負(fù)載,實(shí)現(xiàn)簡(jiǎn)單并且邏輯解耦。

最后介紹下實(shí)現(xiàn)細(xì)節(jié)。

cpuUsage() {
  const taker = this[kHandle]?.cpuUsage();
  return new Promise((resolve, reject) => {
    if (!taker) return reject(new ERR_WORKER_NOT_RUNNING());
    taker.ondone = (err, current) => {
      if (err !== null) {
        return reject(err);
      }
      resolve({
        user: current.user,
        system: current.system,
      });
    };
  });
}

因?yàn)椴僮魇窃谀康木€程完成的,所以實(shí)現(xiàn)上采用的是異步方式,同步會(huì)阻塞調(diào)用 cpuUsage 的線程,完全沒有必要。cpuUsage 依賴 C++ 層的實(shí)現(xiàn)。

void Worker::CpuUsage(const FunctionCallbackInfo<Value>& args) {
  Worker* w;
  ASSIGN_OR_RETURN_UNWRAP(&w, args.This());

  Environment* env = w->env();
  AsyncHooks::DefaultTriggerAsyncIdScope trigger_id_scope(w);
  Local<Object> wrap;
  if (!env->worker_cpu_usage_taker_template()
           ->NewInstance(env->context())
           .ToLocal(&wrap)) {
    return;
  }

  BaseObjectPtr<WorkerCpuUsageTaker> taker =
      MakeDetachedBaseObject<WorkerCpuUsageTaker>(env, wrap);
  // 給子線程提交一個(gè)任務(wù)
  bool scheduled = w->RequestInterrupt([taker = std::move(taker),
                                        env](Environment* worker_env) mutable {
    auto cpu_usage_stats = std::make_unique<uv_rusage_t>();
    // 在子線程執(zhí)行 uv_getrusage_thread 獲取其 CPU 負(fù)載
    int err = uv_getrusage_thread(cpu_usage_stats.get());
    // 獲取完畢,給調(diào)用線程提交一個(gè)任務(wù)
    env->SetImmediateThreadsafe(
        [taker = std::move(taker),
         cpu_usage_stats = std::move(cpu_usage_stats),
         err = err](Environment* env) mutable {
          
          Local<Value> argv[] = {
              Null(isolate),
              Undefined(isolate),
          };

          if (err) {
            argv[0] = UVException(
                isolate, err, "uv_getrusage_thread", nullptr, nullptr, nullptr);
          } else {
            Local<Name> names[] = {
                FIXED_ONE_BYTE_STRING(isolate, "user"),
                FIXED_ONE_BYTE_STRING(isolate, "system"),
            };
            Local<Value> values[] = {
                Number::New(isolate,
                            1e6 * cpu_usage_stats->ru_utime.tv_sec +
                                cpu_usage_stats->ru_utime.tv_usec),
                Number::New(isolate,
                            1e6 * cpu_usage_stats->ru_stime.tv_sec +
                                cpu_usage_stats->ru_stime.tv_usec),
            };
            argv[1] = Object::New(
                isolate, Null(isolate), names, values, arraysize(names));
          }
          // 調(diào)用者線程執(zhí)行 JS 回調(diào),即 JS 的 ondone
          taker->MakeCallback(env->ondone_string(), arraysize(argv), argv);
        },
        CallbackFlags::kUnrefed);
  });

  if (scheduled) {
    args.GetReturnValue().Set(wrap);
  }
}

C++ 的實(shí)現(xiàn)有一點(diǎn)復(fù)雜,主要是因?yàn)樯婕暗蕉嗑€程之前的操作,有興趣的同學(xué)可以參考 https://github.com/nodejs/node/pull/59177。

責(zé)任編輯:武曉燕 來源: 編程雜技
相關(guān)推薦

2021-03-09 08:03:21

Node.js 線程JavaScript

2011-09-09 14:23:13

Node.js

2021-05-21 09:36:42

開發(fā)技能代碼

2019-03-29 16:40:02

Node.js多線程前端

2022-06-23 06:34:56

Node.js子線程

2021-05-27 09:00:00

Node.js開發(fā)線程

2022-09-04 15:54:10

Node.jsAPI技巧

2015-03-10 10:59:18

Node.js開發(fā)指南基礎(chǔ)介紹

2021-12-18 07:42:15

Ebpf 監(jiān)控 Node.js

2013-11-01 09:34:56

Node.js技術(shù)

2021-08-04 23:30:28

Node.js開發(fā)線程

2022-01-29 22:27:31

內(nèi)核子線程應(yīng)用

2021-04-20 12:39:52

Node.js多線程多進(jìn)程

2023-06-20 06:44:14

Node.jsCPU 負(fù)載

2013-01-24 13:26:09

NginxNode.js高負(fù)載網(wǎng)絡(luò)

2021-12-25 22:29:57

Node.js 微任務(wù)處理事件循環(huán)

2020-05-29 15:33:28

Node.js框架JavaScript

2012-02-03 09:25:39

Node.js

2020-01-03 16:04:10

Node.js內(nèi)存泄漏

2023-03-02 23:09:53

Node.jsC++JS
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

2018av男人天堂| 中文字幕在线亚洲| 一级黄色片播放| 欧美视频亚洲视频| 深夜福利一区二区| 91精选在线| 亚洲综合免费观看高清完整版在线 | 久久九九免费视频| 日本调教视频在线观看| 秋霞影院一区二区| 国产精品久久久久久久一区探花| 国产乱码在线| 欧美日韩在线一区| 日韩中文字幕a| 国产福利91精品| 久久国产精品99久久久久久丝袜 | 久久久久久久欧美精品| 九九热精品在线| 国产91在线视频| 色噜噜一区二区| 久久蜜桃av| 日韩在线播放视频| 亚洲少妇视频| 91精品一区二区三区在线观看| 免费福利片在线观看| 国产高清一区日本| 亚洲精品久久区二区三区蜜桃臀| 在线观看日韩av电影| 成人激情综合网| 极品美女一区二区三区| 久久久噜噜噜久噜久久| 国产精品视频一区视频二区 | 黑料吃瓜在线观看| 国产精品萝li| 亚洲老女人av| 久久影视一区二区| 九九九九免费视频| 国产精品亚洲一区二区三区妖精 | 国产精品一区二区av交换| 精品少妇v888av| jizz亚洲女人高潮大叫| 亚洲欧美在线免费| 周于希免费高清在线观看| 精品国产自在久精品国产| 99青草视频在线播放视| 在线看一区二区| 久久伊伊香蕉| 欧美狂野另类xxxxoooo| 高清全集视频免费在线| 亚洲福利视频免费观看| 黄色在线免费观看网站| 亚洲人成五月天| 91亚洲精品在看在线观看高清| 日韩在线精品视频| 欧美影视资讯| 精品国偷自产在线视频| 国产色99精品9i| 国产91精品久久久久| 亚洲宅男一区| 国产成人a亚洲精品| 欧美mv日韩| 免费在线观看一区二区| 国内精品写真在线观看 | 国产一区二区三区四区老人| 成人激情直播| 捆绑紧缚一区二区三区视频| 四虎精品欧美一区二区免费| 成人看片黄a免费看在线| 噼里啪啦国语在线观看免费版高清版| 中文字幕亚洲在| 国产乱视频在线观看| 欧美大片顶级少妇| 色猫猫成人app| 欧美专区在线播放| 黄色日韩精品| 日本精品福利视频| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ原创 | 国产a级片免费看| 久久久99精品免费观看不卡| 久久久噜噜噜久久久| 国产女主播在线直播| 日韩精品高清在线| 一区二区日韩| 极品日韩久久| 91网站在线观看视频| 黄页网站视频在线观看| 欧美一区二区三区白人| 久久日本片精品aaaaa国产| 国产精品精品久久久| 日韩不卡一区二区| 加勒比在线日本| 黄色国产精品| 亚洲国产成人porn| 黑人极品ⅴideos精品欧美棵| 日韩亚洲一区二区| 97色伦图片97综合影院| 亚洲一区二区三区免费观看| 亚洲国产精品二十页| 3p在线观看| 午夜精品美女自拍福到在线| 久草在现在线| 国产精品一区二区久久精品爱涩| 99热在线免费播放| 亚洲精品乱码久久久久久按摩观| 卡一精品卡二卡三网站乱码| 久久人人爽爽人人爽人人片av| 久久综合九色综合97婷婷女人| 超碰免费在线| 8090成年在线看片午夜| 久久99精品视频| 一级毛片在线观| 欧美尺度大的性做爰视频| 国产一在线精品一区在线观看| 六月丁香婷婷在线| 欧美一区二区免费| 久久亚洲影视| 免费看黄色一级大片| 亚洲国产精品电影| 欧美日韩调教| x88av蜜桃臀一区二区| 久久视频在线播放| 久久成人麻豆午夜电影| 国产高清视频在线| 国产精品久久久久久超碰| 久久综合五月天婷婷伊人| 成人在线免费观看黄色| 成人欧美视频在线| 亚洲综合久久久久| 美女视频免费精品| 国产精品美女久久久久久久 | 国产亚洲欧美视频| 国产日韩一区| 桥本有菜亚洲精品av在线| 欧美大片免费观看在线观看网站推荐| 蜜桃av一区二区三区电影| 国产视频网址在线| 国产剧情日韩欧美| 亚洲一级二级三级| 网曝91综合精品门事件在线| www.超碰com| 色综合久久88色综合天天看泰| 成人中文字幕电影| 日本综合久久| 免费特级黄色片| 中文字幕欧美日韩精品| 国产福利视频一区二区三区| 18aaaa精品欧美大片h| 欧美日韩亚洲综合一区二区三区激情在线| 五月天久久比比资源色| 波多野结衣的一区二区三区 | 国内精品写真在线观看| 日本精品600av| 国产乱码一区| 欧美日本不卡视频| 亚洲中字黄色| 亚洲小说区图片| 亚洲一区高清| 亚洲美女喷白浆| 国产激情精品久久久第一区二区| 手机在线观看av| 日韩极品视频在线观看| 夜夜嗨av色一区二区不卡| 国产91精品入口| 国产剧情一区二区在线观看| 国产黄色特级片| 91成人在线观看国产| 一区二区三区在线观看动漫| 精品视频免费在线观看| 男男激情在线| 麻豆av一区| 日韩电影在线观看永久视频免费网站| 狠狠色丁香婷综合久久| se69色成人网wwwsex| wwwwww.色| 国产精品美女久久久久久免费| 天天色图综合网| 久久精品日产第一区二区 | 色综合网站在线| 国产精品日本| 一区二区三区电影大全| 亚洲精品无码久久久久久| 欧美一区二区三区四区在线| 亚洲成人动漫精品| 亚洲免费观看| 成人午夜视屏| 亚洲一级免费观看| 国产精品天天狠天天看| 欧美日韩精品一区二区三区蜜桃 | 国产精品视频一二| 久久不见久久见中文字幕免费| 亚洲欧洲成人| 神马影院我不卡| 久久综合久中文字幕青草| 一级做a爱片久久| 免费国产自线拍一欧美视频| 成人日韩精品| 在线麻豆国产传媒1国产免费| 欧美日韩一区二区视频在线观看| 日韩在线不卡视频| 精品成人国产在线观看男人呻吟|