帶你一起擼一遍 nodejs 常用核心模組(三)

xlei1123發表於2019-02-27

壓縮模組

zlib 可以用來實現對 HTTP 中定義的 gzip 和 deflate 內容編碼機制的支援。
HTTP 的 Accept-Encoding 頭欄位用來標記客戶端接受的壓縮編碼。
使用 zlib 編碼成本會很高, 結果應該被快取。(下面的演示程式碼只演示壓縮)

//compresss方法實現壓縮 
compress(req, res, statObj, realPat) {    //實現壓縮功能
    let encoding = req.headers[`accept-encoding`];   //瀏覽器請求頭會自動帶上accept-encoding 告訴 伺服器支援哪幾種壓縮格式
    if (encoding) {
        if (encoding.match(/gzip/)) {
            res.setHeader(`content-encoding`,`gzip`)
            return zlib.createGzip()    //返回壓縮流  let zip = compress(req, res, statObj, realPat); 
            //通過fs.createReadStream(realPath).pipe(zip).pipe(res) 返回給客戶端
        } else if (encoding.match(/deflate/)) {
            res.setHeader(`content-encoding`, `deflate`)
            return zlib.createDeflate();  //返回壓縮流  let zip = compress(req, res, statObj, realPat); 
            //通過fs.createReadStream(realPath).pipe(zip).pipe(res) 返回給客戶端
        } else {
            return false
        }
    } else {
        return false
    }
}
複製程式碼

加密和摘要演算法

crypto 模組提供了加密功能,包含對 OpenSSL 的雜湊、HMAC、加密、解密、簽名、以及驗證功能的一整套封裝.

let crypto = require(`crypto`);
console.log(crypto.getHashes());
[ `DSA`,
  `DSA-SHA`,
  `DSA-SHA1`,
  `DSA-SHA1-old`,
  `RSA-MD4`,
  `RSA-MD5`,
  `RSA-MDC2`,
  `RSA-RIPEMD160`,
  `RSA-SHA`,
  `RSA-SHA1`,
  `RSA-SHA1-2`,
  `RSA-SHA224`,
  `RSA-SHA256`,
  `RSA-SHA384`,
  `RSA-SHA512`,
  `dsaEncryption`,
  `dsaWithSHA`,
  `dsaWithSHA1`,
  `dss1`,
  `ecdsa-with-SHA1`,
  `md4`,
  `md4WithRSAEncryption`,
  `md5`,
  `md5WithRSAEncryption`,
  `mdc2`,
  `mdc2WithRSA`,
  `ripemd`,
  `ripemd160`,
  `ripemd160WithRSA`,
  `rmd160`,
  `sha`,
  `sha1`,
  `sha1WithRSAEncryption`,
  `sha224`,
  `sha224WithRSAEncryption`,
  `sha256`,
  `sha256WithRSAEncryption`,
  `sha384`,
  `sha384WithRSAEncryption`,
  `sha512`,
  `sha512WithRSAEncryption`,
  `shaWithRSAEncryption`,
  `ssl2-md5`,
  `ssl3-md5`,
  `ssl3-sha1`,
  `whirlpool` ]
複製程式碼
//幾種常用的
let crypto = require(`crypto`);

// console.log(crypto.getHashes());
// 摘要演算法
let str = `hello`;
let r = crypto.createHash(`md5`).update(str).digest(`hex`);
console.log(r)

let crypto = require(`crypto`);
let r2 = crypto.createHash(`md5`).update(`hello`).digest(`hex`)
console.log(r2)
let r1 = crypto.createHash(`md5`).update(`h`).update(`ell`).update(`o`).digest(`hex`)
console.log(r1)

// 加鹽演算法
let mac = crypto.createHmac(`sha256`, `xl`);  //用雜湊演算法,以一個金鑰和一個訊息為輸入,生成一個訊息摘要作為輸出
let r = mac.update(`hello`).digest(`hex`)
console.log(r)
複製程式碼

process – 程式

程式(Process)是計算機中的程式關於某資料集合上的一次執行活動,是系統進行資源分配和排程的基本單位,是作業系統結構的基礎。程式是執行緒的容器。程式是指令、資料及其組織形式的描述,程式是程式的實體。

process 物件是一個全域性變數,它提供當前 Node.js 程式的有關資訊,以及控制當前 Node.js 程式。

  1. `exit` 事件

兩種情況下 `exit` 事件會被觸發:

  • 顯式呼叫 process.exit() 方法,使得 Node.js 程式即將結束;
  • Node.js 事件迴圈陣列中不再有額外的工作,使得 Node.js 程式即將結束。
  1. `message` 事件

訊息通過 childprocess.send() 傳送),會觸發 `message` 事件。具體用法演示下面額外管道 ipc模式有.
3. `kill` 事件 — 注意只有父程式才可以kill子程式

process.kill(pid[, signal]) //pid 程式id 可以通過process.pid獲取

child_process – 子程式

