网易首页 > 网易号 > 正文 申请入驻

一文告诉你大厂亿级并发下高性能服务器是如何实现的!

0
分享至

  历史上最早出现也是最简单的一种并行处理多个请求的方法就是利用多进程。

  比如在Linux世界中,我们可以使用fork、exec等系统调用创建多个进程,我们可以在父进程中接收用户的连接请求,然后创建子进程去处理用户请求,就像这样:

  这种方法的优点就在于:

  1. 编程简单,非常容易理解

  2. 由于各个进程的地址空间是相互隔离的,因此一个进程崩溃后并不会影响其它进程

  3. 充分利用多核资源

  多进程并行处理的优点很明显,但是缺点同样明显:

  1. 各个进程地址空间相互隔离,这一优点也会变成缺点,那就是进程间要想通信就会变得比较困难,你需要借助进程间通信(IPC,interprocess communications)机制,想一想你现在知道哪些进程间通信机制,然后让你用代码实现呢?显然,进程间通信编程相对复杂,而且性能也是一大问题

  2. 我们知道创建进程开销是比线程要大的,频繁的创建销毁进程无疑会加重系统负担。

  幸好,除了进程,我们还有线程。

  不是创建进程开销大吗?不是进程间通信困难吗?这些对于线程来说统统不是问题。

  由于线程共享进程地址空间,因此线程间通信天然不需要借助任何通信机制,直接读取内存就好了。线程创

  建销毁的开销也变小了,要知道线程就像寄居蟹一样,房子(地址空间)都是进程的,自己只是一个租客,因此非常的轻量级,创建销毁的开销也非常小。

  我们可以为每个请求创建一个线程,即使一个线程因执行I/O操作——比如读取数据库等——被阻塞暂停运行也不会影响到其它线程,就像这样:

  但线程就是完美的、包治百病的吗,显然,计算机世界从来没有那么简单。

  由于线程共享进程地址空间,这在为线程间通信带来便利的同时也带来了无尽的麻烦。

  正是由于线程间共享地址空间,因此一个线程崩溃会导致整个进程崩溃退出,同时线程间通信简直太简单了,简单到线程间通信只需要直接读取内存就可以了,也简单到出现问题也极其容易,死锁、线程间的同步互斥、等等,这些极容易产生bug,无数程序员宝贵的时间就有相当一部分用来解决多线程带来的无尽问题。

  虽然线程也有缺点,但是相比多进程来说,线程更有优势,但想单纯地利用多线程就能解决高并发问题也是不切实际的。

  因为虽然线程创建开销相比进程小,但依然也是有开销的,对于动辄数万数十万的链接的高并发服务器来说,创建数万个线程会有性能问题,这包括内存占用、线程间切换,也就是调度的开销。

  因此,我们需要进一步思考。

  Event Loop:事件驱动

  到目前为止,我们提到“并行”二字就会想到进程、线程。但是,并行编程只能依赖这两项技术吗,并不是这样的。

  还有另一项并行技术广泛应用在GUI编程以及服务器编程中,这就是近几年非常流行的事件驱动编程,event-based concurrency。

  大家不要觉得这是一项很难懂的技术,实际上事件驱动编程原理上非常简单。这一技术需要两种原料:

  1. event

  2. 处理event的函数,这一函数通常被称为event handler

  剩下的就简单了:

  你只需要安静的等待event到来就好,当event到来之后,检查一下event的类型,并根据该类型找到对应的event处理函数,也就是event handler,然后直接调用该event handler就好了。

  That's it!

  以上就是事件驱动编程的全部内容,是不是很简单!从上面的讨论可以看到,我们需要不断地接收event然后处理event,因此我们需要一个循环(用while或者for循环都可以),这个循环被称为Event loop。

  使用伪代码表示就是这样:

  Event loop中要做的事情其实是非常简单的,只需要等待event的到来,然后调用相应的event处理函数即可。

  注意,这段代码只需要运行在一个线程或者进程中,只需要这一个event loop就可以同时处理多个用户请求。

  有的同学可以依然不明白为什么这样一个event loop可以同时处理多个请求呢?

  原因很简单,对于web服务器来说,处理一个用户请求时大部分时间其实都用在了I/O操作上,像数据库读写、文件读写、网络读写等。当一个请求到来,简单处理之后可能就需要查询数据库等I/O操作,我们知道I/O是非常慢的,当发起I/O后我们大可以不用等待该I/O操作完成就可以继续处理接下来的用户请求。

  现在你应该明白了吧,虽然上一个用户请求还没有处理完我们其实就可以处理下一个用户请求了,这也是并行,这种并行就可以用事件驱动编程来处理。

  这就好比餐厅服务员一样,一个服务员不可能一直等上一个顾客下单、上菜、吃饭、买单之后才接待下一个顾客,服务员是怎么做的呢?当一个顾客下完单后直接处理下一个顾客,当顾客吃完饭后会自己回来买单结账的。

  看到了吧,同样是一个服务员也可以同时处理多个顾客,这个服务员就相当于这里的Event loop,即使这个event loop只运行在一个线程(进程)中也可以同时处理多个用户请求。

  相信你已经对事件驱动编程有一个清晰的认知了,那么接下来的问题就是事件驱动、事件驱动,那么这个事件也就是event该怎么获取呢?

  在Linux/Unix世界中一切皆文件,而我们的程序都是通过文件描述符来进行I/O操作的,当然对于socket也不例外,那我们该如何同时处理多个文件描述符呢?

  IO多路复用技术正是用来解决这一问题的,通过IO多路复用技术,我们一次可以监控多个文件描述,当某个文件(socket)可读或者可写的时候我们就能得到通知啦。

  这样IO多路复用技术就成了event loop的原材料供应商,源源不断的给我们提供各种event,这样关于event来源的问题就解决了。

  至此,关于利用事件驱动来实现并发编程的所有问题都解决了吗?event的来源问题解决了,当得到event后调用相应的handler,看上去大功告成了。

  想一想还有没有其它问题?

  现在,我们可以使用一个线程(进程)就能基于事件驱动进行并行编程,再也没有了多线程中让人恼火的各种锁、同步互斥、死锁等问题了。

  但是,计算机科学中从来没有出现过一种能解决所有问题的技术,现在没有,在可预期的将来也不会有。

  那上述方法有什么问题吗?

  不要忘了,我们event loop是运行在一个线程(进程),这虽然解决了多线程问题,但是如果在处理某个event时需要进行IO操作会怎么样呢?

  程序员最常用的这种IO方式被称为阻塞式IO,也就是说,当我们进行IO操作,比如读取文件时,如果文件没有读取完成,那么我们的程序(线程)会被阻塞而暂停执行,这在多线程中不是问题,因为操作系统还可以调度其它线程。

  但是在单线程的event loop中是有问题的,原因就在于当我们在event loop中执行阻塞式IO操作时整个线程(event loop)会被暂停运行,这时操作系统将没有其它线程可以调度,因为系统中只有一个event loop在处理用户请求,这样当event loop线程被阻塞暂停运行时所有用户请求都没有办法被处理,你能想象当服务器在处理其它用户请求读取数据库导致你的请求被暂停吗?

  因此,在基于事件驱动编程时有一条注意事项,那就是不允许发起阻塞式IO。

  有的同学可能会问,如果不能发起阻塞式IO的话,那么该怎样进行IO操作呢?有阻塞式IO,就有非阻塞式IO。

  为克服阻塞式IO所带来的问题,现代操作系统开始提供一种新的发起IO请求的方法,这种方法就是异步IO,对应的,阻塞式IO就是同步IO。

  异步IO时,假设调用aio_read函数(具体的异步IO API请参考具体的操作系统平台),也就是异步读取,当我们调用该函数后可以立即返回,并继续其它事情,虽然此时该文件可能还没有被读取,这样就不会阻塞调用线程了。此外,操作系统还会提供其它方法供调用线程来检测IO操作是否完成。

  就这样,在操作系统的帮助下IO的阻塞调用问题也解决了。

  虽然有异步IO来解决event loop可能被阻塞的问题,但是基于事件编程依然是困难的。

  首先,我们提到,event loop是运行在一个线程中的,显然一个线程是没有办法充分利用多核资源的,有的同学可能会说那就创建多个event loop实例不就可以了,这样就有多个event loop线程了,但是这样一来多线程问题又会出现。

  另一点在于编程方面,编程方式需要把处理逻辑分为两部分,一部分调用方自己处理,另一部分在回调函数中处理,这一编程方式的改变加重了程序员在理解上的负担,基于事件编程的项目后期会很难扩展以及维护。

  那么有没有更好的方法呢?

  要找到更好的方法,我们需要解决问题的本质,那么这个本质问题是什么呢?

  为什么我们要使用异步这种难以理解的方式编程呢?

  是因为阻塞式编程虽然容易理解但会导致线程被阻塞而暂停运行。

  那么聪明的你一定会问了,有没有一种方法既能结合同步IO的简单理解又不会因同步调用导致线程被阻塞呢?

  答案是肯定的,这就是用户态线程,user level thread,也就是大名鼎鼎的协程,关于协程值得单独拿出一篇文章来讲解,就在下一篇。

  虽然基于事件编程有这样那样的缺点,但是在当今的高性能高并发服务器上基于事件编程方式依然非常流行,但已经不是纯粹的基于单一线程的事件驱动了,而是event loop + multi thread + user level thread。

  高并发技术从最开始的多进程一路演进到当前的事件驱动,计算机技术就像生物一样也在不断演变进化,但不管怎样,了解历史才能更深刻的理解当下。希望这篇文章能对大家理解高并发服务器有所帮助。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
