精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

在Node.js中使用SO_RESUEPORT

開發 前端
今天下載了Node.js最新版代碼,并為Node.js的TCP模塊增加了SO_RESUEPORT的能力,本文介紹一下具體的實現。

[[412935]]

前言:今天下載了Node.js最新版代碼,并為Node.js的TCP模塊增加了SO_RESUEPORT的能力,本文介紹一下具體的實現,關于SO_RESUEPORT的知識可以參考之前的文章或者網上文章。

1 Libuv

SO_RESUEPORT是操作系統內核提供的能力,所以第一步首先修改Libuv。考慮到操作系統兼容性的問題,目前只支持Linux系統,舊版Mac OS也支持相關屬性但是效果不符合預期,新版Mac OS倒是支持,考慮到Node.js在幾乎都是部署到Linux,所以可以先關注Linux內核。首先修改deps/uv/include/uv.h。

  1. enum uv_tcp_flags { 
  2.   UV_TCP_IPV6ONLY = 1, 
  3.   // 支持SO_RESUEPORT flags 
  4.   UV_TCP_REUSEPORT = 2 
  5.  
  6. }; 

接著修改deps/uv/src/unix/tcp.c。

  1. #if defined(SO_REUSEPORT) && defined(__linux__)  
  2.   on = 1; 
  3.   if ((flags & UV_TCP_REUSEPORT) && setsockopt(tcp->io_watcher.fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on))) 
  4.     return UV__ERR(errno); 
  5. #endif 

這里判斷一下是否有兩個宏,有的話才能使用SO_RESUEPORT。如果支持則通過setsockopt設置socket的SO_REUSEPORT標記,這是最核心的邏輯。

2 修改C++層

修改完底層的Libuv后,繼續修改C++層,因為這是一個可選的屬性,所以我們需要增加相關的邏輯。修改src/tcp_wrap.cc。首先導出一個新的常量

  1. #if defined(SO_REUSEPORT) && defined(__linux__)  
  2.  NODE_DEFINE_CONSTANT(constants, UV_TCP_REUSEPORT); 
  3.  
  4. #endif 

