.net core高并发_高并发下的Node.js与负载均衡

2a0a45950a4efd78e500502526fd2c45.png

cb99d373cd9a1dac4910c8b2b1618ff4.gif

阅读本文约需要6分钟

大家好,我是你们的导师,我每天都会在这里给大家分享一些干货内容(当然了,周末也要允许老师休息一下哈)。上次老师跟大家分享了下浅谈前端自动化构建的相关知识,今天跟大家分享浅谈前端自动化构建的相关知识
参考来源:https://www.cnblogs.com/tingshuo/archive/2013/01/17/2864280.html

众所周知,node.js基于v8引擎,所以它本身并不支持多线程(有多线程的Module哦),那么为了充分利用server的Multi-core,就必须使用多进程的方式。那么进程之间如何负载均衡就会是一个关键所在。

多进程共享监听socket

Node.js与进程相关的模块有process,child_process,cluster,这其中cluster用于方便的创建共享端口的多进程模式(The cluster module allows you to easily create a network of processes that all share server ports),这种模式使多个进程间共享一个监听状态的socket,并由系统将accept的connection分配给不同的子进程,而且实现起来也非常简单,cluster为你做了大部分事情,这里有一个test case:

  var cluster = require('cluster');  var http = require('http');  var numCPUs = require('os').cpus().length;    if (cluster.isMaster) {    // Fork workers.    for (var i = 0; i < numCPUs; i++) {      cluster.fork();    }    cluster.on('exit', function(worker, code, signal) {     console.log('worker ' + worker.process.pid + ' died');   }); } else {   // Workers can share any TCP connection   // In this case its a HTTP server   http.createServer(function(req, res) {     res.writeHead(200);     res.end("hello world\n");   }).listen(8000); }

但是这种完全依赖于系统的负载均衡存在着一个重要缺陷:在linux和Solaris上,只要某个子进程的accept queue为空(通常为最后创建的那个子进程),系统就会将多个connetion分配到同一个子进程上,这会造成进程间负载极为不均衡。

特别是在使用长连接的时候,单位时间内的new coming connection并不高,子进程的accept queue往往均为空,就会导致connection会不停的分配给同一个进程。所以这种负载均衡完全依赖于accept queue的空闲程度,只有在使用短连接,而且并发非常高的情况下,才能达到负载均衡,但是这个时候系统的load会非常高,系统也会变得不稳定起来。

Nginx是怎么做的?

如果你了解nginx,那么你可能第一时间会想到使用nginx的处理方式,nginx有一个master和多个worker进程,master进程监听端口,负责accept connection,并把accept 的socket发送给各worker进程,由worker进程接收数据并处理。

linux下,nginx是使用socketpair建立master和worker进程间的通信,并使用sendmsg、recvmsg等api来传输命令和文件描述符的。那么node.js是否支持这种方案呢?

答案是肯定的,作出这个回答的依据在于node.js的child_process和cluster模块均有一个send方法:child.send(message, [sendHandle])

这个方法的第二个参数就是我们想要传递的socket,而且node.js文档上还给出了一个test case:

 var normal = require('child_process').fork('child.js', ['normal']); var special = require('child_process').fork('child.js', ['special']); // Open up the server and send sockets to child var server = require('net').createServer(); server.on('connection', function (socket) { // if this is a VIP if (socket.remoteAddress === '74.125.127.100') { special.send('socket', socket); return; } // just the usual dudes normal.send('socket', socket); }); server.listen(1337);
child.js
 process.on('message', function(m, socket) { if (m === 'socket') { socket.end('You were handled as a ' + process.argv[2] + ' person'); } });

简单,精炼!似乎是一个完美的解决方案。我们稍微加工一下,让他成为一个可以正常运行的http server:

master.js

 var http = require('http'), numCPUs = require('os').cpus().length; cp = require('child_process'),  net = require('net'); var workers = []; for (var i = 0; i < numCPUs; i++) { workers.push(cp.fork('app.js', ['normal'])); }  net.createServer(function(s) { s.pause(); var worker = worker.shift(); worker.send('c',s); workers.push(worker); }).listen(80);
 var http = require('http'), cp = require('child_process'), net = require('net'); var server = http.createServer(function(req,res){ res.writeHead(200, {"Content-Type": "text/plain",         "Connection": "close"}); res.end("hello, world"); }); console.log("webServer started on " + process.pid); process.on("message", function(msg,socket) { process.nextTick(function(){ if(msg == 'c' && socket) { socket.readable = socket.writable = true;socket.resume(); server.connections++; socket.server = server; server.emit("connection", socket); socket.emit("connect"); } }); });

我们在worker进程中创建了一个http server,但是这个http server并不监听,也不绑定端口,在收到master传输过来的socket时,调用server.emit("connection", socket);就可以触发server的connection事件了

看起来很不错,简单的测试之后可以正常工作,这个方案几近于完美。在经历过共享监听socket方案的失败后,我们把服务迁移到这种架构上来。

但是,我们遇到了问题。我们发现master进程的cpu和内存在逐渐增长,并最终到达100%,或者node.js崩溃(Assertion `fd_to_send >= 0' failed),这令我很抓狂,百般无奈之下我们求助于node.js的开发人员,在github上报告了我们遇到的问题(Issue #4587)。

就在当天晚上,node.js的开发人员indutny找到了问题所在,主要在于主进程在将socket发送给子进程之后,并没有销毁,而是保留在socketList中,这会导致socket在主进程中逐步累积,并最终达到上限。

indutny很快解决了这个问题,于第二天提交了这个commit,按照这个commit,indutny给send函数增加了第三个可选参数,修改后的send函数将变为:

child.send(message,[socket], [{ track: false, process: false }])

我们的master进程不需要track每个socket状态,所以我们将它设为false即可。到此,这个问题得到了完美的解决

今天就分享这么多,关于高并发下的Node.js与负载均衡,你学会了多少?欢迎在留言区评论,对于有价值的留言,我们都会一一回复的。如果觉得文章对你有一丢丢帮助,请点右下角【在看】,让更多人看到该文章。如果有想了解的,也可以进行留言

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/528637.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android arm 寄存器,ARM汇编

8种机械键盘轴体对比本人程序员&#xff0c;要买一个写代码的键盘&#xff0c;请问红轴和茶轴怎么选&#xff1f;Android Native 进程启动流程ARM传参&#xff0c;R0-R3传递前四个参数1. Thumb 指令集特点Thumb 指令集指令长度&#xff1a;16或32&#xff0c;16为为主Thumb-16 …

如何制作印章_用Word也能做出逼真的电子印章!简单3步!1分钟搞定

我们在办公的时候经常需要用到印章&#xff0c;以前可能是在纸上盖章&#xff0c;现在电子文档比较多&#xff0c;电子印章也开始流行使用&#xff0c;那么我们如何制作一个逼真的印章呢&#xff1f;很简单&#xff0c;用Word就可以搞定啦&#xff01;一、印章制作1、圆圈制作首…

鸿蒙唯独没有手机,想用鸿蒙OS,却没有华为手机?华为高层:还有1亿台设备可体验...

不再是PTT系统&#xff01;鸿蒙OS真的要来了&#xff0c;年内初步实现全场景交互从2019年开始&#xff0c;有关 鸿蒙OS 的消息越来越多&#xff0c;不仅公布了发展规划&#xff0c;也确定将适配多款机型&#xff0c;期待度直接拉满。可惜以目前的情况来看&#xff0c;鸿蒙OS 适…

@kafkalistener中id的作用_SSM框架(十一):Spring框架中的IoC(1)

控制反转 IOC&#xff1a;控制反转&#xff08;Inversion of Control&#xff0c;缩写为IoC&#xff09;&#xff0c;是面向对象编程中的一种设计原则&#xff0c;可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入&#xff08;Dependency Injection&#xff…

keras优化算法_目标检测算法 - CenterNet - 代码分析

代码出处吃水不忘打井人&#xff0c;分析github上的基于keras的实现&#xff1a;xuannianz/keras-CenterNet​github.com代码主体结构模型训练的主函数流程如下所示&#xff0c;该流程也是使用keras的较为标准的流程。其中代码篇幅较大的是数据准备的部分&#xff0c;通常的代码…

c语言中创建一个整数数组_VBA中动态数组的创建及利用方法

大家好&#xff0c;后疫情时代一定会到来&#xff0c;各行各业&#xff0c;都将是一场战胜萧条的无声的战役。无论怎样&#xff0c;我们一定要坚信&#xff0c;疫情终将会过去&#xff0c;曙光一定会到来。后疫情时代将会是一个全新的世界&#xff0c;很多理念都将被打破&#…

用计算机求函数公式,计算机常用的函数公式有哪些?

01计算机常用的函数公式包括RANK函数、COUNTIF函数、IF函数、ABS函数、AND函数、AVERAGE函数、COLUMN 函数等。RANK函数是Excel计算序数的主要工具&#xff0c;它的语法为&#xff1a;RANK(number&#xff0c;ref&#xff0c;order)&#xff0c;其中number为参与计算的数字或含…

golang 读取文件最后一行_python3从零学习-5.4.3、文件输入流fileinput

源代码: Lib/fileinput.py此模块实现了一个辅助类和一些函数用来快速编写访问标准输入或文件列表的循环。 如果你只想要读写一个文件请参阅 open().典型用法为:import fileinputfor line in fileinput.input(): process(line)这将遍历sys中列出的所有文件的行。argv[1:]如果…

云计算机具体应用场景,云计算的定义、类型及应用场景

云计算是20年来IT行业出现的最激动人心且最具颠覆性的技术&#xff0c;甚至比大型主机向客户端/服务器架构的迁移还更具颠覆性。无论是IT服务的交付方式&#xff0c;还是企业消费这些IT服务的方式&#xff0c;都因云计算而改变。用户也正在快速应对新架构带来的变革&#xff0c…

dataframe for循环 筛选_Python循环12种超强写法,又快又省内存

0 前言说到处理循环&#xff0c;我们习惯使用for, while等&#xff0c;比如依次打印每个列表中的字符&#xff1a;在打印内容字节数较小时&#xff0c;全部载入内存后&#xff0c;再打印&#xff0c;没有问题。可是&#xff0c;如果现在有成千上百万条车辆行驶轨迹&#xff0c;…

html5文字飞入插件,jquery使用CSS3实现文字动画效果插件Textillate.js

jquery使用CSS3实现文字动画效果插件Textillate.jsTextillate是一款基于CSS3动画效果的 JavaScript 库&#xff0c;您可非常轻轻松地把这些动画效果应该于网页中的任何文字。使用方法引入核心文件构建html标签My Title写入JS&#xff0c;初始化$(function () {$(.tlt).textilla…

工业机器人导轨 百度文库_工业机器人或许开创一个全新的PLC时代

自机器人诞生之日起人们就不断地尝试着说明到底什么是机器人。但随着机器人技术的飞速发展和信息时代的到来&#xff0c;机器人所涵盖的内容越来越丰富&#xff0c;机器人的定义也不断充实和创新。机器人技术作为20世纪人类最伟大的发明之一&#xff0c;自20世纪60年代初问世以…

银联分账与银联代付_第三方分账系统到底有哪些作用?

随着监管越来越严&#xff0c;业务越来越复杂&#xff0c;所有平台电商企业都需要通过第三方分账系统解决支付清算及二清等问题。作为第三方分账系统行业从业者&#xff0c;整理了部分关于系统的相关问题及解答&#xff0c;希望对大家有所帮助。问题一&#xff1a;第三方分账系…

计算机更改桌面,2010年职称计算机考试:更改桌面背景和颜色

Windows XP提供了各种桌面的颜色和背景方案,用户可以根据自己的爱好进行选择。颜 色充当桌面的最底层,背景覆盖于颜色之上。(l)桌面背景的更改在"显示属性"对话框中,选择"桌面"选项卡。在"桌面"选项卡上有一个"背景"列表框,选择列表框…

dell t40 固态系统盘_笔记本怎么安装固态硬盘 笔记本安装固态硬盘教程【详解】...

首先我不得不介绍一下我这古董级别的笔记本 硬件升级&#xff0c;然后给大家介绍一下笔记本安装固态硬盘的教程。dell戴尔1320&#xff0c;cpu t6500 主频2.1ghz 。内存运用了淘汰的ddr2 分别是两条1g&#xff0c;共2g 800频率。这样的古董用的着用固态么?SATA2.0接口完全成为…

如何进入zabbix的wab界面_如何不用光盘重装系统呢?

如果身边没有系统光盘如何重装系统呢&#xff1f;小鱼系统可以帮助你一键重装系统和U盘重装系统的方法&#xff0c;下面一起看下小鱼系统教你的如何不用光盘重装系统吧。一键重装系统方法1、首先请备份好电脑C盘重要资料&#xff0c;然后打开【小鱼系统】&#xff0c;进入电脑环…

全国高中计算机大赛,2019年含金量最大的中小学全国性竞赛活动——五大学科竞赛...

五大学科竞赛历史是我国含金量最高的中小学全国性竞赛活动&#xff0c;在各高校自主招生过程中&#xff0c;具有较高的参考价值。对相关方面有一定兴趣的同学&#xff0c;也可以积极参与。五大赛面向的对象都是高中学生。一、全国中学生数学奥林匹克竞赛此项竞赛的主办单位是中…

单片机红绿灯电路灯有几种_新农村建设的太阳能路灯如何选择?

随着我国城乡一体化发展进程&#xff0c;城乡道路照明已成为新农村建设必不可少的一部分。目前市面通用的道路照明有两种&#xff1a;即市电路灯照明&#xff08;市电220V&#xff09;和太阳能路灯照明。安装简便且不需要布线的太阳能路灯在新农村建设中应用广泛&#xff0c;下…

lr不能直接转ps编辑_摄影后期调色软件,Lr软件包

摄影后期调色除了用到PS软件还有一款与之媲美的就是LR软件了&#xff0c;全名是Adobe Lightroom&#xff0c;喜欢拍照的人&#xff1b;总会希望自己拍下来的照片更好看&#xff0c;不管是多好的器材直出的 jpg 本身总会多多少少有一些限制&#xff0c;而利用后期软件可以很好的…

hive中如何把13位转化为时间_重要知识点收藏 | Hive常用函数大全

关系运算1、等值比较: 语法&#xff1a;AB操作类型&#xff1a;所有基本类型描述: 如果表达式A与表达式B相等&#xff0c;则为TRUE&#xff1b;否则为FALSE举例&#xff1a;hive>select 1 from lxw_dual where 11;12、不等值比较: <>语法: A <> B操作类型: 所有…