![640?wx_fmt=png](https://i-blog.csdnimg.cn/blog_migrate/dd67546cd22fb8fc8ff9eba2b8060ebe.png)
![640?wx_fmt=png](https://i-blog.csdnimg.cn/blog_migrate/6f807331046aad8c30ab16e3c5f2a177.png)
前端精髓
每日为你推送
![640?wx_fmt=png](https://i-blog.csdnimg.cn/blog_migrate/68398253596cda4335ad94f9d3af4454.png)
![640?wx_fmt=png](https://i-blog.csdnimg.cn/blog_migrate/5c44b2c608ad3aaa7e7bc3b5d1621f94.png)
为了解决同步架构的并发问题,一个简单的改进是通过进程的复制同时服务更多的请求和用户。这样每个连接都需要一个进程来服务,即100个连接需要启动100个进程来进行服务,这是非常昂贵的代价。在进程复制的过程中,需要复制进程内部的状态,对于每个连接都进行这样的复制的话,相同的状态将会在内存中存在很多份,造成浪费。并且这个过程由于要复制较多的数据,启动是较为缓慢的。
为了解决进程复制中的浪费问题,多线程被引入服务模型,让一个线程服务一个请求。线程相对进程的开销要小许多,并且线程之间可以共享数据,内存浪费的问题可以得到解决,并且利用线程池可以减少创建和销毁线程的开销。但是多线程所面临的并发问题只能说比多进程略好,因为每个线程都拥有自己独立的堆栈,这个堆栈都需要占用一定的内存空间。另外,由于一个CPU核心在一个时刻只能做一件事情,操作系统只能通过CPU切分为时间片的方法,让线程可以较为均匀地使用CPU资源,但是操作系统内核在切换线程的同时也要切换线程的上下文,当线程数量过多时,时间将会被耗用在上下文切换中。所以在大并发量时,多线程结构还是无法做到强大的伸缩性。
多线程的服务模型服役了很长一段时间,Apache就是采用多线程/多进程模型实现的,当并发增长到上万时,内存耗用的问题将会暴露出来,这即是著名的C10k问题。
为了解决高并发问题,基于事件驱动的服务模型出现了,像Node与Nginx均是基于事件驱动的方式实现的,采用单线程避免了不必要的内存开销和上下文切换开销。
基于事件的服务模型存在的问题:CPU的利用率和进程的健壮性。单线程的架构并不少见,其中尤以PHP最为知名——在PHP中没有线程的支持。它的健壮性是由它给每个请求都建立独立的上下文来实现的。但是对于Node来说,所有请求的上下文都是统一的,它的稳定性是亟需解决的问题。
![640?wx_fmt=png](https://i-blog.csdnimg.cn/blog_migrate/462bf619e605164acf44c72f4a0c1abc.jpeg)