近来,小林接到一则京都快报:杨桑在上周给甲方爸爸的邮件体系晋级新程序,程序上线后发现运用客户端无法收取新邮件,急忙对程序进行回退,新功用上线也就此泡汤凉凉了。
上线翻车?!为什么会呈现这么严峻的现场事端?!测验为什么没有发现这个BUG?!开发为什么写出这个BUG?!
小林猎奇、很猎奇、超级无敌猎奇,瞬间翻身坐起‍♂️,双手合十,驱咒结印,“以我凡魂,迎请神探一致,洞天火明,寻万物本宗,破!”
电光火石间,四海八方的信息源源不断地涌入小林的识海,需求评价、计划规划、编码、测验、上线一桩桩过往瞬间记忆犹新,遽然一道黑影闪过混入其间,原来如此!
小林瞋目一睁,挥毫泼墨画六合,洋洋洒洒写下几个大字——多端交互,时区差异是大坑,吹墨化形为一道浑厚的掌力,直击那黑影肝脑涂地,就地烟消云散。
随后小林长袖一甩,拂袖而去,独留一个洒脱的背影在漫天光辉中。
至此,小林捉BUG的奇遇之旅就告一段落。
“什么?这就完了?故事还没讲就完毕了?你耍我呢?退钱!”
“诶诶诶,这位客官别急别急,这不是还有我嘛”
“你是哪位大爷?!”
“江湖人称百晓生,无人不知,无人不晓,各抒己见,言无不尽,这就向您娓娓道来哈”

【一、现场翻车】

杨桑‍是一位闯荡技能江湖多年、经历老练独特的售前参谋,服务尊贵的甲方爸爸提供售前技能支持。
话说5月1日杨桑接到来自京都的研制快讯,奉告:依甲方爸爸的需求开发程序,代码已合并完成、程序包已出,可择日换包上线!
二话不说,杨桑转头向甲方爸爸请示上线的详细时刻。甲方爸爸闻后,双目慢慢一闭,掐指一算,拟定一个黄道吉日:5月5号。好叻!杨桑收到指令,动身为五日后的上线开端做准备。
测验环境现在情况如何?一切正常。出产环境现在情况如何?一切正常。
测验环境更换程序后情况如何?现在工作正常。好!待5号准备上出产环境!
5月5号晚上十点,正是夜黑风高好办事的时节。杨桑目不斜视地盯着大屏幕,双手不间断地敲着指令,整个现场环境安静地只能听见时钟的滴答声和杨桑的呼吸声。
遽然杨桑敲代码的声响骤但是至,他垂头望向键盘,食指慢慢伸向ENTER键,轻轻屏气,随后双目一闭、ENTER键一按,大屏幕上瞬间涌出很多字符,程序指令不断往上翻滚,快得让人眼花缭乱。
终于,程序中止运转,只见屏幕末行显现着SUCCESS❗杨桑狂喜,离成功只差一步之遥了。
杨桑急忙进行简单测验,运用web端进行收发信,没有问题!退出重启,没有问题!运用客户端进行收发信,没有问题!退出重启,好像有点问题?咦?怎样收不到新邮件通知呢?出大问题了!
完了完了,翻车了翻车了,这但是出产环境啊,急忙回退急忙回退!
杨桑立马将之前备份的旧程序找出来换上,再进行WEB端和客户端的收发信测验,还好没问题。
但是刚才的上线事端吓得甲方爸爸差点当众掀桌子争吵走人,杨桑立马安慰甲方爸爸激动的心情,再拟诀千里传音一封,速速通知总部招集研制大佬协助问题排查。

【二、问题根因】

