最近阅读某大牛的公众号时,其讲Kafka请求全流程和源码时又提到了熟悉又陌生的Reactor模式。熟悉是因为可以说基本上只要底层是高性能网络通信就一定和Reactor模式息息相关,比如Netty,Redis等底层都是Reactor模式。陌生是仍不能探其究竟、知其本真。
早期的网络编程当一个请求过来了,要么当前线程直接就处理了要么另起一个新的线程去处理,一个线程很容易处理不过来且又没有充分利用计算机资源,而每次新起一个线程则对计算机资源要求太高。没错,线程池是一个很好的选择,池化技术确实能缓解资源问题。但池子也是有限的,池子里的线程也是在候着连接等待指示。现在的互联网早就突破C10K(concurrent 10000 connection),应对C10K问题的关键在于充分利用计算机资源、减少CPU消耗。故,引入I/O多路复用,由一个线程监控一堆连接,同步等待一个或多个I/O事件的到来,分配给对应的handler处理,即Reactor模式。
网络通信模型的发展线路:
单线程 => 多线程 => 线程池 => Reactor模型
讲那么多,就是想说理解I/O模型和I/O多路复用很重要。呵呵。
C10K问题本质上是操作系统的问题,故还得从操作系统入手。
本节先理解操作系统(linux)的User space用户空间和Kernel space内核空间。
简单来说,Kenel space是linux的内核运行空间,User space是用户程序的运行空间。安全起见,它们是相互隔离的,当用户程序崩溃时内核不受影响。在内核空间可以执行任何命令、调用系统的一切资源;用户空间内只能执行简单的运算&