018-服务器的“排班艺术“:从奶茶店看并发模型那些事儿
曾几何时,你跟一群技术大佬在茶馆吹牛,有人拍着桌子说"高性能这事儿,本质就是把人用对地方"。当时你还觉得是玄学,直到某天蹲在公司楼下的奶茶店等单,看着前台小姐姐手忙脚乱的样子,突然悟了——服务器处理请求,跟奶茶店接订单简直是一个模子刻出来的。

当奶茶店刚开业:来了客人就招人(PPC模式)
假设你开了家奶茶店,刚开始生意冷清,每天就零星几个客人。你的运营策略简单粗暴:只要有客人推门进来,就当场招一个全职员工专门伺候他——客人点单、做奶茶、打包,全由这个员工负责,直到客人拎着奶茶走人,这个员工就"下岗"(进程销毁)。
这操作是不是很眼熟?这就是服务器界的PPC(Process Per Connection)模式:每个新连接来了,就新创建一个进程处理,从头到尾一对一服务。

但问题很快就来了。某天你的奶茶店突然成了网红店,排队排到街对面。客人一茬接一茬,你就得马不停蹄地招人——签合同(分配内核资源)、复印身份证(复制内存映像)、培训怎么做奶茶(初始化进程状态)。光是招人流程就耗掉大半时间,客人等得直跺脚,差评刷满了点评网站。
更头疼的是,这些全职员工各干各的,想让他们互相帮忙递个珍珠都难(进程间通信复杂)。要是某天突然涌来几百个客人,店里塞不下这么多员工,走路都得互相绊脚(进程调度压力大),最后只能挂个"今日售罄"的牌子(并发连接上限被捅破)。
提前招好人:把"临时工"变成"预备役"(prefork模式)
吃了亏的你学聪明了:既然客人多的时候招人来不及,那开业前就先招一批全职员工等着。客人一进门,直接抓一个现成的员工服务,省去了临时招人的麻烦。这就是prefork模式的精髓——“提前创建进程”。
但新问题又冒出来了。某天你站在店门口看,发现一群员工挤在收银台旁边,只要有客人进来,所有人都条件反射地往前冲(惊群现象),最后只有一个人抢到订单,其他人白激动一场,还耽误了手头的活儿。后来你给收银台装了个叫号器(Linux 2.6内核优化),才总算让大家不用瞎起哄。
可这模式还是没解决根本问题:全职员工工资高(进程资源占用大),店里最多只能养200人(Apache prefork默认256连接上限)。赶上周末大促,照样得眼睁睁看着客人被隔壁奶茶店抢走。
改用兼职:成本降了,但麻烦来了(TPC模式)
你看着账本上的工资单,突然想到:要不招兼职?兼职不用签长期合同(创建线程代价低),也不用单独给他们配工作台(线程共享进程内存),成本低多了。客人来了,喊个兼职过来服务,效率明显提升——这就是TPC(Thread Per Connection)模式:每个连接对应一个线程。
但兼职多了也头疼。有次两个兼职同时抢一台果糖机(线程竞争资源),一个说"我先按的",一个说"我手快",吵到最后把机器砸了(死锁)。更要命的是,有个兼职擦桌子时打翻了热水,溅到了旁边正在做奶茶的兼职身上,结果俩人全撂挑子了(一个线程异常导致进程崩溃)。
你这才发现,兼职虽灵活,但得天天盯着他们别打架(线程同步),还得防着有人搞破坏(线程安全),管理成本一点没少。
兼职也提前招:把"救火队"变成"常备军"(prethread模式)
吸取了教训,你搞了个"兼职预备役":每天开业前,让一批兼职在休息区待命,客人来了直接派活。这就是prethread模式——提前创建线程池,省去临时创建线程的开销。
更妙的是,你把兼职分成几个小组(多进程+多线程),每组配个小组长(进程管理线程)。某天三组的兼职跟客人吵起来了(某个进程崩溃),你直接把三组解散重新招人,其他组照样正常出单(Apache worker模式的稳定性设计)。
现在你的奶茶店,既能应付高峰期的客流(支持更多并发),又能控制成本(线程轻量),偶尔出点小问题也不影响全局——这大概就是单服务器并发模型的终极追求了。
说到底,适合的才是最好的
回头看看,其实没有哪种模式是万能的:
- 要是你开的是社区小茶馆,每天就几个熟客(低并发、长连接),PPC模式反而稳当,毕竟全职员工靠谱(进程隔离性好);
- 要是做网红快闪店,客人来得猛走得快(高并发、短连接),prethread模式的兼职预备役才能扛住;
- 至于那些既要稳定又要兼顾并发的场景(比如电商秒杀预热),多进程套多线程的"混合编队"才是王道。
所以啊,服务器的高性能密码,跟开奶茶店没啥区别——搞懂自家的客流特点(业务场景),再琢磨透员工的脾性(进程/线程特性),排班表(并发模型)自然就清晰了。下次再跟大佬喝茶聊性能,你大可以掏出奶茶店的例子,保管他们点头称是。








