游侠 X 新车发布会惊魂半小时

作为游侠一员,2015年7月26日游侠发布会的时候我就在后台等待着准备把游侠 X 的介绍网页上线,同时监视网站图文直播的工作状态,最后再顺便监视一下车机的在线状态。

这里所谓的车机指的是车载的 Android 系统,而不是汽车的 ECU。我们在工作中都把这个 Android 系统简称为车机,下文出现的“车机”都指这个 Android 系统。

其实发布会的时候出了一些状况,虽然表面上看发布会很成功,但实际上和我们彩排时的流程不一样,有一些东西没有进行演示,这就是我经历的惊魂半小时。

发布会开始的时候,和预料中的一样,网站涌入了大量用户,估计都是来看直播的。直播页面每 5~30 秒自动更新一次,这会给平时流量不大的网站带来很大的压力。其实这种情况我们在发布会之前就已经预料到了,所以提前购买了额外的带宽,并估算了 CPU 的承载能力。根据当时的估算,我们可以承受一万人同时使用在线图文直播。

先来说一下会场的网络环境,我们提前在会场布置了 WIFI,但考虑到人数众多,但带宽有限,所以我们只把这个 WIFI 提供给媒体使用。

虽然我们没有向所有人公开 WIFI,但是参会的人员基本上都是人手一台打开了 WIFI 的智能设备,现场的无线网络环境可以说是非常复杂,这给后面的惊魂时刻埋下了伏笔。

刚开始的时候,网站还是好好的,这时候有游侠的同学使用手机访问我们自己的网站,发现速度比较缓慢。当时我认为可能是会场的无线网络信号的问题,并没有太在意。我自己使用手机访问了一下,发现速度虽然比平时慢了些,但尚可接受,于是没有继续关注。

又过了几分钟,负责微博直播的同学告诉我,微博上有人反映网站打不开啦。我立刻在电脑上打开我们的网站,发现网站真的挂掉了。

这就出大问题啦,网站挂掉的话网站图文直播功能就没法用了。首先我怀疑可能是 PHP 的处理能力达到了极限,于是首先查看 CPU 的使用情况:CPU 的使用率只有 10% 左右,系统负载也在 1 以下,大多数 php-fpm 进程的状态也是 S。看来问题并不是出在 PHP 的处理能力上。我顺便看了一下内存的使用情况,内存还有很多富余,所以也不会是内存不足引起的性能下降。

排除了 CPU 方面的性能问题,接下来就是带宽了。我们在发布会前购买了 200Mbps 的带宽,以应对可能出现的大量访问。200Mbps 的带宽我觉得应该不至于被跑满,使用 nload 查看网络流量后发现确实如此,200Mbps 的带宽只是用了很少一部分。

CPU 和带宽都没有问题,那么问题就只有可能在数据库上了。我们的数据库和网站是放在不同的服务器上的,既然网站这边的服务器没问题,那就很有可能是数据库服务器那边出问题了。登录到数据库服务器上一看,MySQL 的 CPU 使用率达到了 100%,看来性能应该就是被数据库给拖累了。

另一种可能是,图文直播的 AJAX 刷新请求页面处理存在问题。这个页面要做的事情应该很简单,只需要从数据库中查询到尚未发送给用户的数据,把数据读取出来丢给用户就行了。但这个查询涉及到一个排序操作,我怀疑可能是用于排序的字段没有使用索引。虽然说现在直播的数据量不大,就算没有索引应该也不会造成太大影响,但为了排除这种可能性,我还是打算通过查询计划来确认一下这个页面的处理有没有太大的性能问题。

这时候,我还要负责监控车机的在线状态,已经忙不过来了,于是叫来另一位也是负责网站开发兼 C 开发兼自动驾驶研究兼运维的同学(是的,创业公司人人都是半个“半栈”工程师)也帮忙看看 MySQL 的性能问题出在哪。

很快,MySQL 性能下降的原因就被这位同学找到了。原因出在一个保存在线用户数据的表上,MySQL 的会话列表显示,有大量的请求卡在了对这个在线用户表的查询操作上。

我们有一个表,用于保存在线的用户数据,这个表在设计的时候不知道为什么没有索引,也许是忘了添加了,或是认为没有必要。事实上在网站访客不多的时候,确实没有必要给这个表加上索引,同时在线用户就那几十个,加了索引反而影响增删改速度。

但现在的情况不同了,网站涌入了大量用户,由于表没有添加索引,查询性能急剧下降,一个查询可能需要几秒钟才能出结果,而 PHP 端这边则会等待 MySQL 返回结果后才能继续处理,于是 php-fpm 进程被迅速耗尽,新来的请求得不到执行,表现在网站上,就是网站挂掉了。

问题原因找到后,迅速给这个表加上索引,人肉操作的速度是很迅速的,但由于这个表已经变得很大,MySQL 花了两三分钟时间才把索引给加上。

索引添加成功之后,再查看 MySQL 的进程状态,发现 CPU 使用率已经降下来了,现在只有不到 10% 的使用率。再打开网站看看,网站刷刷刷地就出来了,这时再查看网站服务器的状态,CPU 使用率正常,系统负载正常,带宽尚有富余,问题解决√

我们本来是有机会将网站崩掉这个问题扼杀在萌芽状态的,在网站彻底崩溃之前,就已经有同学发现网站变慢了,但当时我认为是现场复杂的无线环境导致的本地网络质量下降,并未想到可能是服务器那边的问题,于是网站不可避免地崩溃了。

