国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

Node.Js中實現端口重用原理詳解

2024-05-06 15:34:41
字體:
來源:轉載
供稿:網友

本文介紹了Node.Js中實現端口重用原理詳解,分享給大家,具體如下:

起源,從官方實例中看多進程共用端口

const cluster = require('cluster');const http = require('http');const numCPUs = require('os').cpus().length;if (cluster.isMaster) { console.log(`Master ${process.pid} is running`); for (let i = 0; i < numCPUs; i++) {  cluster.fork(); } cluster.on('exit', (worker, code, signal) => {  console.log(`worker ${worker.process.pid} died`); });} else { http.createServer((req, res) => {  res.writeHead(200);  res.end('hello world/n'); }).listen(8000); console.log(`Worker ${process.pid} started`);}

執行結果:

$ node server.js
Master 3596 is running
Worker 4324 started
Worker 4520 started
Worker 6056 started
Worker 5644 started

了解http.js模塊:

我們都只有要創建一個http服務,必須引用http模塊,http模塊最終會調用net.js實現網絡服務

// lib/net.js'use strict'; ...Server.prototype.listen = function(...args) {  ... if (options instanceof TCP) {   this._handle = options;   this[async_id_symbol] = this._handle.getAsyncId();   listenInCluster(this, null, -1, -1, backlogFromArgs); // 注意這個方法調用了cluster模式下的處理辦法   return this;  }  ...};function listenInCluster(server, address, port, addressType,backlog, fd, exclusive) {// 如果是master 進程或者沒有開啟cluster模式直接啟動listenif (cluster.isMaster || exclusive) {  //_listen2,細心的人一定會發現為什么是listen2而不直接使用listen // _listen2 包裹了listen方法,如果是Worker進程,會調用被hack后的listen方法,從而避免出錯端口被占用的錯誤  server._listen2(address, port, addressType, backlog, fd);  return; } const serverQuery = {  address: address,  port: port,  addressType: addressType,  fd: fd,  flags: 0 };// 是fork 出來的進程,獲取master上的handel,并且監聽,// 現在是不是很好奇_getServer方法做了什么 cluster._getServer(server, serverQuery, listenOnMasterHandle);} ...

答案很快就可以通過cluster._getServer 這個函數找到

    代理了server._listen2 這個方法在work進程的執行操作 向master發送queryServer消息,向master注冊一個內部TCP服務器
// lib/internal/cluster/child.jscluster._getServer = function(obj, options, cb) { // ... const message = util._extend({  act: 'queryServer',  // 關鍵點:構建一個queryServer的消息  index: indexes[indexesKey],  data: null }, options); message.address = address;// 發送queryServer消息給master進程,master 在收到這個消息后,會創建一個開始一個server,并且listen send(message, (reply, handle) => {   rr(reply, indexesKey, cb);       // Round-robin. }); obj.once('listening', () => {  cluster.worker.state = 'listening';  const address = obj.address();  message.act = 'listening';  message.port = address && address.port || options.port;  send(message); });}; //... // Round-robin. Master distributes handles across workers.function rr(message, indexesKey, cb) {  if (message.errno) return cb(message.errno, null);  var key = message.key;  // 這里hack 了listen方法  // 子進程調用的listen方法,就是這個,直接返回0,所以不會報端口被占用的錯誤  function listen(backlog) {    return 0;  }  // ...  const handle = { close, listen, ref: noop, unref: noop };  handles[key] = handle;  // 這個cb 函數是net.js 中的listenOnMasterHandle 方法  cb(0, handle);}// lib/net.js/*function listenOnMasterHandle(err, handle) {  err = checkBindError(err, port, handle);  server._handle = handle;  // _listen2 函數中,調用的handle.listen方法,也就是上面被hack的listen  server._listen2(address, port, addressType, backlog, fd); }*/            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 集安市| 富民县| 余庆县| 伊宁市| 朝阳县| 巧家县| 焉耆| 罗源县| 克什克腾旗| 通化市| 娄底市| 信丰县| 新营市| 辉南县| 宜川县| 玛纳斯县| 拉孜县| 上饶县| 永靖县| 肇源县| 义马市| 侯马市| 休宁县| 永丰县| 涿鹿县| 拜城县| 普兰县| 抚远县| 东至县| 大洼县| 湾仔区| 志丹县| 宁阳县| 满城县| 西畴县| 高碑店市| 南丹县| 彰化市| 峨眉山市| 大姚县| 陆良县|