飞哥的开发内功修炼技术号更新文章有一年多了,以前的文章都是单独介绍一个技术点,没给大家一个整体的视角。所以有的读者读到个别文章的时候难免就会有困惑。
比如我曾经写过的 说出来你可能不信,内核这家伙在内存的使用上给自己开了个小灶! 。有的读者就纳闷了,你研究内核使用内存这么深,工作中有啥用么。
今天我就来说一下我的创作整体思路。我在选题的时候,并不是想到啥就写啥的,而且很早就有一个规划。拿网络篇来说,可以用一个短句来概括这个规划,那就是理解网络性能。在确定了研究目标以后,我对任务进行了拆解,把性能拆分为三个角度:CPU 开销、内存开销、时间开销。
具体到某个角度比如 CPU,那我需要给自己解释清楚网络包是怎么从网卡到内核中的,内核又是通过哪些方式通知进程的。只有理解清楚了这些才能真正把握网络对 CPU 的消耗。
对于内存角度也是一样,只有理解了内核是如何使用内存,甚至需要哪些内核对象都搞清楚,也才能真正理解一条 TCP 连接的内存开销。
飞哥把之前网络篇相关的所有文章都做了个汇总,也添加了部分新内容比如性能优化建议和前沿技术展望等,整理出了一本电子书。我给它起了个名字叫《理解了实现再谈网络性能》。在这本电子书里,你将能更清晰看到我的整体思路,也将能更深入地把握网络性能开销。
今天在这里我把这本《理解了实现再谈网络性能》献给大家,在文末介绍电子书的获取方式。
修炼技术内功有啥好处
先容许我多扯一点。我在我的技术群里看到有的同学说他去面试,遇到面试官说:“你是来面 PHP 的,懂 IO 多路复用这玩意儿有啥用!”。我只能说这个面试官一定自己的技术级别也不高,只懂得 CURD 之类的技术。如果是高级别的开发连 IO 多路复用是啥都不懂,以后项目中网络遇到瓶颈怎么优化,遇到高并发怎么样选择更优秀的技术方案。
我觉得目前大多数的业界的技术学习都太偏向于各种花拳绣腿了,太缺乏对内功的重视,上面的面试官就是一个典型的例子。
高性能的 PHP 异步网络通信引擎 swoole 的作者韩天峰说过,很多程序员职业规划的文章,上来就是 Linux、PHP、MySQL、Nginx、Redis、Memcache、jQuery 这些,然后就直接上手搭环境、做项目,中级就是学习各种 PHP 框架和类库,高级阶段就是 MySQL 优化、PHP 内核与扩展、架构设计这些了。这些文章都存在一个严重的缺陷,不重视基础。就好比练武功,只求速成,不修炼内功和心法,只练各种招式,这样练出来的高手能高到哪里去?
事实上,码农圈里的牛人比如韩天峰,比如 PHP7 作者鸟哥,他们都具备非常非常扎实的基础,他们之所以牛,并不是他们掌握的花拳绣腿的功夫多,而是内功非常非常深厚。举个小例子,鸟哥在 PHP7 中把 HashTable 结构体从 72 字节压缩到了 56 字节,表面看起来不大的优化,实际上是数倍的性能提升。因为 CPU 在向内存要数据的时候是以 Cache Line 为单位进行的,一个 Cache Line 是 64 字节。56 字节可以一次请求搞定,而原来的 72 字节则需要两次。另外就是 L1/L2/L3 的命中率也会提升很多,这个对性能的帮助更大。显然鸟哥深谙 CPU 的工作原理。
内功它不帮助你掌握最新的开发语言,也不教会你时髦的框架,也不会带你走进火热的人工智能。但是我相信它是你成为大牛的必经之路。我简单列一下锻炼内功的好处:
1)内功方面的技术生命周期长。Linux 操作系统 1991 年就发布了,现在还是发展的如日中天。对于作者 Linus,我觉得他也有年龄焦虑。但他可能焦虑的找不到合适的接班人。反观应用层的一些技术尤其是很多的框架,生命周期能超过十年我就已经觉得他很牛叉了。如果你的精力全部押宝在这些生命周期很短的技术上,你说能不焦虑吗!所以我觉得戒掉浮躁,踏踏实实练好内功是你对抗中年焦虑的解药之一。
2)内功深厚的人理解新技术非常快。不用说业界的各位大牛,就拿我自己来举两个小例子。我其实还没怎么去翻过 kafka 的源码。但是当我研究完了内核是如何读取文件的、内核处理网络包的整体过程后,就秒懂了 kafka 在网络这块为啥性能表现很突出了。另外一个是当我理解了 epoll 的内部实现以后,回头再看 Golang 的 net 包,才切切实实看懂了地球上绝顶精妙的对网络 IO 的封装。所以 Linux 内核你真的弄懂了的话,再看应用层的各种新技术就犹如带了透视镜一般,直接看到骨骼。
3)内核提供了优秀系统设计的实例。Linux 作为一个千锤百炼的系统,其中蕴含了大量的世界顶级的设计和实现方案。平时我们在自己的业务开发中,在编码之前也需要先进行设计。比如我在刚工作的时候负责的一个数据采集任务调度,其中的实现就是部分参考了操作系统进程调度方案。再比如如何在管理海量的连接,epoll 内部的红黑树 + 就绪队列的组合可以提供给你一个很好的参考。这种例子还有很多很多,总之如果能将 Linux 的某些优秀实现,搬到你的系统中会极大提升你的项目的实现水平。
4)对性能的把握更到位。如果不具备扎实的内功对性能问题很难理解到本质。一般工作几年的同学凭经验能知道 A 快 B 慢,但为啥 A 快,还是不清楚!如果理解底层是怎么运作的,你对性能的把握会更到位、工作中做性能优化才不底虚、做技术方案选型的时候也更得心应手!
时髦的东西终究会过时,但扎实的内功能力将会伴随你的一生。只有具备了深厚的内功底蕴,你才能在你的发展道路上走的更稳、走的更远。
内功修炼网络篇诞生记
我曾经听到过有的人说,学习网络就是在学习各种协议,这种说法其实误导了很多的人。提到计算机网络的知识点,你肯定也首先想到的是 OSI 七层模型、IP、TCP、UDP,HTTP。关于 TCP 再多一点你也会想到三次握手、四次挥手、滑动窗口、流量控制。关于 HTTP 协议就是报文格式、 GET/POST,状态码、Cookie/Session 等等。
这些东西确实很有用,但是我的这些知识却不能帮我清除我在工作实践中的如下几个疑惑。
1)有一次我们运维找过来,说某某几台线上机器上出现了 3 万多个 TIME_WAIT,不行了得赶紧处理哈。后来他帮我们打开了 tcp_tw_reuse 和 tcp_tw_recycle,先把问题处理掉了。 但是我的思考却并没有停止,一条 TIME_WAIT 到底会有哪些开销。端口占用导致新连接无法建立?还是会过多消耗机器上的内存? 3 万条 TIME_WAIT 究竟该算是 warning 还是 error?
2)另外一次是当时公司还没有建立 redis 平台之前,我们业务自己维护了一组 redis server 。为了节约握手开销,我们的业务进程对 redis 开启了长连接。这样一个 redis 实例上最终就出现了 6000 条的连接。虽然每条连接上大部分时间都是空闲的,但是我却在思考一条空闲的连接究竟会有哪些开销?这 6000 条连接会不会把服务器搞坏? 当然最终观测的结果是没啥问题,但是对于细节原理我仍然吃的不是很准。
3)另外一次也是我们业务要把短连接优化成长连接。但是这次涉及到了要访问公司的 Mysql 平台。当时我们公司的 Mysql 需要为每一个 ip 申请一个并发数。因为我们当时使用的是 php-fpm,没有连接池的概念。所以我们有多少个 fpm 进程,就得申请多大的并发数,我们当时申请了 200 个。 然后工程部的同学就过来 PK 了,你们这单机 200 个并发不行,太高了。虽然我最终给他举了上面 redis 的例子,最终他同意了。虽然勉强说服了他,但是我仍然吃不准空闲的 tcp 连接到底开销在哪儿?
经过以上各种实践问题的磨炼,我发现了问题的关键所在。那就是我们大家之前对于计算机网络的知识太多都聚集于协议层面了,太过于偏向理论。而对于网络在机器是如何被实现的,开销如何,却理解太少太少了。 网络是如何使用 cpu 的,如何使用内存的,这些知识感觉在整个业界说很匮乏也不为过。
举个小例子,按理说现在整个业界都在讲高并发,那一台服务器到底能支持多少条 TCP 连接,这算是高并发里很基础的问题了吧。但是当我产生以上疑问以后,在网上、在各种经典书里,都根本搜不到能让我满意的答案。很多文章都是含含糊糊讲了半天 ,讨论了半天的 CxxxK。但看完还是不知道最多能支持多少,更别说具体点的细节了,比如一条 TCP 到底需要消耗多大内存。
所以,飞哥下定决心,要在实现层面把计算机网络扒个底儿朝天,把网络的 cpu 开销,内存开销要彻底搞搞清楚!
开发内功修炼网络篇系列文章就是出于这个背景产生的,进而也诞生出了今天的《理解了实现再谈网络性能》!
电子书目录概览
引言
- 作者简介
- ⻢上 35 岁,我该不该焦虑
- 目前业界技术文章的问题
- ⻜哥深入研究网络的出发点
- 适用读者
一、TCP 连接的 CPU 开销 - 1.1 LINUX 是如何接收一个网络包的
- 1.2 UDP 下用户进程如何和内核协同?
- 1.3 TCP 下用户进程如何和内核协同?
- 1.4 IO 多路复用 EPOLL 内部实现
- 1.5 网络包处理之 CPU 开销汇总
二、TCP 连接的内存开销
- 2.1 内核对象是如何使用内存的
- 2.2 实验测试 TCP 连接内存开销
- 2.3 一台服务器最大可以支撑多少条TCP连接
- 2.4 一台客户端可以支撑多少条 TCP 连接
- 2.5 实验单机100 万 TCP 连接的源码
三、TCP 连接的时间开销
- 3.1 正常TCP连接建立过程
- 3.2 TCP 连接建立时的异常情况
- 3.3 TCP 连接耗时实测
四、LINUX 网络性能优化建议
- 4.1 耗时优化建议
- 4.2 内存优化建议
- 4.3 CPU 优化建议
五、项目实际问题分析
六、前沿技术展望
七、推荐书单
电子书领取方式
先说声小小的抱歉,我并不准备把电子书放到网盘上供大家随意下载。原因有两个:一是飞哥期望这本书能得到你的认可,你愿意把它分享给你的好友和同事;二是我觉得太容易得到的东西大家反而不会珍惜它,直接丢在硬盘里吃灰,这也是我不想看到的。
所以我设置了个小门槛,需要符合以下两个条件中的任意一个就行。
- 获取方式 1:配一句话的(几个字都行)推荐语分享本文到朋友圈。然后加飞哥,我通过微信发你。
- 获取方式 2:把本公众号推荐给你身边的至少一位朋友。加飞哥,把你好友的微信昵称发给我,这位好友须是最近两天的新粉。
完成上面任意一个就行,我会在微信上把电子书发给你。而且只要完成一次,后期当电子书再更新升级的时候,都可以享受获取最新版的权益。
只要你认可飞哥的这本电子书,我觉得这个完成起来非常的容易。绝不会给你造成太大的负担!飞哥的微信如下:zhangyanfei748528
水平有限,疏漏难免,如你发现书中内容中有描述不正确的地方,欢迎指正。
最后,还是求转发!!
PS:由于我的这些知识在公众号里文章比较分散,很多人似乎没有理解到我对知识组织的体系结构。而且图文也不像视频那样理解起来更直接。所以我在知识星球上规划了视频系列课程,包括硬件原理、内存管理、进程管理、文件系统、网络管理、Golang语言、容器原理、性能观测、性能优化九大部分大约 120 节内容,每周更新。加入方式参见我要开始搞知识星球啦、如何才能高效地学习技术,我投“融汇贯通”一票
Github:https://github.com/yanfeizhang/coder-kung-fu
关注公众号:微信扫描下方二维码