马斯克遭遇“踢馆”:有证的飞行汽车研发公司发布其车飞越特斯拉视频,称已领先11年

马斯克遭遇“踢馆”:有证的飞行汽车研发公司发布其车飞越特斯拉视频,称已领先11年

红星新闻
2026-10-17 16:28:14
10轮对话烧掉44万token:多智能体正在被上下文拖垮

10轮对话烧掉44万token:多智能体正在被上下文拖垮

全栈遛狗员
2026-10-17 00:43:36
让灵活就业人员贷款交社保推出“社银贷”,真荒诞!

让灵活就业人员贷款交社保推出“社银贷”,真荒诞!

A活着
2026-10-17 10:31:54
今夏曾点赞张庆鹏下课!张帆时隔287天复出轰13+4自我正名

今夏曾点赞张庆鹏下课!张帆时隔287天复出轰13+4自我正名

狼叔评论
2026-10-17 23:04:16
一点都不想待在中国了?出国的人已排得人山人海,到底是什么原因

一点都不想待在中国了?出国的人已排得人山人海,到底是什么原因

全球沸点直击
2026-10-14 20:03:02
苹果客服回应货轮沉没大量iPhone漂浮海面:没有相关通知

苹果客服回应货轮沉没大量iPhone漂浮海面:没有相关通知

快科技
2026-10-17 19:46:08
日本投降前一晚有多疯狂?日本女军医:日军用刀劈开了一个人

日本投降前一晚有多疯狂?日本女军医:日军用刀劈开了一个人

阿胂是吃瓜群众
2026-10-16 12:43:48
普通人最傻的消费,就是买一辆 20 万左右的新能源新车

普通人最傻的消费,就是买一辆 20 万左右的新能源新车

小怪吃美食
2026-10-17 06:13:28
5-2!亚马尔传射+造红牌,巴萨豪取11连胜,静候大巴黎皇马

5-2!亚马尔传射+造红牌,巴萨豪取11连胜,静候大巴黎皇马

我的护球最独特
2026-10-18 02:38:40
西甲前瞻丨贝蒂斯1-2巴萨:送给巴萨赛季首败,圆神主导

西甲前瞻丨贝蒂斯1-2巴萨:送给巴萨赛季首败,圆神主导

体育世界
2026-10-17 17:34:45
男子花1800点陪酒女,摸胸被报警!姑娘:1800是陪酒钱,摸胸得另加

男子花1800点陪酒女,摸胸被报警!姑娘:1800是陪酒钱,摸胸得另加

一丝不苟的法律人
2026-10-16 12:39:11
体制内外退休金的巨大差距引起老百姓的很大不满!