如果你以为这篇文章就到此结束,那你就错了。

我们的汽车是需要联网的,在发布会开始前我们有两种方案,一种是通过 4G 进行联网,另一种是通过 WIFI 进行联网。我们的 4G 设备只支持 4G 网络,而考虑到发布会当天现场人数众多,如果运营商的基站不能承载如此大的通信量而将 4G 服务降级为 3G 甚至是 2G 网络的话,那我们的车子就没法联网了,随之而来的后果就是语音识别、应用商店、微听、导航等需要联网的功能都无法演示。因此,我们决定在发布会时不使用 4G 进行联网,而是使用一个专门的 WIFI 进行联网。这个 WIFI 是隐藏的,仅供汽车连接,WIFI 后面通过一条专线连接到互联网。

事实上我们还打算演示使用手机和手表控制汽车的部分功能,如开关车灯、开关车门、闪灯等。这个功能是这样实现的,用户使用手机(或手表)上的客户端发出指令,指令会传到我们的汽车消息服务期上,汽车消息服务期再将消息转发给汽车,汽车根据收到的消息做出相应的动作。很明显,要实现这个功能,汽车必须联网。如果没有网络的话,这些功能就无法演示了。

来帮我们进行现场网络布置的老师在发布会期间一直在通过 ping 来监控汽车的联网状态。发布会开始时,汽车的联网状态还是好好的。在网站崩溃问题修复之后,状态也依旧是好好的。然而突然间,ping 开始丢包,丢包越来越多,很明显这是无线信号受到了干扰,干扰从何而来我们无从知晓,但最有可能的干扰源就是现场大量的无线设备。

没过多长时间,ping 已经完全收不到回包了,汽车的网络连接看来已经完全断掉了。这时候,汽车消息服务期上也显示车机已经掉线了。这下问题就大了。现场与汽车的交互演示是发布会的一个重要环节,如果没有网络,这些演示都无法进行,发布会将会遭受到 65535 点的致命打击。

随着发布会的继续进行,网络依然没有任何恢复的迹象,车子上盖着的幕布就快要揭下来了,幕布揭下来之后再过一会就要进行交互演示了。

我们也想过重启车上的无线设备(车子在设计上是使用 4G 进行联网的,所以我们临时在车上放了一个 WIFI 设备,这样才能让车子使用无线网络),看看这样能不能让车子重新连接到无线网络上,但是最后还是没有任何办法让车子重新联网。

就在我们一筹莫展的时候,车子的幕布被揭开了,没过多久就要进行交互演示了,而这时候汽车的网络依然没有连通。

神奇的事情发生了,车子的幕布完全揭开之后,汽车的网络竟然突然恢复正常了,ping 收到了回包,并且非常稳定,没有任何丢包,车子连上网络了!

接下来要进行的交互演示可以顺利进行了!

不过还有一个问题,车机并没有上线。我们的车机是有自动重新上线功能的,如果检测到网络断开,那么车机就会重新上线。网络已经恢复了,但车机并没有上线。

没有办法,我们只好跳过使用手机和手表来控制汽车这个演示环节了。其实这个环节对发布会来说很重要,这是发布会上唯一一个能演示与汽车功能相关的环节,与汽车交互的演示更偏向于对 Android 系统的演示,而使用手机来遥控汽车开关灯、开解锁才更偏向于对汽车功能的演示。

虽然很遗憾,但是使用手机控制汽车这个环节只能取消了。

令人郁闷的是,使用手机控制汽车这个环节跳过之后,车机竟然上线了。好吧,至少看来我们的车机断线自动重连功能是没有问题的。

惊魂三十分终于结束了。到发布会结束之后,至少在我负责监控的事情中,没有再出现什么吓人的事情了。

————————-

事后我们分析发布会时汽车网络突然中断的原因可能是这样的,用来遮挡汽车的幕布表面的涂料可能据有一定的导电能力,这就对汽车形成了一个微弱的电磁屏蔽。虽然有一层屏蔽,但屏蔽作用不是很强,汽车上的网络信号勉强可以穿透这道屏蔽,但信号出来以后已经变得很微弱,路由器只能勉强收到信号。

当发布会开始时,使用我们提供的无线网络的人还不是很多,发布会进行一段时间后,随着无线网络使用量的增加,现场的无线网络环境越来越复杂,从汽车上发出来的穿透了屏蔽的微弱的信号开始被现场的无线信号干扰,于是汽车的网络连接质量慢慢下降,最后完全断掉。

当遮挡汽车的幕布揭开之后,汽车上的无线信号没有了电磁屏障的阻碍,信号强度已经不会被现场的其它无线网络信号所覆盖,于是汽车的网络立刻就恢复了。

至于车机为什么过了一会儿之后才上线,原因可能是这样的。我们的车机会在检测到网络变化时立即进行重连。然后,当车子在处于屏蔽状态时,虽然我们已经收不到任何 ping 的回应包,但对 Android 来说,它仅仅是没有收到任何数据包,并没有收到要求断开连接的数据包,也没有收到来自用户层面的断开连接请求,所以 Android 不会认为网络已断开,车机就不会立刻重连。

网络恢复后过了一段时间,车机在定时上报数据时才发现服汽车消息务器端已经断开了连接,于是这时候才进行重连。这就解释了为什么网络恢复之后过了一段时间车机才重新上线。

该文章发表于 乱七八糟。将永久链接保存到书签。

发表评论

电子邮件地址不会被公开。