小乙侃科技|高性能开发十大必须掌握的核心技术


小乙侃科技|高性能开发十大必须掌握的核心技术
文章图片
作者|轩辕之风O
来源|编程技术宇宙(ID:xuanyuancoding)
程序员经常要面临的一个问题就是:如何提高程序性能?
这篇文章 , 我们循序渐进 , 从内存、磁盘I/O、网络I/O、CPU、缓存、架构、算法等多层次递进 , 串联起高性能开发十大必须掌握的核心技术 。
首先 , 我们从最简单的模型开始 。
老板告诉你 , 开发一个静态web服务器 , 把磁盘文件(网页、图片)通过网络发出去 , 怎么做?
【小乙侃科技|高性能开发十大必须掌握的核心技术】你花了两天时间 , 撸了一个1.0版本:
主线程进入一个循环 , 等待连接 。 来一个连接就启动一个工作线程来处理 。 工作线程中 , 等待对方请求 , 然后从磁盘读文件、往套接口发送数据 。 上线一天 , 老板发现太慢了 , 大一点的图片加载都有卡顿感 。 让你优化 , 这个时候 , 你需要:
小乙侃科技|高性能开发十大必须掌握的核心技术
文章图片
I/O优化:零拷贝技术
上面的工作线程 , 从磁盘读文件、再通过网络发送数据 , 数据从磁盘到网络 , 兜兜转转需要拷贝四次 , 其中CPU亲自搬运都需要两次 。
小乙侃科技|高性能开发十大必须掌握的核心技术
文章图片
零拷贝技术 , 解放CPU , 文件数据直接从内核发送出去 , 无需再拷贝到应用程序缓冲区 , 白白浪费资源 。
小乙侃科技|高性能开发十大必须掌握的核心技术
文章图片
LinuxAPI:
ssize_tsendfile(intout_fd,intin_fd,off_t*offset,size_tcount)
函数名字已经把函数的功能解释的很明显了:发送文件 。 指定要发送的文件描述符和网络套接字描述符 , 一个函数搞定!
用上了零拷贝技术后开发了2.0版本 , 图片加载速度明显有了提升 。 不过老板发现同时访问的人变多了以后 , 又变慢了 , 又让你继续优化 。 这个时候 , 你需要:
小乙侃科技|高性能开发十大必须掌握的核心技术
文章图片
I/O优化:多路复用技术
前面的版本中 , 每个线程都要阻塞在recv等待对方的请求 , 这来访问的人多了 , 线程开的就多了 , 大量线程都在阻塞 , 系统运转速度也随之下降 。
这个时候 , 你需要多路复用技术 , 使用select模型 , 将所有等待(accept、recv)都放在主线程里 , 工作线程不需要再等待 。
小乙侃科技|高性能开发十大必须掌握的核心技术
文章图片
过了一段时间之后 , 网站访问的人越来越多了 , 就连select也开始有点应接不暇 , 老板继续让你优化性能 。
这个时候 , 你需要升级多路复用模型为epoll 。
select有三弊 , epoll有三优 。
select底层采用数组来管理套接字描述符 , 同时管理的数量有上限 , 一般不超过几千个 , epoll使用树和链表来管理 , 同时管理数量可以很大 。 select不会告诉你到底哪个套接字来了消息 , 你需要一个个去询问 。 epoll直接告诉你谁来了消息 , 不用轮询 。 select进行系统调用时还需要把套接字列表在用户空间和内核空间来回拷贝 , 循环中调用select时简直浪费 。 epoll统一在内核管理套接字描述符 , 无需来回拷贝 。 用上了epoll多路复用技术 , 开发了3.0版本 , 你的网站能同时处理很多用户请求了 。
但是贪心的老板还不满足 , 不舍得升级硬件服务器 , 却让你进一步提高服务器的吞吐量 。 你研究后发现 , 之前的方案中 , 工作线程总是用到才创建 , 用完就关闭 , 大量请求来的时候 , 线程不断创建、关闭、创建、关闭 , 开销挺大的 。 这个时候 , 你需要: