aiohttp 高并发web服务_程序优化-浅谈服务器实现高并发的原理

54c78790d2d37043aaad8ba1877a83f6.png
我们每天刷手机都会接收到各种各样的信息,看到这篇文章时,不知大家有没有思考过,这些信息是如何组织,然后通过服务器发送给我们的呢?
其实也很简单,不就是一条一条请求嘛,服务器根据不同的请求分别去不同的数据库拿数据,然后通过网络返回给用户,但是复杂起来也复杂,对于成百上千的用户请求,服务器是如何去并行处理的呢?

多进程

最简单的一种方法便是利用多进程去并行处理多个请求,在linux操作系统中,我们可以通过fork,exec等系统调用去创建多个进程,可以通过在父进程中接受用户的连接请求,然后通过创建子进程去处理用户请求,就像下图所示

51b5361b40758c2b330382f528a0743c.png

这种方式的优势在于

•编程简单,容易理解•由于各个进程的地址空间相互隔离,因此一个进程的崩溃不会影响其他进程•充分利用多核资源

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

•各个进程地址空间相互隔离,进程间的通信将会变的很困难•创建进程的开销远比创建线程的开销要大,频繁创建销毁进程会影响系统的性能

有什么解决的方法呢?下面多线程要登场啦

多线程

线程是操作系统中进行调度的基本单位,它从属于进程,由于线程共享同一个进程下的地址空间,所以线程间通信是通过共享内存,线程是轻量级的,创建一个线程的开销也是非常的小

我们对于每个请求,可以单独创建一个线程去进行处理,即使一个线程由于执行某些I/O操作,例如读取数据库而阻塞住,其他线程仍然可以正常执行

942347262d32436ee2b1874fdd2dcca8.png

但线程就是完美的嘛?并不是的

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

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

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

于是就有了下面的策略

Event Loop:事件驱动

在GUI编程以及服务器编程中,流行着一种基于事件驱动编程的设计模式 这一种技术需要两种原料:

•event•处理event的函数,这一种函数通常称为event handler

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

d85e174844731d82e8717e06eac079a7.png

是不是很装逼,我们可以看到,我们只需要不断的接受event然后处理event,因此我们需要一个循环,而这个循环就称为event loop

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

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

dd7fcda1e24baf53e24da2ffed2a82ed.png

现在你应该明白了吧,虽然上一个用户请求还没有处理完我们其实就可以处理下一个用户请求了,这也是并行,这种并行就可以用事件驱动编程来处理。这就好比餐厅服务员一样,一个服务员不可能一直等上一个顾客下单、上菜、吃饭、买单之后才接待下一个顾客,服务员是怎么做的呢?当一个顾客下完单后直接处理下一个顾客,当顾客吃完饭后会自己回来买单结账的。看到了吧,同样是一个服务员也可以同时处理多个顾客,这个服务员就相当于这里的Event loop,即使这个event loop只运行在一个线程(进程)中也可以同时处理多个用户请求。这就涉及到多线程的异步执行,感兴趣的朋友可以看看上一篇文章的介绍程序优化-浅谈多任务的异步执行


扫描并关注以下公众号 ,我把我的一些技术学习资料都整理好了,涉及算法,计算机网络,Java,数据库,大家需要的可以访问以下链接自取,一起加油

https://github.com/zxhjames/learn_resource

b35cfe6525f5cf7c6f81ca9f997e6a97.png

0e47d1d4fe721198afb59c5dcf32fee1.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值