此刻的明酱正卧床呼呼大睡,睡得可香甜啦。遽然她感觉自己被一股强大的力量拽出梦乡,再定眼一看,自己已身处京都总部的问题排查大殿,老大A哥正坐C位!
哎呀妈呀,出啥大事啦?!
A哥单手一挥,向明酱传了一道指令:今天杨桑上线突发事端,未能自行解决,吾命汝速速前往援助。
收到,保证完成使命!‍明酱掐指拟了个瞬移术,化为一道青烟就地消散。
此刻杨桑合理束手无策,看见明酱前来援助瞬间喜极而泣,热心的拥抱将明酱扑了个四脚朝天。明酱连连将杨桑推开,连带赠送一个力道浑厚的上勾拳。
算了算了,解决问题要紧。明酱急忙让杨桑在测验环境复原一遍现场情况,果不其然,测验环境一更新程序,客户端一重启,问题百分百重现。
不应该呀?!程序包仅仅将甲方爸爸的定制代码同产品最新版别的代码进行合并,由原先的A03体系晋级为A05体系而已,区区一个版别晋级,怎样就出事端了呢?
莫非问题呈现在版别晋级上?客户端的版别不支持?看看日志怎样说!明酱灵机一动,双手立马啪嗒啪嗒地打开客户端的日志进行排查,杨桑在旁瞪大双眼一脸膜拜。
客户端重启后收不到新邮件,问题很可能呈现在WEB端与客户端收发信功用的交互上。在WEB端发送邮件,登录客户端进行收取,此刻客户端从WEB端拉取邮件会调用LIST_MESSAGR 接口,向MODIFED_TIME_ZONE字段传参。而MODIFED_TIME_ZONE字段参数值的判别依赖于GBL_OPT接口回来的version值。当version=1,MODIFED_TIME_ZONE字段指定运用的是本地时刻;version≥2,则指定运用标准时刻。
明酱定神考虑顷刻,十指再接再励地敲打指令,果不其然,日志过滤下关键字GBL_OPT一探究竟,本相已然本相大白。
只见那大屏幕上日志赫然显现:FUNCTION=GBL_OPT,RESULT_VAR={version=1,web:{login:0}}。明酱大吃一惊,version=1说明什么?!说明了问题的根因⭕:客户端传给MODIFED_TIME_ZONE字段指定的本地时刻,但程序由原先的A03版别升至A05,晋级后WEB端运用的是标准时刻功用,即WEB端与客户端二者时刻不匹配,导致客户端无法从WEB端拉取邮件。
再详细一点说明,程序版别晋级后,因为WEB端运用的是标准时刻(UTC),0点在WEB端发送邮件,通过GBL_OPT接口奉告客户端version=1。此刻登录客户端进行收取邮件,理应两头会进行信息同步,正常情况下客户端会立马收取到该邮件。
但是客户端从WEB端得到信息是version=1,所以从WEB端拉取邮件时调用LIST_MESSAGR 接口传递给MODIFED_TIME_ZONE字段指定的是本地时刻(本地时刻=UTC+时区差,时区差东为正,西为负)。假设客户端此刻的本地时刻为北京时刻,北京时刻是东八区,抢先UTC标准时刻8个小时,即客户端奉告WEB端要拉去早上8点的邮件,但此刻WEB端处于0点。
0点在WEB端发送的邮件被客户端误以为早上8点的邮件,两头时刻不匹配,导致WEB端以为客户端想要的是未来时刻的邮件,因而WEB端奉告客户端没有它要拉取的邮件,自但是然地此刻登录客户端会呈现收取不到邮件的问题。
功用上线就是与时刻赛跑,已然本相已然大白,自然是要再接再励地修正BUG‍♀️!究竟身处服务行业,时刻就是金钱,此刻亡羊补牢,期望为时不晚。明酱叹了口气,双手结印,催动识海,气聚天灵,口中念念有词:”术法六合,万物皆神灵,相邀六合大移动,聚!✊”
只见大屏幕上无形中呈现一个漩涡,汹涌地粉碎着数以万计行代码。弹指一挥间,崭新的程序包已然生成。目光暗示,明酱用手肘戳了一把在旁早已目瞪口呆的杨桑:”该你上了!”
“好叻,大佬!”杨桑立马回过神来,驾轻就熟地敲着指令。不一会功夫,程序更新完毕,再看看WEB端和客户端的交互情况,几十种应用场景轮番测验个遍,都无意外产生。
终于搞定啦!明酱和杨桑相视一笑,放心地回京都复命啦~

【三、测验遗失】

京都大殿上,A哥单手用双指不停地揉着太阳穴,听着明酱和杨桑你一言我一语地复述着工作的通过,头疼得好像添了凉水的热油锅,快要炸了!
耐着极度想要发火的心情,A哥冷声问道:“为何上线前测验环节没有发现,比及上线后才暴雷?”这一灵魂发问,场子瞬间被泼了盆冷水,搞得明酱和杨桑面面相觑,安静到了极点。
过了良久,明酱用蚊子般的声响弱弱地囔了句:”这可能要问下测验大护法T君才知道了。”A哥怒目而视,锋利的目光吓得明酱忍不住往后退了半步。
说时迟那时快,T君的身影飘然显现在大殿中央。问好礼毕,T君长袖一挥,一应俱全镜⬜呈现在世人眼前,镜中正放映的画面一一解释了工作的来龙去脉。
早在上一年腊月之际,彼时京都正集结各方研制能者之大成,铸造一方神器。其间有一新功用,便是WEB端的LIST_MESSAGR 接口支持对客户端传递的时刻进行时区转化,工单编号FUNC-37777,完成产品版别A05。
因为客户端本身具有将本地时刻转化为标准时刻的功用,假如客户端向WEB端的LIST_MESSAGR接口的MODIFED_TIME_ZONE字段传递的是本地时刻转化后的标准时刻,那WEB端的LIST_MESSAGR接口对MODIFED_TIME_ZONE字段的参数进行时区转化,导致二次过滤,即使WEB端和客户端在同一时区,程序也会判别失误❌。
因而,程序做出如下设定:当GBL_OPT接口存在时,客户端向LIST_MESSAGR接口的MODIFED_TIME_ZONE字段传递的是本地时刻,WEB端对其进行时区转化,运用标准时刻存储邮件;当接口不存在时,即使传的是本地时刻,WEB端不对其进行时区转化,运用本地时刻存储邮件。
乍一看好像没啥缺点,其实背面有一个深不见底的大坑正默默恭候着。早先不知何年何月,客户端程序有一个设定:当GBL_OPT接口回来的version值为1时,客户端运用本地时刻获取邮件;当回来值大于等于2时,客户端运用标准时刻获取邮件。
而这恰恰是矛盾和冲突地点!WEB端只需GBL_OPT接口存在,便以标准时刻存储邮件;而客户端需GBL_OPT接口存在且version值为2时,客户端才会运用标准时刻获取邮件!
甲方爸爸的程序包将体系从A03晋级到A05,正是包含了FUNC-37777的功用,导致呈现在WEB端发送的邮件以标准时刻存储,从客户端运用本地时刻获取失利的惨痛局面。
那测验大佬布下天罗地网进行防卫,为何单单让这个BUG溜之大吉了呢?T君轻捻双指,向一应俱全镜注入灵力,镜中画面不断被放大,BUG藏匿之处终于被揭露在世人眼前,引得现场惊呼声不断。
究竟是怎样一回事呢?只见其一测验场景是如此规划的:以存在用户U01、U02且U02已登录客户端为条件,假定U01地点的时区为UTC+0600、U02为UTC+0800,U01登录WEB端发信给U02,U02在客户端点击收信,测验结果为可实时收信且时刻显现正确。这和事端现场不符啊⁉到底问题出在哪里呢?
测验场景和事端现场有何差异呢?差异在于前者是U02已登录客户端,而后者是重启客户端后才露出问题。
细究客户端的技能完成逻辑,客户端只有在发动初期向WEB端获取版别信息,因而测验场景以U02已登录客户端为条件,即使WEB端已更新版别,但因为客户端没重启退出,客户端仍是会按照缓存的旧版别信息去向WEB端拉去邮件,即客户端以为不存在GBL_OPT接口,按照常逻辑向WEB端申请拉去以本地时刻存储的邮件。
而事端现场将客户端重启,重启后客户端得知WEB端存在GBL_OPT接口,但因为回来值version=1,所以客户端传递本地时刻,但却按照新逻辑向WEB端申请拉去以标准时刻存储的邮件,导致了后续问题。
遗失一个小小的重启操作,竟然埋下了后续程序上线翻车事端的导火索,可这谁能想得到呢?!
A哥看完一应俱全镜中的画面,心里五味杂陈,醒悟不能在同个当地跌倒两次,痛定思痛,紧迫会聚灵力千里修书一封,让小林复盘整个事情的始末,总结经历吸取这血淋淋的教训!

【四、复盘总结】

“小林小林,脑筋有点小机灵~小林小林,超级爱吃冰淇淋~~“此刻的小林正躺在吊床上,啃着冰淇淋不亦乐乎。遽然小林周身气味纵横交错,喘息之间平地起风卷,将小林带至面壁思过崖上。
好在刚刚用灵力死死护住手里的冰淇淋,这才没被风卷跑!小林暗自感概,连连舔了好几口冰淇淋压压惊。眼前慢慢展示A哥传来的京都快报,小林定神一瞧,细心一品,原来是杨桑给甲方爸爸上线现场翻车啦!
瞬间激起小林那从前害死乒乓猫吃尽哑巴亏的猎奇心,二话不说小林立马打开明察秋毫术,将功用从开发到上线的整个过程探个一清二楚,让那溜之大吉的漏网之鱼立马原形毕露,随后一道思过掌将其就地粉碎。
竟然让小林判下思过掌进行惩办,这漏网之鱼究竟犯下多大差错啊?!来看看小林怎样说~
以面壁思过崖做图纸,以灵力为翰墨,小林聚六合之灵,屏气凝思地落笔:

  • 九一年二月,工单编号FUNC-36000,体系WEB端支持按客户端的本地事情按TIME_ZONE进行时区转化,完成产品版别A03;
  • 九二年孟秋,工单编号FUNC-38999,体系WEB端新增GBL_OPT接口回来值产品版别号version,完成产品版别A05;
  • 九二年仲秋,工单编号FUNC-39111,体系客户端支持通过GBL_OPT接口获取关于WEB端功用的信息,完成产品版别Z03;
  • 九二年仲冬,工单编号FUNC-37777,体系WEB端的LIST_MESSAGR 接口支持对客户端传递的时刻进行时区转化,完成产品版别A05;
  • 九三年仲夏,售前参谋杨桑将甲方爸爸的体系从A03晋级到A05,现场翻车,呈现重启后Z03客户端收不到信的重大事端;同日,京都问题排查组敏捷派出研制大神明酱前往协助,究其祸源为:WEB端和客户端断定邮件的发送时区不匹配所造成的,随后程序调整为:体系客户端通过判别体系版别决定传入MODIFED_TIME_ZONE的参数,产品BUG修正工单编号FUNC-55555,完成产品版别Z05;
  • 细察工单编号FUNC-37777,测验天兵忒斯托1号于九二年仲冬,因疏忽重启操作导致漏网之鱼繁殖且破网而逃;但次年孟春,另一测验天兵忒斯托2号无意间发现此漏网之鱼,奉告研制大佬漆黑荣耀需进行排查,追其根因呈现在WEB端和客户端交互信息不一,因不知何种原因,问题跟进终止于排查未进行修正,导致仲夏时期此漏网之鱼在甲方爸爸的出产环境肆意横行,变成弥天大祸。
  • 九三年仲夏月圆之夜,复盘使者(爱吃冰淇淋的)小林将漏网之鱼抓获,钉于思己柱上,判其三大罪:
  • ❌罪其一:WEB端和客户端接口交互信息确定不一致,研制计划需一致对齐;
  • ❌罪其二:测验场景未考虑其他时区差异,如GMT、UTC、DST等,且遗失重启客户端更新程序版别信息操作;
  • ❌罪其三:测验发现问题奉告研制排查,问题跟进中止,未及时向上反馈、推进后续修正。
  • 此漏网之鱼罪孽深重,危祸出产环境,影响信息来往,惩办思过掌将其就地伏法。
  • 虽事已了,但前车之鉴后事之师;今复盘工作来龙去脉,剖析根因总结经历,望引以为戒,防微杜渐!

一挥而就,一气呵成,眨眼之间小林将事情的前世此生道了个明明白白。笔锋一收,面壁思过崖散发出刺眼的光辉,再看时只见崖壁上刻满了字,正是小林刚刚所书所写。
使命完成!小林左手刚传了个回讯给A哥,右手立马从六合袋里掏出个大大的冰淇淋,称心如意地舔了舔,背对着这漫天的余辉洒脱地走了!

【终】

”怎样怎样?听的还过瘾吧~“百晓生一脸满意地向听众卖弄着笑脸。
”果真不错,这话本值我投这六个666币!还有吗?爷爷我有的是钱,再来!再来!“
”客官别急哈~新的话本正在派人快马加鞭送来中,欢迎点赞保藏重视一键三连哟!这里是江湖百晓生的八卦茶话馆,重视我八卦路上不迷路哦”❣

01 多端交互,时区差异是大坑