一开始提到脉冲流量,我想到的不是什么高深的限流算法,而是上周五那个CPU曲线红得发紫的晚上。起因特别小,我在豆瓣小组跟人争论某款蓝牙耳机的低频到底是不是虚标,吵到一半,顺手挂了张自建测试页的截图。结果帖子被转到虎扑,几个数码博主接着引用,凌晨2点那个页面开始起飞。平常一天也就80多个人看的东西,那一晚几乎每三分钟涌进1500多人,到3点静态页访问量破了26万。我这台服务器是2核4G,平时当个人博客跑得挺悠闲,那一瞬间忽然觉得自己变成了一颗豌豆射手,面前站了一大排红眼巨人。头二十分钟Nginx日志几乎全是502,PHP-FPM进程直接挤满,后台面板点开要等半分钟。
后来我冷静下来看数据,发现脉冲流量和普通流量的差异不是量的大小,而是性质完全不同。普通流量的来访很散,像润物细无声的细雨,来自各个搜索词、书签、外链,时间分布平坦,你有充足时间从日志里琢磨页面要不要改、哪个按钮点的人多。脉冲流量则像被上游水库开闸放了一次水,在极短时间里涌进来的请求大多是同一个URL、同一个平台、同一种表述。用户从讨论帖或者某个大V转发里点进来,并没有强烈的意愿了解你整个站,他们的到来本身就是一道洪峰,注意力转瞬即逝。这时候谈体验优化、内容更新都太奢侈,唯一的现实问题就是:能不能在流量塌方之前把页面打开。
扛这次脉冲,我没有也用不起复杂的弹性集群,只做了三件还算土的消峰操作。第一是开Redis缓存那个测评页的json数据,缓存时间设置十分钟,因为这群人挤进来看的都是同一批拆机图和频响曲线,数据库根本没机会被真正打到。第二是调整Nginx的worker_connections从默认1024提到4096,把php-fpm进程数从4降到2,反正动态请求非常少,省出来的内存全扔给静态文件缓存。第三是在网关上加了简单的限流,同一IP每秒最多5次请求,多的直接返回“请稍后刷新”。最后看了下记录,峰值每秒大概370次请求,被缓存和限流挡掉了近九成,居然稳稳扛住了。但真正让我在意的其实是另一个数据:这波访问里,只有700多个去重IP点了那个文件下载按钮。那些转帖带来的人,绝大多数只看了第一屏就离开了。
所以我的看法可能和那些教人如何防脉冲的教程不太一样。脉冲流量确实会带来服务器压力,但它也是极少数的、能让陌生人忽然对一个几乎没人知晓的小页面产生好奇的机会。与其一门心思去扩容、上CDN、做负载均衡,不如想一想人的行为是怎么被推动的。那晚过后,真正留下私信跟我讨论耳机的几个人里,有一位专门做音频测量的工程师,还有一个后来问我能不能把页面打包成工具。如果为了追求平稳而提前把页面捂得严严实实,或者把所有请求都交给运营商缓存,那我可能根本不会听到他们的声音。说到底,洪峰退掉之后留在岸边的贝壳,才是流量脉冲真正有价值的部分。我现在甚至有点怀念那个502的夜晚,它至少证明了这个角落还在被真实的人看见。