让我们先把这场半夜3点的惊慌无措搁在一边。在我们解决问题之前,得先理解问题。所以问题来了:“服务器”到底是啥?
请暂时忽略过于技术的解释。忘记在冰冷机房闪烁的指示灯。在本书剩余部分,我建议你用一个更简单浅显的概念来看待“服务器”:它就是只有一个厨师的餐厅后厨,所以很明显那个厨师会非常忙碌。
这个类比将会是有关服务器架构的最重要基础,其它东西都将在这个类比的基础上构建。
CPU: 厨师的速度
中央处理器 (Central Processing Unit) 就是掌勺的大厨。它是所有处理逻辑的核心大脑。这位厨师把原料 (数据)按照菜谱(代码)制作成一道可口的菜肴(一张网页,一个搜索结果,一笔完成的订单)。
● 更快的CPU ****(用千兆赫作为单位, 即GHz) 意味着你拥有手脚更麻利的厨师。 它可以用更快的速度进行切菜,炒菜和装盘。
● 多核CPU就像厨师多了几个机械臂 。 比如4核CPU就像一位能够同时操作切菜,炒菜,煎炸和调味的厨师。它可以在同一时间处理多项任务。
我们那512MB的服务器只有一个单核CPU。按照这个厨师的类比,就如同我们只有一位独臂大厨但我们却要求他为1万人做一顿大餐。
RAM: 厨房的操作台面空间
内存(Random Access Memory)就是厨房的操作台面。这是理解服务器最关键的一步。内存就是厨师可以利用的工作空间。厨师(CPU)会使用内存来保存当前正在被制作的菜肴所需的所有原料以及锅碗瓢盆。
从厨房台面拿取所需非常快速。厨师甚至不需要思考, 想要什么直接伸手去拿就可以了。 更多的内存意味着更大的操作台面。如果拥有很大的操作台面,那厨师可以立马处理很多不同的点餐需求因为所有食材都在它面前的台面上摆放着可供随时取用。
但是如果台面放不下了,那厨师就会有棘手的麻烦。他得放下手头正在处理的活儿, 一头钻进后面的储藏室,从中花时间找到并拿回他所需的食材,还需要从台面上挪走一些东西以便腾出空间。这样一个操作明显会让所有事情都变得更慢。
这就是之前发生在我们服务器上的事情。我们仅有512MB的服务器就好比一个只有砧板大小的厨房台面。而我们自己的应用(Dukkan),我们的数据库以及服务器上的操作系统本身 全都在争夺这一块小小的砧板空间。所以当台面放不下的时候,服务器开始使用 "SWAP"空间—可以看成是储藏室中一个特殊的区域,在临时救急时也可用作台面空间。这肯定是效率极低的方案。厨师不得不花时间来回奔走于储藏室与台面之间,必然耽误了它真正用于烹饪的功夫。
磁盘: 厨房的储藏室
磁盘,无论是传统机械硬盘或者是固态硬盘,都可以看做厨房的储藏室和冰箱,是用来长期存储菜谱(代码),食材(数据)以及厨房用具(操作系统)的地方。
储藏室比操作台面(RAM)显然要大很多,但存取耗时也要慢很多很多. 你肯定不希望你的厨师即使为了拿一点点食盐也得跑去储藏室一趟。 最理想当然是食盐就摆在它的操作台面上。
资源竞争: 厨房里的无序
现在请设想一下我们面对的场景。在一个迷你的厨房里,我们的独臂厨师只有一个砧板大小的操作台面, 然后我们苛求它完成:
● 运行应用程序: 厨师需要看明白菜谱(我们的Python代码) 并完成菜肴的烹制。
● 管理数据库: 大厨还得兼任储藏室管理员,不停地把食材(我们的用户数据)分门别类记录好 ,保存好并按食谱准确地取用。
● 处理网络流量: 除了以上, 大厨还需要完成服务生的工作:跑到餐厅前台以最快速度为数千用户点单。
这就是资源竞争。每一项任务都在同一时刻高呼大厨希望优先得到处理。应用程序需要CPU来处理运算逻辑,数据库需要把数据写入磁盘,还有刚接收到的用户请求需要内存来暂时记录。所有这些都在竞争同一个有限的资源,所以结果就是完全的死局,无法动弹。
如果想看到厨房里发生的这些无序竞争,你可能需要安装一个监控摄像头。在服务器的世界里,我们的摄像头只是一个简单的命令:htop. 它是命令行工具 top的优化版本,可以让你犹如现场直播般看到大厨正在忙啥。
虽然可能看上去挺复杂,但你只需要了解以下几点:
● 顶部的CPU柱: 如果它显示红色的100%,那你的大厨就是过载了。
● 内存柱: 如果这个数字满了,说明你的操作台面已经放不下了。
● SWAP柱: 如果这个数字开始增加,这不是好的信号。说明你的大厨正在尝试使用储藏室作为额外的操作台面。
● 进程列表: 这里展示了大厨正在处理的每一个任务并且能让你看到哪一个占用了最多的资源。
学会读懂这个htop的输出只是成为CTO(要么像我这样误打误撞,要么按部就班)的第一步。从这里开始,我们将进行科学的诊断而不是盲目的瞎猜。对于我个人而言, 那晚半夜3点的服务器屏幕尖锐地喊出了一个无可辩驳的事实: 我们的厨房对于我们的抱负而言,实在是太小了,小到足以致命。