谈谈单服务器下的高性能编程

一、背景

单服务器下的编程,想要高性能,该怎么做?
确切地说,怎么使用好“异步”这个银弹?大多数人会说,使用线程池!!没错,线程池采用了池化技术,是Doug Lea 专门为了多线程编程,利用java实现了线程池技术,方便编程人员直接使用。
这篇文章我们想探讨的内容包括:

  • 单服务器下,PPC模式 (Process Per Connection)
  • 单服务器下,TPC模式 (Thread Per Connection)
  • 单服务器下,Reactor模式
  • 单服务器下,Proactor模式

通过对上述的模式梳理,希望能总结出线程池技术与Reactor编程模式的关联、异同。

二、PPC模式

每次有新的连接就新建一个进程去专门处理这个连接的请求。

适用于常量连接数,支持的并发连接数有限。fork代价高,后面衍生了一个prefork模式。

三、TPC模式

每次有新的连接就新建一个线程去专门处理这个连接的请求。

适用于常量连接数,存在 CPU 线程调度和切换代价的问题;创建线程虽然比创建进程代价低,但并不是没有代价,后面衍生了一个prethread模式。

四、Reactor模式

事件反应,来一个事件我就有相应的反应。也作Dispatcher模式。IO多路复用统一监听事件,收到事件后分配Dispatch给某个进程。

1、Reactor模式的引入

每个连接都要创建进程/线程,在连接结束后,销毁它,这造成了极大的浪费。为了解决这个问题,一个自然而然的想法就是资源复用,即不再单独为每个连接创建进程/线程,引入资源池技术(线程池技术)。
在引入线程池后,会引出一个新的问题:
进程如何才能高效地处理多个连接的业务?

  • 一个进程一个连接时,进程可以采用“read -> 业务处理 -> write”的处理流程;如果当前连接没有数据可读,则进程就阻塞在read操作上。
  • 一个进程多连接时,进程阻塞在某个连接的read操作上,此时即使其他连接有数据可读,该进程也无法去处理。无法做到高性能!!!

第一种场景下,是没有问题;第二种场景下,解决方法是把read操作改为非阻塞,然后进程不断地轮询多个连接。缺点是:1、轮询消耗cpu;2、一个进程处理几千上万的连接,轮询的效率低。

由此引入IO多路复用结合线程池,完美解决了PPC和TPC的问题。

2、Reactor模式的分类

Reactor数量可以是一个或多个;
资源池的数量可以是单个或多个进程/线程。

  • 单 Reactor 单进程 / 线程
  • 单 Reactor 多进程 / 线程
  • 多 Reactor 多进程 / 线程

1)单 Reactor 单进程 / 线程

适用于业务处理非常快速的场景,比如开源软件redis。

谈谈单服务器下的高性能编程_第1张图片
单 Reactor 单进程 / 线程.png

2)单 Reactor 多进程 / 线程

为了业务处理之间不干扰,把单线程修改为多线程。这里一般是多线程,不会是多进程,因为线程之间通信比较方便,且是共享数据的。

谈谈单服务器下的高性能编程_第2张图片
单 Reactor 多进程 / 线程.png

3)多 Reactor 多进程 / 线程

采用该模式的有著名的nginx, netty。

谈谈单服务器下的高性能编程_第3张图片
多 Reactor 多进程 / 线程.png

四、Proactor模式

来了事件我来处理,处理完了我通知你。模型示意图见下:

谈谈单服务器下的高性能编程_第4张图片
Proactor模式.png

你可能感兴趣的:(谈谈单服务器下的高性能编程)