前提
IO编程中,。Input Stream就是数据从外面(磁盘、网络)流进内存,Output Stream就是数据从内存流到外面去。对于浏览网页来说,浏览器和新浪服务器之间至少需要建立两根水管,才可以既能发数据,又能收数据。由于CPU和内存的速度远远高于外设的速度,所以,在IO编程中,就存在速度严重不匹配的问题。举个例子来说,比如要把100M的数据写入磁盘,CPU输出100M的数据只需要0.01秒,可是磁盘要接收这100M数据可能需要10秒。所以我们可以理解为cpu处理数据多速度是很快的,但是主要的时间耗费在IO上。
1. 多进程处理
为了解决同步架构的并发问题,一个简单的改进是通过进程的复制同时服务更多的请求和用户。这样每个连接都需要一个进程来服务,即100个连接需要启动100个进程来进行服务,这是非常昂贵的代价。
2. 多线程处理
让一个线程服务一个请求。线程相对进程的开销要小许多,并且线程之间可以共享数据,并且利用线程池可以减少创建和销毁线程的开销。但是线程过多,在CPU中较多的切换线程会浪费CPU资源,当线程数量过多时,时间将会被耗用在上下文切换中(这也就是多线程编程中为何开启更多的线程并不能提高性能的原因)。所以在大并发量时,多线程结构还是无法做到强大的伸缩性。 虽然效率够高但是耗费CPU资源而且多线程问题很多,比如安全问题等等。
Apache就是采用多线程/多进程模型实现的,当并发增长到上万时,内存耗用的问题将会暴露出来,这即是著名的C10k问题。
3. 事件驱动模型
为了解决高并发问题,基于事件驱动的服务模型出现了,像Node与Nginx均是基于事件驱动的方式实现的,采用单线程避免了不必要的内存开销和上下文切换开销。
异步(也就是IO多路复用模型)。
单线程任务交错在cpu执行效率高,而且不会出现多线程问题。
灰色表示IO处理的延迟,因为IO延迟比较高,CPU数据处理延迟几乎可以忽略。