成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Node.js 指南(輕松分析Node.js應(yīng)用程序)

HitenDev / 1468人閱讀

摘要:要解決此問題,請(qǐng)對(duì)上述處理程序進(jìn)行一些小修改,以使用函數(shù)的異步版本以上基準(zhǔn)測(cè)試與你的應(yīng)用程序的異步版本的一個(gè)新的運(yùn)行結(jié)果好極了你的應(yīng)用程序現(xiàn)在每秒大約提供個(gè)請(qǐng)求,大約是同步哈希生成的倍,此外,平均延遲從之前的秒降至僅超過秒。

輕松分析Node.js應(yīng)用程序

有許多第三方工具可用于分析Node.js應(yīng)用程序,但在許多情況下,最簡(jiǎn)單的選擇是使用Node.js內(nèi)置的分析器,內(nèi)置的分析器使用V8內(nèi)部的分析器,在程序執(zhí)行期間定期對(duì)堆棧進(jìn)行采樣,它將這些樣本的結(jié)果以及重要的優(yōu)化事件(如jit編譯)記錄為一系列tick:

code-creation,LazyCompile,0,0x2d5000a337a0,396,"bp native array.js:1153:16",0x289f644df68,~
code-creation,LazyCompile,0,0x2d5000a33940,716,"hasOwnProperty native v8natives.js:198:30",0x289f64438d0,~
code-creation,LazyCompile,0,0x2d5000a33c20,284,"ToName native runtime.js:549:16",0x289f643bb28,~
code-creation,Stub,2,0x2d5000a33d40,182,"DoubleToIStub"
code-creation,Stub,2,0x2d5000a33e00,507,"NumberToStringStub"

在過去,你需要V8源代碼才能解釋tick,幸運(yùn)的是,最近在Node.js 4.4.0中引入了一些工具,可以方便地使用這些信息而無需從源代碼多帶帶構(gòu)建V8,讓我們看看內(nèi)置的分析器如何幫助提供對(duì)應(yīng)用程序性能的深入了解。

為了說明tick分析器的使用,我們將使用一個(gè)簡(jiǎn)單的Express應(yīng)用程序,我們的應(yīng)用程序?qū)⒂袃蓚€(gè)處理程序,一個(gè)用于向我們的系統(tǒng)添加新用戶:

app.get("/newUser", (req, res) => {
  let username = req.query.username || "";
  const password = req.query.password || "";

  username = username.replace(/[!@#$%^&*]/g, "");

  if (!username || !password || users.username) {
    return res.sendStatus(400);
  }

  const salt = crypto.randomBytes(128).toString("base64");
  const hash = crypto.pbkdf2Sync(password, salt, 10000, 512, "sha512");

  users[username] = { salt, hash };

  res.sendStatus(200);
});

另一個(gè)用于驗(yàn)證用戶身份驗(yàn)證嘗試:

app.get("/auth", (req, res) => {
  let username = req.query.username || "";
  const password = req.query.password || "";

  username = username.replace(/[!@#$%^&*]/g, "");

  if (!username || !password || !users[username]) {
    return res.sendStatus(400);
  }

  const { salt, hash } = users[username];
  const encryptHash = crypto.pbkdf2Sync(password, salt, 10000, 512, "sha512");

  if (crypto.timingSafeEqual(hash, encryptHash)) {
    res.sendStatus(200);
  } else {
    res.sendStatus(401);
  }
});

請(qǐng)注意,這些不是推薦的處理程序,用于在Node.js應(yīng)用程序中對(duì)用戶進(jìn)行身份驗(yàn)證,僅用于說明目的,你通常不應(yīng)該嘗試設(shè)計(jì)自己的加密身份驗(yàn)證機(jī)制,使用現(xiàn)有的,經(jīng)過驗(yàn)證的身份驗(yàn)證解決方案要好得多。

現(xiàn)在假設(shè)我們已經(jīng)部署了我們的應(yīng)用程序,用戶抱怨請(qǐng)求的延遲很高,我們可以使用內(nèi)置的分析器輕松運(yùn)行應(yīng)用程序:

NODE_ENV=production node --prof app.js

并使用ab(ApacheBench)在服務(wù)器上加點(diǎn)負(fù)荷:

curl -X GET "http://localhost:8080/newUser?username=matt&password=password"
ab -k -c 20 -n 250 "http://localhost:8080/auth?username=matt&password=password"

并得到一個(gè)ab輸出:

Concurrency Level:      20
Time taken for tests:   46.932 seconds
Complete requests:      250
Failed requests:        0
Keep-Alive requests:    250
Total transferred:      50250 bytes
HTML transferred:       500 bytes
Requests per second:    5.33 [#/sec] (mean)
Time per request:       3754.556 [ms] (mean)
Time per request:       187.728 [ms] (mean, across all concurrent requests)
Transfer rate:          1.05 [Kbytes/sec] received

...

Percentage of the requests served within a certain time (ms)
  50%   3755
  66%   3804
  75%   3818
  80%   3825
  90%   3845
  95%   3858
  98%   3874
  99%   3875
 100%   4225 (longest request)

從這個(gè)輸出中,我們看到我們每秒只能處理大約5個(gè)請(qǐng)求,平均請(qǐng)求往返只需不到4秒。在實(shí)際示例中,我們可以代表用戶請(qǐng)求在許多函數(shù)中執(zhí)行大量工作,但即使在我們的簡(jiǎn)單示例中也是如此,編譯正則表達(dá)式、生成隨機(jī)salt、從用戶密碼生成唯一哈希,或者在Express框架內(nèi)部,時(shí)間可能會(huì)損失。

由于我們使用--prof選項(xiàng)運(yùn)行我們的應(yīng)用程序,因此在與本地應(yīng)用程序運(yùn)行相同的目錄中生成了一個(gè)tick文件,它的格式應(yīng)為isolate-0xnnnnnnnnnnnn-v8.log(其中n為數(shù)字)。

為了理解這個(gè)文件,我們需要使用與Node.js二進(jìn)制文件捆綁在一起的tick處理器,要運(yùn)行處理器,請(qǐng)使用--prof-process標(biāo)志:

node --prof-process isolate-0xnnnnnnnnnnnn-v8.log > processed.txt

在你喜歡的文本編輯器中打開processed.txt將為你提供一些不同類型的信息,該文件被分解為多個(gè)部分,這些部分再次被語(yǔ)言分解,首先,我們查看匯總部分,并查看:

[Summary]:
   ticks  total  nonlib   name
     79    0.2%    0.2%  JavaScript
  36703   97.2%   99.2%  C++
      7    0.0%    0.0%  GC
    767    2.0%          Shared libraries
    215    0.6%          Unaccounted

這告訴我們收集的所有樣本中有97%發(fā)生在C++代碼中,當(dāng)查看處理輸出的其他部分時(shí),我們應(yīng)該最關(guān)注用C++完成的工作(而不是JavaScript),考慮到這一點(diǎn),我們接下來找到[C++]部分,其中包含有關(guān)哪些C++函數(shù)占用最多CPU時(shí)間的信息,并查看:

[C++]:
   ticks  total  nonlib   name
  19557   51.8%   52.9%  node::crypto::PBKDF2(v8::FunctionCallbackInfo const&)
   4510   11.9%   12.2%  _sha1_block_data_order
   3165    8.4%    8.6%  _malloc_zone_malloc

我們看到前三個(gè)條目占該程序占用CPU時(shí)間的72.1%,從這個(gè)輸出中,我們立即看到至少51.8%的CPU時(shí)間被一個(gè)名為PBKDF2的函數(shù)占用,這個(gè)函數(shù)對(duì)應(yīng)于我們從用戶密碼生成哈希。但是,較低的兩個(gè)條目如何影響我們的應(yīng)用程序可能不會(huì)立即顯而易見(或者如果我們?yōu)榱耸纠傺b其他方式),為了更好地理解這些函數(shù)之間的關(guān)系,接下來我們將看一下[Bottom up(heavy)profile]部分,它提供了有關(guān)每個(gè)函數(shù)的主要調(diào)用者的信息,檢查此部分,我們發(fā)現(xiàn):

ticks parent  name
  19557   51.8%  node::crypto::PBKDF2(v8::FunctionCallbackInfo const&)
  19557  100.0%    v8::internal::Builtins::~Builtins()
  19557  100.0%      LazyCompile: ~pbkdf2 crypto.js:557:16

   4510   11.9%  _sha1_block_data_order
   4510  100.0%    LazyCompile: *pbkdf2 crypto.js:557:16
   4510  100.0%      LazyCompile: *exports.pbkdf2Sync crypto.js:552:30

   3165    8.4%  _malloc_zone_malloc
   3161   99.9%    LazyCompile: *pbkdf2 crypto.js:557:16
   3161  100.0%      LazyCompile: *exports.pbkdf2Sync crypto.js:552:30

解析此部分需要比上面的原始tick計(jì)數(shù)更多的工作,在上面的每個(gè)“調(diào)用堆棧”中,parent列中的百分比告訴你當(dāng)前行中的函數(shù)調(diào)用上面行中的函數(shù)的樣本百分比。例如,在sha1block_data_order上面的中間“調(diào)用堆?!敝校覀兛吹?b>_sha1_block_data_order出現(xiàn)在11.9%的樣本中,我們從上面的原始計(jì)數(shù)中知道了。但是,在這里,我們還可以告訴它始終由Node.js加密模塊中的pbkdf2函數(shù)調(diào)用,我們看到類似地,_malloc_zone_malloc幾乎完全由相同的pbkdf2函數(shù)調(diào)用。因此,使用此視圖中的信息,可以告訴我們,用戶密碼帳戶的哈希計(jì)算不僅僅是上面的51.8%,而且對(duì)于前3個(gè)最多采樣函數(shù)中的所有CPU時(shí)間,因?yàn)閷?duì)_sha1_block_data_order_malloc_zone_malloc的調(diào)用是代表pbkdf2函數(shù)進(jìn)行的。

此時(shí),很明顯基于密碼的哈希生成應(yīng)該是我們優(yōu)化的目標(biāo),值得慶幸的是,你已完全內(nèi)化了異步編程的優(yōu)勢(shì),并且你意識(shí)到從用戶密碼生成哈希的工作是以同步方式完成的,從而束縛事件循環(huán),這阻止我們?cè)谟?jì)算哈希時(shí)處理其他傳入請(qǐng)求。