体制内外退休金的巨大差距引起老百姓的很大不满!

逍遥论经
2026-10-08 14:57:40
又一电诈头目落网!坑害国人超27亿,杀人不眨眼,全网呼吁查赵薇

又一电诈头目落网!坑害国人超27亿,杀人不眨眼,全网呼吁查赵薇

泪满过眼
2026-10-10 07:24:15
051C“沈阳舰”大改后现身,中国带垂发的驱逐舰数量减1!

051C“沈阳舰”大改后现身,中国带垂发的驱逐舰数量减1!

天下布武
2026-10-17 20:32:09
张继科再次反击刘丁硕,字字扎心不留情:认识他没想到这么坏 要撕能撕碎他

张继科再次反击刘丁硕,字字扎心不留情:认识他没想到这么坏 要撕能撕碎他

球盲百小易
2026-10-18 01:28:53
随着登贝莱1球1助+巴黎圣日耳曼3-1逆转,法甲最新积分榜出炉

随着登贝莱1球1助+巴黎圣日耳曼3-1逆转,法甲最新积分榜出炉

侧身凌空斩
2026-10-18 01:13:09
上任仅5天 白宫新闻秘书遭特朗普“劝退”

上任仅5天 白宫新闻秘书遭特朗普“劝退”

财联社
2026-10-17 03:40:04
成本30元,一盒卖到6000元,总台曝光老年人“防癌神药”骗局

成本30元,一盒卖到6000元,总台曝光老年人“防癌神药”骗局

上观新闻
2026-10-17 19:36:43
谢贤前女友CoCo大曝张柏芝三胎生父内幕,无底线爆料,账号被封!

谢贤前女友CoCo大曝张柏芝三胎生父内幕,无底线爆料,账号被封!

寻墨阁
2026-03-06 13:57:52
65岁后存款别只写名字!赶紧换种写法,子女省心你也安心!

65岁后存款别只写名字!赶紧换种写法,子女省心你也安心!

别人都叫我阿腈
2026-10-11 01:08:15
2026-10-18 03:23:00
程序员谷鸡泰
程序员谷鸡泰
爱分享,爱学习,从无到有!
88文章数 395关注度
往期回顾 全部

科技要闻

刘煜辉:99%的黄金分析师报告一钱不值

头条要闻

普京:包围并消灭2000人的乌军集群 这非比寻常

头条要闻

普京:包围并消灭2000人的乌军集群 这非比寻常

体育要闻

升级版杨瀚森再闯难关:当上开拓者第三中锋还得拼

娱乐要闻

庾澄庆罕谈前妻 撕下伊能静仅剩的体面

财经要闻

新一轮大跌源头,找到了!

汽车要闻

星瑞L PLUS限时售价10.97万元起 开启智混3L时代

态度原创

教育
数码
房产
公开课
军事航空

教育要闻

“你很漂亮,但我们不要你!”女大学生简历精修照火了,但HR说出实话

数码要闻

超七成笔记本OLED被三星拿捏!中国面板厂开始反击了

房产要闻

利好密集落地+现房好房断档,广州楼市买入窗口,正在倒计时!

公开课

李玫瑾:为什么性格比能力更重要?

军事要闻

“星盾”限速事件加剧美乌裂痕

无障碍浏览 进入关怀版