在JS層可以通過判斷是否導出了這個常量來判斷系統是否支持SO_RESUEPORT。接著修改bind函數,因為我們再bind的時候可以設置SO_RESUEPORT。

  1. template <typename T> 
  2.  
  3. void TCPWrap::Bind( 
  4.  
  5.     const FunctionCallbackInfo<Value>& args, 
  6.     int family, 
  7.     std::function<int(const char* ip_address, int port, T* addr)> uv_ip_addr) { 
  8.   TCPWrap* wrap; 
  9.   ASSIGN_OR_RETURN_UNWRAP(&wrap, 
  10.                           args.Holder(), 
  11.                           args.GetReturnValue().Set(UV_EBADF)); 
  12.   Environment* env = wrap->env(); 
  13.   node::Utf8Value ip_address(env->isolate(), args[0]); 
  14.   int port; 
  15.   unsigned int flags = 0; 
  16.   if (!args[1]->Int32Value(env->context()).To(&port)) return
  17.   // ipv6支持ipv6Only和SO_RESUEPORT 
  18.   if (family == AF_INET6 && 
  19.       !args[2]->Uint32Value(env->context()).To(&flags)) { 
  20.     return
  21.   // ipv4之前是不支持任何標記的,這里需要加上這個邏輯,因為我們需要支持SO_RESUEPORT 
  22.   } else if (family == AF_INET4 && 
  23.       !args[2]->Uint32Value(env->context()).To(&flags)) { 
  24.     return
  25.   } 
  26.  
  27.   T addr; 
  28.   int err = uv_ip_addr(*ip_address, port, &addr); 
  29.  
  30.   if (err == 0) { 
  31.     err = uv_tcp_bind(&wrap->handle_, 
  32.                       reinterpret_cast<const sockaddr*>(&addr), 
  33.                       flags); 
  34.   } 
  35.   args.GetReturnValue().Set(err); 
  36.  

C++主要是完成透傳flags的邏輯。

3 修改JS層

修改JS層是最復雜的地方,主要是為了應用層的兼容性問題。也就是說如果Node.js真的支持了SO_RESUEPORT,在某些平臺不支持SO_RESUEPORT的情況下,我們如何能保證我們的代碼能在各個平臺上跑。簡單來說,如果我們平臺支持SO_RESUEPORT,我們可以開啟多個子進程,然后分別執行以下代碼。

  1. const http = require('http'); 
  2. http.createServer((req, res) => { 
  3.     res.end('hello'); 
  4.  
  5. }) 
  6.  
  7. .listen({port: 8000, reuseport: true}); 

這時候,只需要修改一下Node.js的net.js,把reuseport標記傳到C++層再傳到Libuv就行,但是問題是,如果我們這樣寫代碼,就無法在不支持SO_RESUEPORT的平臺跑了,因為會導致重復監聽端口的錯誤。所以為了兼容性,我想的方案是利用Cluster模塊,目前Cluster模塊支持輪詢和共享兩種模式,那么我們再加一種reuseport模式就好了,這樣的好處是一旦我們平臺不支持SO_RESUEPORT,我們可以降級到Node.js現在到模式。我們知道Cluster模塊的原理有兩種,一種是主進程監聽,分發連接給子進程,另一種是主進程創建socket,通過文件描述符傳遞的方式傳給子進程,所有的進程都是共享一個socket的。下面我們看看怎么做。首先修改lib/internal/cluster/primary.js。

  1. // 增加這if的邏輯 
  2. if ((message.addressType === 4 ||  
  3.  message.addressType === 6) &&  
  4.  (message.flags & TCPConstants.UV_TCP_REUSEPORT)) { 
  5.  handle = new ReusePort(key, address, message); 
  6. else if (schedulingPolicy !== SCHED_RR || 
  7.     message.addressType === 'udp4' || 
  8.     message.addressType === 'udp6') { 
  9.   handle = new SharedHandle(key, address, message); 
  10. else { 
  11.   handle = new RoundRobinHandle(key, address, message); 

我們在queryServer函數里增加了一個if的邏輯。如果addressType是4或6說明是TCP協議,并且設置了UV_TCP_REUSEPORT(listen的時候傳入),就會走到reuseport的邏輯,剩下的兩個else是目前Node.js的邏輯。我們看看ReusePort.js做了什么。

  1. 'use strict'
  2.  
  3. const assert = require('internal/assert'); 
  4.  
  5. const net = require('net'); 
  6.  
  7. const { constants: TCPConstants } = internalBinding('tcp_wrap'); 
  8.  
  9.  
  10. module.exports = ReusePort; 
  11.  
  12. function ReusePort(key, address, {port, addressType, fd, flags}) { 
  13.   this.key = key
  14.   this.workers = []; 
  15.   this.handles = []; 
  16.   this.list = [address, port, addressType, fd, flags]; 
  17.  
  18.  
  19.  
  20. ReusePort.prototype.add = function(worker, send) { 
  21.   assert(!this.workers.includes(worker)); 
  22.   const rval = net._createServerHandle(...this.list); 
  23.   let errno; 
  24.   let handle; 
  25.   if (typeof rval === 'number'
  26.     errno = rval; 
  27.   else 
  28.     handle = rval; 
  29.   this.workers.push(worker); 
  30.   this.handles.push(handle); 
  31.   send(errno, null, handle); 
  32.  
  33. }; 
  34.  
  35.  
  36. ReusePort.prototype.remove = function(worker) { 
  37.   const index = this.workers.indexOf(worker); 
  38.  
  39.   if (index === -1) 
  40.     return false; // The worker wasn't sharing this handle. 
  41.  
  42.   this.workers.splice(index, 1); 
  43.   this.handles[index].close(); 
  44.   this.handles.splice(index, 1); 
  45.   return true
  46.  
  47. }; 

上面的代碼我們只需要關注net._createServerHandle。在不能多個進程同時監聽同一個端口的情況下,Node.js只會調net._createServerHandle創建一個socket,然后多個進程共享。而我們這里會給每個進程創建一個socket。這個socket就是在子進程調用queryServer的時候返回給子進程的。剩下的邏輯我們暫時不用關注。最后看一下_createServerHandle的邏輯。

  1. const handle = new TCP(TCPConstants.SERVER); 
  2.  
  3. if (addressType === 6) { 
  4.  
  5.   err = handle.bind6(address, port, flags);}  
  6.  
  7. else { 
  8.  
  9.   err = handle.bind(address, port, flags || 0); 
  10.  

_createServerHandle的邏輯是創建一個socket并且給socket綁定IP和端口,我們看到這里會給C++層傳入flags,C++層就會傳到LIbuv了,這樣我們就完成了整個過程,整體的流程如下。

1 子進程執行listen的時候,傳入reuseport為true

2 子進程通過進程間通信請求主進程

3 主進程返回一個新的socket并綁定到對應的地址

4 子進程執行listen啟動服務器。

4 使用

接下來我們看看如何使用,首先創建一個server.js。

  1. const cluster = require('cluster'); 
  2.  
  3. const os = require('os'); 
  4.  
  5. const http = require('http'); 
  6.  
  7. const cpus = os.cpus().length; 
  8.  
  9.  
  10.  
  11.  if (cluster.isPrimary) { 
  12.  
  13.   const map = {}; 
  14.   for (let i = 0; i < cpus; i++) { 
  15.     const worker = cluster.fork(); 
  16.     map[worker.process.pid] = 0; 
  17.     worker.on('message', (pid) => { 
  18.         map[pid]++; 
  19.     }); 
  20.   } 
  21.  
  22.   process.on('SIGINT', () => { 
  23.     console.log(map); 
  24.   }); 
  25.  
  26. else { 
  27.  
  28.   http.createServer((req, res) => { 
  29.       process.send(process.pid); 
  30.       res.end('hello'); 
  31.   }) 
  32.  
  33.   .listen({reuseport: true, port: 8000}); 
  34.  

再創建一個客戶端client.js

  1. const http = require('http'); 
  2. function connect() { 
  3.     setTimeout(() => { 
  4.         http.get('http://localhost:8000/', (res) => { 
  5.             console.log(res.statusCode); 
  6.             connect(); 
  7.         }); 
  8.     }, 50); 
  9.  
  10.  
  11. connect(); 

客戶端串行訪問服務器,我們看到使用方式和目前Node.js的Cluster使用一樣。即使我們把reuseport改成false或者其他平臺跑也沒問題,效果如下

圖片

我們看到在reuseport的情況下,負載還是挺均衡的。

后記:目前是通過listen的時候傳入參數去控制是否開啟SO_RESUEPORT的,后續可以增加通過設置cluster.schedulingPolicy的方式,和目前共享、輪詢模式對齊,考慮到Cluster模塊不是必須,因為我們可以直接用子進程模塊監聽同一個端口。所以通過listen函數去控制是非常必要的。目前通過修改Node.js內核大概體驗了一下SO_RESUEPORT,后續review和改進一下代碼。

 

責任編輯:姜華 來源: 編程雜技
相關推薦

2021-01-18 08:06:38

Node.js 追蹤JSON

2021-07-30 11:20:53

JavaScriptNode.jsWeb Develop

2020-08-05 08:31:51

SSL TLSNode.js

2021-07-03 17:43:03

Node.jsNode變量

2014-03-07 13:43:32

Node.jsNode

2021-08-20 16:05:28

JavaScript node.js 應用安全

2022-08-28 16:30:34

Node.jsDocker指令

2022-01-11 17:23:12

配置Node.jsNode

2023-01-10 14:11:26

2013-11-01 09:34:56

Node.js技術

2015-03-10 10:59:18

Node.js開發指南基礎介紹

2017-04-10 13:28:32

Node.jsJavaScript

2020-12-08 06:28:47

Node.js異步迭代器

2021-07-16 04:56:03

NodejsAddon

2021-03-03 06:39:05

Nodejs前端開發

2021-01-27 08:05:55

本地存儲HTTP

2016-08-25 21:28:04

前端node截圖

2022-08-22 07:26:32

Node.js微服務架構

2012-09-29 11:13:15

Node.JS前端開發Node.js打包

2011-11-01 10:30:36

Node.js
點贊
收藏

51CTO技術棧公眾號

免费在线观看你懂的| 亚洲一区二区不卡视频| 国产污污视频在线观看 | sm在线观看| 91在线观看下载| 国产精品久久久精品| 艳妇荡乳欲伦69影片| 免费日韩一区二区三区| 欧美性生活大片视频| 久久久天堂国产精品| 你懂的视频在线| 国产一区二区成人久久免费影院| 97在线视频观看| 国产精品久久国产精麻豆96堂| 91蜜桃臀久久一区二区| 在线观看日韩电影| 青青艹视频在线| 99在线视频观看| 国产亚洲人成网站| 国产伦精品一区二区三区视频黑人| 免费看污视频的网站| 国产精品多人| 久久视频国产精品免费视频在线| 亚洲熟妇无码av| 99a精品视频在线观看| 欧美午夜片在线看| 91视频 -- 69xx| 在线h片观看| 国产精品久久毛片| 欧美日韩国产精品一卡| 亚洲AV无码精品色毛片浪潮| 男男视频亚洲欧美| 97成人精品视频在线观看| 国产黄在线免费观看| 欧美中文字幕一区二区| 日韩精品免费在线视频| 亚洲最大视频网| 精品国产鲁一鲁****| 欧美中文字幕一区| 国产精品wwwww| 亚洲欧洲自拍| 欧美视频一区二区三区…| 免费超爽大片黄| 青草视频在线免费直播 | 日本三级免费看| 综合日韩在线| 久久亚洲精品成人| 999精品在线视频| 欧美激情成人| 樱桃视频在线观看一区| 久久国产欧美日韩精品| 精品国精品自拍自在线| 性生活一级大片| 电影中文字幕一区二区| 精品视频1区2区| 日日噜噜夜夜狠狠| 色婷婷成人网| 6080午夜不卡| 免费黄频在线观看| 制服丝袜中文字幕第一页| 欧美黄色aaa| 91嫩草亚洲精品| yw.139尤物在线精品视频| 国内毛片毛片毛片毛片毛片| 国产精品久久久久蜜臀| 久久在线精品视频| 欧美黄色免费在线观看| 在线观看一区| 2020国产精品视频| 无码人妻精品一区二区50| 日本伊人精品一区二区三区观看方式 | 日本久久久久久| 精产国品一区二区| 极品尤物av久久免费看| 97免费资源站| 五月婷中文字幕| 国产婷婷色一区二区三区四区 | 亚洲免费大片| 日韩av电影在线免费播放| 亚洲视屏在线观看| 国产精品99久久久久久有的能看| 岛国视频一区免费观看| 四虎在线观看| 久久久久久99久久久精品网站| 视频一区三区| av网站大全在线| 欧美性xxxx在线播放| 我看黄色一级片| 日韩精品一区二区三区免费视频| 日韩成人高清在线| 欧美aaa级片| 伊人久久亚洲影院| 国产美女精品视频| 黄色av免费观看| 亚洲国产精品t66y| 国产亚洲黄色片| 久久亚洲精品人成综合网| 亚洲成人av在线播放| 国精产品一区二区三区| 黄色成人91| 国产精品久久久久福利| 国精品人妻无码一区二区三区喝尿| 久久看人人爽人人| 黄色一级片黄色| 成人国产一区| 亚洲经典中文字幕| 黄色一级大片在线免费观看| 巨乳诱惑日韩免费av| 99re国产在线播放| 香蕉视频在线播放| 姬川优奈aav一区二区| 日韩成人av免费| 亚洲警察之高压线| 欧美极品美女视频网站在线观看免费| 天堂av免费在线观看| 国产成人精品1024| 中国成人在线视频| 亚洲成人av观看| 日韩成人在线网站| 九九热国产精品视频| 蜜臀精品一区二区三区在线观看| 精品综合在线| 欧美韩日亚洲| 日韩一区二区三区av| 在线观看免费黄色网址| 久久都是精品| 国产一区二区三区色淫影院| 69xxx在线| 欧美精品123区| 中文字幕第69页| 丝瓜av网站精品一区二区| 国产亚洲福利社区| 天堂av资源在线观看| 欧美丰满嫩嫩电影| 日本在线观看网址| 蜜臀av性久久久久av蜜臀妖精| 蜜桃网站成人| 中文在线аv在线| 亚洲精品久久久久中文字幕欢迎你| 日韩黄色免费观看| 国产精品一区免费在线观看| 中文字幕中文字幕在线中心一区| 成人精品动漫| 最新中文字幕亚洲| 亚洲天堂一二三| 国产精品成人免费在线| 亚洲天堂2018av| 欧美第十八页| 成人网在线视频| caopo在线| 日韩女优av电影| 久草国产在线观看| 波波电影院一区二区三区| 无码 制服 丝袜 国产 另类| 国产成人福利av| 2018国产精品视频| 男同在线观看| 欧美日韩三级在线| 大地资源高清在线视频观看| 激情文学综合插| 国产乱子伦精品视频| 成人午夜三级| 欧美一级高清免费播放| 国产中文字幕在线| 制服丝袜中文字幕一区| 强乱中文字幕av一区乱码| 丁香天五香天堂综合| 乱妇乱女熟妇熟女网站| 国模精品一区| 成人在线视频福利| 国产探花视频在线观看| 亚洲精品永久免费| 中文在线免费观看| 亚洲六月丁香色婷婷综合久久| 亚洲精品成人无码毛片| 亚洲专区一区| 中文字幕色一区二区| jizz国产精品| 日本亚洲欧美成人| 黄色免费在线观看网站| 亚洲第一视频网| 无码人妻久久一区二区三区不卡| 中文字幕一区二区三区色视频 | 妺妺窝人体色www在线小说| 加勒比久久综合| 91香蕉电影院| 一区二区三区短视频| 日韩在线观看网站| 蜜桃在线一区二区| 欧美日韩一级片在线观看| 国产女人被狂躁到高潮小说| 91亚洲男人天堂| 国产无遮挡猛进猛出免费软件| 亚洲视频福利| 亚洲高清不卡一区| 六月丁香久久丫| 国产日韩欧美在线| 国产在线美女| 久久天天躁日日躁| 国产女人在线视频| 精品国产sm最大网站免费看| 欧美成人一区二区视频| 婷婷国产v国产偷v亚洲高清| www.黄色com| 91色九色蝌蚪| 国产亚洲精品成人a| 蜜臀av一区二区在线免费观看 | 日韩精品美女| 久久深夜福利免费观看| 韩国中文免费在线视频| 亚洲精品在线观看网站| 国产精品国产精品国产专区| 欧美性xxxx在线播放| 久久精品免费av| 亚洲日本在线天堂| 国产破处视频在线观看| 久久综合久久久久88| 熟女人妻一区二区三区免费看| 麻豆视频一区二区| 怡红院av亚洲一区二区三区h| 欧美日韩久久| 最新不卡av| 欧美激情成人| 一区二区日本| 成人在线免费小视频| 欧美性xxxx69| 午夜欧洲一区| 国语精品中文字幕| youjizz亚洲| 波多野结衣久草一区| 99精品国产九九国产精品| 国产精品老女人视频| 日韩不卡免费高清视频| 日本乱人伦a精品| 在线观看爽视频| 97成人在线视频| 色老头在线一区二区三区| 国产综合在线视频| 91九色在线看| 久久久久久久网站| 91九色美女在线视频| 久久男人的天堂| √8天堂资源地址中文在线| 国语自产在线不卡| а√天堂8资源在线| 国内自拍欧美激情| 嗯啊主人调教在线播放视频 | 91免费视频网站在线观看| 国产精品日本欧美一区二区三区| 欧美久久久久久久久久久久久 | 97视频在线看| 中文字幕在线免费观看视频| 欧美亚洲激情在线| 日本综合字幕| 国产精品美女免费| 国产乱子精品一区二区在线观看| 国产精品私拍pans大尺度在线 | 欧美日韩国产一二三区| 国产精品美女久久久久久2018| 欧美乱大交做爰xxxⅹ小说| 中文字幕字幕中文在线中不卡视频| 日本青青草视频| 亚洲国产sm捆绑调教视频| 亚洲天堂日韩av| 欧美伊人久久久久久午夜久久久久| 中日韩av在线| 制服丝袜日韩国产| 丰满少妇在线观看bd| 日韩av在线最新| aaa日本高清在线播放免费观看| 日韩一区在线视频| 日韩伦理电影网站| 91高清免费视频| 国产精品99精品一区二区三区∴| 亚洲一区二区中文字幕| 极品国产人妖chinesets亚洲人妖 激情亚洲另类图片区小说区 | 久久成人免费观看| 免费在线成人网| 中文字幕人妻无码系列第三区| 波多野洁衣一区| 精品伦精品一区二区三区视频密桃| 亚洲激情第一区| 国产熟妇一区二区三区四区| 欧美一卡在线观看| 欧美日韩在线中文字幕| 久久久久北条麻妃免费看| 春色校园综合激情亚洲| 国产日本欧美一区二区三区| 国产精品一线| 一区二区三区在线视频看| 好看的av在线不卡观看| www.亚洲高清| 成人精品视频一区二区三区尤物| 五月婷六月丁香| 亚洲不卡在线观看| 中文字字幕在线中文乱码| 亚洲精品在线一区二区| 欧美成年黄网站色视频| 国产91精品不卡视频| 国产精品亚洲一区二区在线观看 | 欧美成人tv| 日日碰狠狠丁香久燥| 国产精品1区二区.| 久久日免费视频| 精品久久久久久久久国产字幕| 国产精品久久影视| 亚洲视频999| 高清视频在线观看三级| 成人在线视频网址| 98精品视频| 男人搞女人网站| 久久影院午夜论| 国产在线拍揄自揄拍| 日韩欧美中文字幕在线视频| 老司机精品视频导航| 97超碰国产精品| 蜜臀精品一区二区三区在线观看| av网页在线观看| 亚洲黄色小视频| ,亚洲人成毛片在线播放| 围产精品久久久久久久| 日本亚洲欧美三级| 成人搞黄视频| 干日本少妇视频| 麻豆国产一区二区| 亚洲精品国产一区黑色丝袜| 亚洲成av人在线观看| aaa级黄色片| 久久综合九色九九| 四虎国产精品永久在线国在线| 欧美精品七区| 免费日韩精品中文字幕视频在线| 国产一级黄色录像| 亚洲高清免费在线| 亚洲第一色网站| 美女久久久久久久久久久| 91麻豆精品国产综合久久久| 一区二区三区三区在线| 美女一区二区三区| 日本精品久久久久中文| 色婷婷国产精品| 你懂的在线看| 国产精品视频网址| 日韩黄色大片| 中文字幕亚洲乱码| 中文字幕日本不卡| hs视频在线观看| 欧美插天视频在线播放| 深夜激情久久| 日本阿v视频在线观看| 不卡av免费在线观看| 日韩欧美高清在线观看| 亚洲国产欧美一区| 中文字幕 在线观看| 日本不卡在线播放| 蜜臀a∨国产成人精品| 欧美日韩色视频| 日韩欧美国产一二三区| www.youjizz.com在线| 久久99精品久久久久子伦| 手机精品视频在线观看| 超碰97av在线| 欧美一区二区成人6969| av福利在线导航| 日韩在线三区| 国模一区二区三区白浆| 国产无码精品在线播放| 亚洲精品一区二区网址| 久久久久久一区二区三区四区别墅| 51xx午夜影福利| 97se亚洲国产综合自在线不卡| 91视频久久久| 美女999久久久精品视频| 欧美天堂影院| 亚洲国产高清av| 亚洲综合色区另类av| 欧洲毛片在线| 成人精品久久久| 国产欧美成人| 网爆门在线观看| 精品99一区二区三区| 三级成人黄色影院| 特大黑人娇小亚洲女mp4| 91丨porny丨在线| 国产绿帽刺激高潮对白| 午夜精品福利视频| 日韩片欧美片| 日批在线观看视频| 欧美日韩日日夜夜| 岛国片av在线| 制服诱惑一区| 337p粉嫩大胆噜噜噜噜噜91av| 91丨porny丨在线中文 | 日韩国产在线看| 欧美电影在线观看网站| 免费无码毛片一区二三区| 中文字幕av一区二区三区免费看 | 久久久久国产一区二区三区| 一区二区三区日本久久久| xxx中文字幕|