项目上线:凌晨的部署

一、最后的倒计时

办公室的挂钟指针,悄然滑过晚上十一点。日光灯管发出嗡嗡的低鸣,映照着几张年轻而疲惫的脸。空气中弥漫着泡面、咖啡和紧张混合的奇特气味。李默盯着屏幕上最后一行待验证的代码,手指悬在回车键上,迟迟没有落下。

这是他职业生涯的第一个正式项目——一个企业官网,带着简单的新闻发布和产品展示功能。过去三个月,他从切图仔变成了这个项目的“前端负责人”,虽然团队算上他也只有三个人。此刻,项目经理老张第三次踱步到他身后,声音沙哑:“小李,测试那边说,IE8下那个产品轮播图……还是有点卡顿。”

李默心里一沉。又是IE8。这个仿佛从上古时代遗留下来的浏览器,吞噬了他无数个调试的深夜。他深吸一口气,强迫自己冷静:“张哥,那个卡顿是IE8的渲染引擎问题,我们用了最轻量的JS库,图片也压缩了。除非砍掉轮播功能,否则……这可能是我们能达到的最好兼容性了。”

老张沉默了几秒,拍了拍他的肩膀:“行,我知道了。你决定。凌晨一点,准时上线。”

二、部署前的“仪式”

所谓的“部署”,在2015年的他们看来,充满了手工时代的笨拙与仪式感。

李默合上笔记本,开始执行他重复了无数遍的“上线清单”:

  1. 压缩资源:打开一个叫“YUI Compressor”的软件,将CSS和JS文件一个个拖进去,看着进度条缓慢爬升,生成带着.min后缀的文件。这步不能错,错一个,页面可能就崩了。
  2. 图片精灵:手动将几十个小图标拼合成一张大图,再用测量工具一个像素一个像素地记录下每个图标的位置,更新CSS中的background-position。眼睛看得发酸。
  3. FTP传输:打开FileZilla,连接到那台位于某IDC机房的Windows服务器。将本地dist文件夹(他们自己建的,没有构建工具)里的文件,小心翼翼地拖到远程的wwwroot目录。网络速度时快时慢,一个大点的图片上传失败,就得重来。
  4. 备份旧版本:将服务器上现有的整个网站文件夹,重命名为wwwroot_backup_20151127。这是他们学到的血泪教训——第一次上线时直接覆盖,出问题后回退无门,被客户骂了整整一周。
  5. 最终替换:将新的wwwroot文件夹上传,覆盖。心跳随着进度条一起跳动。

同事小王凑过来,递上一罐红牛:“默哥,你说这次,能成吗?”

“不知道。”李默拉开易拉罐,泡沫涌出一点,他手忙脚乱地擦掉,“但该踩的坑,我们这三个月应该踩得差不多了……吧?”

他说得没什么底气。前端的世界,尤其是要兼容IE6到IE10、还有各种奇奇怪怪国产浏览器的世界,永远有未知的坑在等着。

三、凌晨一点的战场

零点五十分。所有文件传输完毕。办公室里的空气仿佛凝固了。老张、测试的同事、还有李默和小王,四个人围在一台电脑前。电脑连着投影仪,墙上投出巨大的浏览器界面。

他们打开了十几个浏览器窗口:Chrome、Firefox、IE6、IE7、IE8、IE9、IE10、360浏览器、搜狗浏览器……每个窗口都指向同一个待上线的域名。

“准备。”老张声音低沉,“倒数一分钟。李默,你负责切换DNS解析,指向新服务器。小王,你盯着Chrome和Firefox。测试小刘,你盯IE系列。我整体看。”

李默手心全是汗。他登录到域名管理后台,找到了那条A记录。将原来的IP,改成新服务器的IP。点击“保存”。

“解析生效需要时间,大概2-10分钟不等。”他哑着嗓子说。

“等。”老张只说了一个字。

时间一分一秒过去。墙上的时钟秒针走动的声音,似乎被放大了无数倍。每个人都不断刷新着面前的浏览器。

“Chrome,正常!”
“Firefox,正常!”
“IE9,正常!IE10,正常!”
“IE8……等等,IE8页面布局乱了!”小刘突然喊道。

李默脑袋“嗡”的一声,几乎要炸开。他扑到小刘的电脑前。果然,在IE8下,那个他们反复调试了无数次的首页布局,右侧栏掉到了主要内容区的下面。

“清除缓存了吗?”他急问。
“清了!还是这样!”
“F12开发者工具……看看!”李默自己都忘了,IE8那简陋无比的“开发者工具”,几乎看不出什么有用信息。

他强迫自己冷静,快速回忆。突然,他想起昨天修改过一个CSS的float属性,为了解决Chrome下的一个小间距问题。“是不是那个clearfix的hack,在IE8下没生效?快,把我本地那个ie8.css文件找出来,里面有针对IE8的单独样式补丁!”

小王立刻找到文件,通过FTP单独上传了这个只有几KB的CSS文件,并在IE8的条件注释中引用。

刷新。
页面缓缓渲染,右侧栏颤颤巍巍地,回到了它该在的位置。

所有人都长出了一口气。

“继续监测!其他浏览器有没有受影响?”老张问。
大家快速检查了一圈。“没有变化,正常。”
“好。IE7呢?IE6呢?”
“IE7……正常。IE6……”小刘顿了顿,“IE6下,那个半透明的PNG图片,背景是灰色的,不是透明的。”

李默闭上眼,叹了口气。这是IE6著名的PNG Alpha通道不支持问题,他们早就知道,也用了专门的JS修复库(DD_belatedPNG),但看来在某个角落还是漏了。

“这个……不影响主要功能,先记录,明天白天专门修复。”老张做出了决策。李默知道,这是权衡后的结果,不能让一个次要的视觉效果,卡住整个上线流程。

四、黎明与“成功”

凌晨三点半。主要功能在所有“重要”浏览器(IE8及以上,加主流现代浏览器)上测试完毕,未发现阻断性bug。

老张宣布:“初步上线成功。大家辛苦了,回去休息吧。上午十点,回来开复盘会,并处理IE6的PNG等遗留问题。”

走出办公楼,清冷的空气扑面而来。城市还在沉睡,街道空旷。李默和小王在路边等车。

“默哥,我们这算……成功了吗?”小王问。
李默看着远处天际线泛起的一丝鱼肚白,点了点头,又摇了摇头:“算把代码放到服务器上,能跑了。但真正的成功,要看明天白天,真实用户在各种千奇百怪的电脑、浏览器、网络环境下访问时,会不会出问题。”

车来了。上车前,李默回头看了一眼公司所在的楼层。那里还有几盏灯亮着,是运维的同事在监控服务器状态。

他知道,对于互联网产品而言,“上线”从来不是一个时间点,而是一个漫长的、需要持续守护的状态。那个他们亲手传上去的wwwroot文件夹,就像一个刚刚发射升空、还未进入稳定轨道的卫星,此刻正在未知的太空环境中接受考验。

而他们这些铸造它的人,能做的,就是在它偏离轨道时,尽快把它拉回来。

坐在车里,疲惫如潮水般涌来,但李默心中却有一种奇异的充实感。他亲手将一段段代码、一张张图片,变成了一个能被千万人访问的“存在”。这种从无到有的创造,以及其中伴随的焦虑、挣扎和最终的(哪怕是暂时的)稳定,让他真切地触摸到了这份职业的重量。

青铜时代的征程,就是在这样一个又一个凌晨的部署中,被笨拙而又坚定地推向前方。每一次上线,都是一次毕业典礼,也是一次新的开学仪式。他们知道,天亮了,坑还在,路还长。