一次因夏令时引发的线上故障(夏时令开始打一个字)
问题背景
对于金融风控系统,保证数据的准确性是首要条件。底层数据一但错误,将会产生不可估量的损失。然而就在前不久,线上风控系统就因为底层数据加工时出现了错误,导致欺诈用户进入系统发生交易,而这个错误的元凶就是--夏令时。
同一个用户利用不同手机号进入一个系统,试图进行交易,这是金融风控最常见的一种欺诈用户。规则引擎当仁不让的成为了整个风控系统最重要的一道防线,规则执行正确的必要条件是底层数据以及加工逻辑正确。
本次所说的问题就发生在底层数据加工这一环节,对于用户是否是欺诈用户的判断,我们有个规则是当前用户的 姓名+生日 是否被其他人使用过。
问题就出现在了此规则上面,从用户的原始数据来看,姓名和生日都是一样的,却怎么都捕获不到欺诈用户。
问题排查
明确了问题后,接下来就要开始苦逼的定位问题过程。
一开始认为不是什么大问题,分分钟就能搞定。
看一遍逻辑代码,没有发现什么异常。。。
这都是小事,没有什么是debug解决不了的问题,测试环境debug一通搞,还是没有发现异常。。。
看来非得逼我使出绝招,于是本地环境连接了线上数据库进行debug,还是没有发现异常,一切正常,欺诈用户也被捕获到了。
好吧,我开始慌了,沉思了一会儿,意识到问题没有想象中的简单。
看来不得不使出独门秘笈了,出山前师傅曾特别强调过,不到万不得已的时候不要用,否则会让人知道你太牛(low)B。
。。。。线上环境打log日志。
加上日志上线后,调试了一会儿,果然发现了问题,相同日期转出来的时间戳不一样,相差了一个小时。
第一时间想到的线上环境的时区有问题,不是东八区。局势出现转机,矛头指向了运维同事。
立马联系运维同事,说明情况后,运维看了项目所部署的机器时区,确定了服务器时区就是东八区(北京时间)。
好吧,看来还是要靠独门秘笈来解决了,于是又新增了打印系统时区的日志,上线后运行一看日志,打印的时区都是东八区,没有什么区别啊。
线上打印的时区是:GMT+08本地环境打印的时区是:Asia/Shanghai这时候始终认为是时区不同导致的,所以当看到GMT+08和Asia/Shanghai时,没有在意他们之间有什么不同,只是觉得都表示的东八区。就没有多想,更没有想到是夏令时引起的。
又折腾了好一会儿,实在是没辙了,就在团队工作群里面说了这个事儿,有同事就提出不同意见,是不是GMT+08 和 Asia/Shanghai有什么不同导致的?于是就抱着怀疑的态度,上网查了下,果然发现了问题所在。
最终锁定了犯罪嫌疑人为“夏令时”,接下来就是收集证据的阶段了,于是查了很多关于夏令时的资料,果不其然,夏令时的特征与整个问题都十分吻合。可以确定,夏令时就是本次问题的罪魁祸首。
那么夏令时为什么会引发这次故障呢?
咱们言归正传,来聊聊今天的主角--夏令时。
夏令时,表示为了节约能源,人为规定时间的意思。也叫夏时制,夏时令(Daylight Saving Time:DST),又称“日光节约时制”和“夏令时间”,在这一制度实行期间所采用的统一时间称为“夏令时间”。一般在天亮早的夏季人为将时间调快一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。各个采纳夏时制的国家具体规定不同。全世界有近110个国家每年要实行夏令时。--百度百科
我国也实行过短暂的夏令时间制度,时间段为1986年到1991年六个年度,每年从四月中旬第一个星期日的凌晨2时整(北京时间),将时钟拨快一小时,即将表针由2时拨至3时,夏令时开始;到九月中旬第一个星期日的凌晨2时整(北京夏令时),再将时钟拨回一小时,即将表针由2时拨至1时,夏令时结束。1992年起,中国的夏令时暂停实行。
中国实行的夏令时具体时间段为:
1986年5月4日至9月14日(1986年因是实行夏令时的第一年,从5月4日开始到9月14日结束)1987年4月12日至9月13日;1988年4月10日至9月11日;1989年4月16日至9月17日;1990年4月15日至9月16日;1991年4月14日至9月15日。GMT+08 和 Asia/Shanghai区别
GMT-8是东八区,北京时间和东八区一致,GMT(Greenwich Mean Time)代表格林尼治标准时间,不能确定是哪个国家,所以就无法使用每个国家规定的夏令时了。
Asia/Shanghai是以地区命名的地区标准时区,在中国叫CST(China Standard Time)。这个地区标准时会兼容历史各个时间节点。中国1986-1991年实行夏令时,夏天和冬天差1个小时,Asia/Shanghai会兼容这个时间段。
所以,1992年以后,在中国,GMT-8和Asia/Shanghai是一样的时间,1986-1991之间,夏天会有一小时时差。
通过上面的介绍,可以知道,在实行夏令时阶段,时间是比平时快了一个小时。这也就印证了我们上面说的问题,出现问题的时间是1988-07-19,刚好就在中国实行夏令时制度的范围内。
反思
事后对这次故障进行了复盘,总结了三个个人观点:
合理使用数据
通过上面的描述,大家可以看出,本次出现的故障是在拿用户生日转时间戳与数据库中的时间戳做比较时发生的。
其实只要数据使用的合理,这次事故本可以避免。既然是比对用户的生日,为什么不直接用日期格式(yyyymmdd)进行存储/比对,而是把生日转成了时间戳再进行存储/比对,这样来回一折腾,问题就出现了。
数据本身没有实际价值,人们利用数据解决了问题,才产生价值。只有合理应用数据,才能让数据在产生价值的道路上变得畅通无阻。
发挥团队作用
从排查问题的初期,就被自己的主观意识给带偏了,钻进了死胡同,一直认为是不同时区导致。于是联系运维一起排查,就算到后面看到了GMT-8和Asia/Shanghai,也没有多想。导致整个排查过程花了近4个小时才完成,一路走到了黑。如果能早点把问题和团队分享,可能排查的过程就会轻松很多。
当局者迷,旁观者清。当我们在排查一个问题超过半个小时还是没有任何头绪时,应该主动和周边的同事分享,他们会给你提供不同的观点和思路,往往解决问题的方法就在此过程中被发现。
贯微动密
夏令时并不是我第一次接触,不过在一开始接触的时候并没有引起重视,也没有进行深入了解,只是在自己的知识体系中一笔带过。
若在第一次接触到夏令制时间时,就对其进行深入的学习理解,我相信,本次的这个故障很快就会解决。
在平时学习的过程中要做到贯微洞密,切忌浮光掠影、走马观花。穷经必专一经,不可泛鹜。
以上就是关于《一次因夏令时引发的线上故障(夏时令开始打一个字)》的全部内容,本文网址:https://www.7ca.cn/tg/42124.shtml,如对您有帮助可以分享给好友,谢谢。