要解決此問題,請(qǐng)對(duì)上述處理程序進(jìn)行一些小修改,以使用pbkdf2函數(shù)的異步版本:

app.get("/auth", (req, res) => {
  let username = req.query.username || "";
  const password = req.query.password || "";

  username = username.replace(/[!@#$%^&*]/g, "");

  if (!username || !password || !users[username]) {
    return res.sendStatus(400);
  }

  crypto.pbkdf2(password, users[username].salt, 10000, 512, (err, hash) => {
    if (users[username].hash.toString() === hash.toString()) {
      res.sendStatus(200);
    } else {
      res.sendStatus(401);
    }
  });
});

以上ab基準(zhǔn)測(cè)試與你的應(yīng)用程序的異步版本的一個(gè)新的運(yùn)行結(jié)果:

Concurrency Level:      20
Time taken for tests:   12.846 seconds
Complete requests:      250
Failed requests:        0
Keep-Alive requests:    250
Total transferred:      50250 bytes
HTML transferred:       500 bytes
Requests per second:    19.46 [#/sec] (mean)
Time per request:       1027.689 [ms] (mean)
Time per request:       51.384 [ms] (mean, across all concurrent requests)
Transfer rate:          3.82 [Kbytes/sec] received

...

Percentage of the requests served within a certain time (ms)
  50%   1018
  66%   1035
  75%   1041
  80%   1043
  90%   1049
  95%   1063
  98%   1070
  99%   1071
 100%   1079 (longest request)

好極了!你的應(yīng)用程序現(xiàn)在每秒大約提供20個(gè)請(qǐng)求,大約是同步哈希生成的4倍,此外,平均延遲從之前的4秒降至僅超過1秒。

希望通過對(duì)這個(gè)(公認(rèn)的設(shè)計(jì))示例的性能調(diào)查,你已經(jīng)了解了V8 tick處理器如何幫助你更好地了解Node.js應(yīng)用程序的性能。

上一篇:入門指南 下一篇:Docker化Node.js Web應(yīng)用程序

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/99173.html

相關(guān)文章

  • Node.js 指南(目錄)

    Node.js 指南 Node.js?是基于Chrome的V8 JavaScript引擎構(gòu)建的JavaScript運(yùn)行時(shí)。 常規(guī) 關(guān)于Node.js 入門指南 輕松分析Node.js應(yīng)用程序 Docker化Node.js Web應(yīng)用程序 遷移到安全的Buffer構(gòu)造函數(shù) Node.js核心概念 阻塞與非阻塞概述 Node.js事件循環(huán)、定時(shí)器和process.nextTick() 不要阻塞事...

    未東興 評(píng)論0 收藏0
  • Node.js 指南(Docker化Node.js Web應(yīng)用程序

    摘要:化應(yīng)用程序此示例的目的是向你展示如何將應(yīng)用程序放入容器中,該指南旨在用于開發(fā),而不用于生產(chǎn)部署,本指南還假設(shè)你有一個(gè)有效的安裝,并且基本了解應(yīng)用程序的結(jié)構(gòu)。 Docker化Node.js Web應(yīng)用程序 此示例的目的是向你展示如何將Node.js應(yīng)用程序放入Docker容器中,該指南旨在用于開發(fā),而不用于生產(chǎn)部署,本指南還假設(shè)你有一個(gè)有效的Docker安裝,并且基本了解Node.js應(yīng)...

    李世贊 評(píng)論0 收藏0
  • Node.js 指南(入門指南

    摘要:調(diào)試指南本指南將幫助你入門調(diào)試應(yīng)用程序和腳本。這樣做可能會(huì)給你帶來潛在的重大安全威脅,我們建議你確保適當(dāng)?shù)姆阑饓驮L問控制措施,以防止安全風(fēng)險(xiǎn)。不再維護(hù)或記錄調(diào)試協(xié)議。 入門指南 安裝Node之后,讓我們嘗試構(gòu)建我們的第一個(gè)Web服務(wù)器,創(chuàng)建名為app.js的文件,并粘貼以下代碼: const http = require(http); const hostname = 127.0....

    ybak 評(píng)論0 收藏0
  • 前端資源分享-只為更好前端

    摘要:一團(tuán)隊(duì)組織網(wǎng)站說明騰訊團(tuán)隊(duì)騰訊前端團(tuán)隊(duì),代表作品,致力于前端技術(shù)的研究騰訊社交用戶體驗(yàn)設(shè)計(jì),簡(jiǎn)稱,騰訊設(shè)計(jì)團(tuán)隊(duì)網(wǎng)站騰訊用戶研究與體驗(yàn)設(shè)計(jì)部百度前端研發(fā)部出品淘寶前端團(tuán)隊(duì)用技術(shù)為體驗(yàn)提供無限可能凹凸實(shí)驗(yàn)室京東用戶體驗(yàn)設(shè)計(jì)部出品奇舞團(tuán)奇虎旗下前 一、團(tuán)隊(duì)組織 網(wǎng)站 說明 騰訊 AlloyTeam 團(tuán)隊(duì) 騰訊Web前端團(tuán)隊(duì),代表作品WebQQ,致力于前端技術(shù)的研究 ISUX 騰...

    zxhaaa 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<