一、基础知识
1、一个主机的端口号为所有进程所共享 , 但普通用户进程绑定bind不了一些特殊端口号如20、80等 。
多个进程不能同时监听listen同一个端口 , 会失败 。当然父进程可以先listen然后fork多个子进程 , 多个子进程都可以accept这个sock , 即抢夺式响应(惊群效应) 。
关注4元组是否能唯一确定一个连接?
2、每个进程都有自己的文件描述符(包括file fd, socket fd, timer fd, event fd, signal fd) , 一般是1024 , 可以通过ulimit -n 设置 , 但所有进程打开的文件描述符总数有上限 , 跟主机的内存有关 。
3、一个进程内的所有线程共享进程的文件描述符 。
二、并发服务器方案:
1、循环式/迭代式( iterative )服务器
无法充分利用多核CPU , 不适合执行时间较长的服务 , 即适用于短连接 。如果是长连接则需要在read/write之间循环 , 那么只能服务一个客户端 。
文章插图
2、并发式(concurrent)服务器
one connection per process/one connection per thread
适合执行时间比较长的服务
文章插图
one connection per process : 主进程每次fork 之后要关闭connfd , 子进程要关闭listenfd
one connection per thread : 主线程每次accept 回来就创建一个子线程服务 , 由于线程共享文件描述符 , 故不用关闭 。
3、prefork or pre threaded(容易发生“惊群”现象 , 即多个子进程都处于accept状态)
文章插图
4、反应式( reactive )服务器 (reactor模式)(select/poll/epoll)
并发处理多个请求 , 实际上是在一个线程中完成 。无法充分利用多核CPU
不适合执行时间比较长的服务 , 所以为了让客户感觉是在“并发”处理而不是“循环”处理 , 每个请求必须在相对较短时间内执行 。
文章插图
5、reactor + thread per request(过渡方案)
6、reactor + worker thread(过渡方案)
7、reactor + thread pool(能适应密集计算)
文章插图
muduo库中的/example/suduku/ 中有这样一个例子 , 因为数独求解是计算密集型任务 。
在实践中为了reactor能快速回到事件循环去响应请求 , 经常将读到的数据put到一个环形内存队列(一般内存or共享内存) , 而thread pool的线程则从中读取进行数据计算 。
需要C/C++ linux服务器架构师学习资料私信“资料”(资料包括C/C++ , Linux , golang技术 , Nginx , ZeroMQ , MySQL , redis , fastdfs , MongoDB , ZK , 流媒体 , CDN , P2P , K8S , Docker , TCP/IP , 协程 , DPDK , ffmpeg等) , 免费分享
文章插图
8、multiple reactors(能适应更大的突发I/O)
reactors in threads(one loop per thread)
reactors in processes
一般来说一个subReactor适用于一个千兆网口
文章插图
9、multiple reactors + thread pool(one loop per thread + threadpool)(突发I/O与密集计算)
subReactor可以有多个 , 但threadpool只有一个 。
文章插图
10、proactor服务器(proactor模式 , 基于异步I/O)
理论上proactor比reactor效率要高一些
异步I/O能够让I/O操作与计算重叠 。充分利用DMA特性 。
Linux异步IO
glibc aio(aio_*) , 有bug
kernel native aio(io_*) , 也不完美 。目前仅支持 O_DIRECT 方式来对磁盘读写 , 跳过系统缓存 。要自已实现缓存 , 难度不小 。
boost asio实现的proactor , 实际上不是真正意义上的异步I/O , 底层是用epoll来实现的 , 模拟异步I/O的 。
推荐阅读
- 如何解密 Linux 版本信息
- 深入聊聊Linux 五种IO模型
- kali linux之应用层Dos
- linux内核驱动第1讲:带你编写一个最简单的字符设备驱动
- Linux常规命令
- 整理 Linux下列出目录内容的命令
- linux系统中socket错误码:eintr和eagain的处理方法
- Linuxfx - 这套Linux操作系统看起来和Windows 10非常类似
- 外网主机A通过带内外网的Linux跳板机B直接访问内网机器C服务
- 带你阅读linux内核源码:下载源码、编译内核并运行一个最小系统