父子程式之間建立管道有三種模式 pipe/0,1,2/ignore,

  1. 預設情況下,子程式的 stdin、 stdout 和 stderr 會重定向到 ChildProcess 物件上相應的 subprocess.stdin、 subprocess.stdout 和 subprocess.stderr 流
  2. 0,1,2是共享輸入輸出(繼承父程式輸入輸出)的不再演示
  3. ignore

額外的 fd 可以被指定來建立父程式和子程式之間的額外管道

1.額外管道pipe模式

//pipe模式

//主程式
let {spawn} = require(`child_process`);
let path = require(`path`);
// 啟動一個子程式
let child = spawn(`node`, [`sub_process1.js`, `--port`, `3000`], {
    cwd: path.join(__dirname, `test`),            //sub_prpcesss1.js檔案路徑
    stdio:[0,1,2,`pipe`]          //預設pipe  (stdin、stdout 和 stderr  --> 0、1 和 2  ==>共享標準輸入,標準輸出,錯誤輸出)
})
child.stdout.on(`data`, function (data) {  //接收子程式的資料
    console.log(data.toString())
})

//被啟動的子程式
console.log(process.argv)  //子程式輸出資料
process.stdout.write(`123`)   //
---------------------------------------------------
//最終在控制檯打出的結果
[ `C:\Program Files\nodejs\node.exe`,
  `c:\Users\Administrator\Desktop\growth_plan\Everest4\22.process\test\sub_process1.js`,
  `--port`,
  `3000` ]
複製程式碼
  1. 額外管道 ipc模式
// on  send

//主程式
let {spawn} = require(`child_process`);
let path = require(`path`);

let child = spawn(`node`, [`03.ipc.js`,],{
    cwd:path.join(__dirname, `test`),
    stdio:[0,1,2,`ipc`]  
})
child.on(`message`, function(data){
    console.log(data);
    child.send(`world`);
    // process.kill(child.pid)   //主程式可以強制殺死子程式
})

// 子程式 03.ipc.js
process.send(`hello`);

process.on(`message`,function(data){
    console.error(data);
    process.exit();   //執行完退出程式
})
複製程式碼

另外常用的fork其實就是衍生一個新的 Node.js 程式,並通過建立 IPC 通訊通道來呼叫指定的模組,該通道允許父程式與子程式之間相互傳送資訊。

//主程式
let {fork} = require(`child_process`);
let path = require(`path`);
let child = fork(`04.fork.js`,[`a`,`b`],{
    cwd:path.join(__dirname,`test`),
    silent:false                           // 如果為 true,則子程式中的 stdin、 stdout 和 stderr 會被導流到父程式中,否則它們會繼承自父程式。
})

child.send(`hello`)
child.on(`message`, function(data) {
    console.log(data)
})
//子程式 04.fork.js
process.send(`end`)
process.on(`message`, function(data) {
    console.log(data)
    process.exit()
})
複製程式碼

叢集

為了提高伺服器的利用率,能不能多核的來處理呢?於是就有了cluster模組。
cluster模組可以輕鬆實現執行在同一機器不同程式上的TCP或HTTP伺服器叢集。它們仍使用相同的底層套接字,從而在相同的IP地址和埠組合上處理請求。

程式並不是開的越多越好,一般是伺服器有幾核一般開幾個程式;

let cluster = require(`cluster`);
let http = require(`http`);

let len = require(`os`).cpus().length;   //獲取cpu的核數
if (cluster.isMaster) {//主程式 
    for(let i = 0; i<len; i++) {     //有幾核就開幾個子程式   
        cluster.fork()     
    }
} else {
    http.createServer(function(req, res) {
        res.end(`child`+process.pid)
    }).listen(3000)
}
複製程式碼
//主程式
let os = require(`os`);

let {fork} = require(`child_process`);
let path = require(`path`);
let http = require(`http`);

let server = http.createServer(function(req, res) {
    res.end(`xxx`);
})
server.listen(3000)    //開了一個3000埠
for(let i = 0; i<os.cpus().length;i++){
    let child = fork(`1.server.js`,{
        cwd: path.join(__dirname),
        silent:false
    });

    child.send(`server`, server)    //公用服務
}
//子程式 1.server.js
let http = require(`http`);
process.on(`message`,function(data,server){
    http.createServer(function(req,res){
        res.end(`child`+process.pid)
    }).listen(server); // 子程式公用這個服務
});
複製程式碼

以上就是nodejs的常用核心模組的一部分,因為涉及的內容比較多並沒有深入進去,特別是加密和摘要演算法這一塊,我也僅僅是會用,其實每個部分都可以展開裡面有很多知識,很多深入的知識我本人也不是很瞭解,希望上面的一些核心內容能夠幫助到你,當然有很多不足之處希望朋友們提出指正。也希望和各位朋友一起學習分享!

相關內容:

  1. nodejs常用核心模組(一)
  2. nodejs常用核心模組(二)

後記:

nodejs常用核心模組到這裡就結束了,可能有很多零零散散的一些知識點沒有提到,希望大家看完這一系列的文章有一些收穫,同時有不足之處和常用但是沒有提到的知識點希望朋友們提出指正,互相交流,共同進步!

相關文章