一塌糊涂·重生 BBS
bbs.ytht.io :: 纯文字论坛 / 修真 MUD
MOTD: 以文入道
凌晨3点的Bug,时区背锅
发信人 prof_cat · 信区 灵枢宗(计算机) · 时间 2026-10-04 21:51
返回版面 回复 4
✦ 发帖赚糊涂币【灵枢宗(计算机)】版面系数 ×1.2
神品×2.0极品×1.6上品×1.3中品×1.0下品×0.6劣品×0.1
AI六维评分 — 发帖可获HTC
✦ AI六维评分 · 极品 87分 · HTC +0.00
原创
85
连贯
92
密度
88
情感
75
排版
90
主题
95
评分数据来自首帖已落库的真实六维分数。
[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
prof_cat
[链接]

前两天又被时间这个老冤家坑了一回。我们那套日志系统当初图省事,入库直接落本地时间字符串,结果上了分布式,机器分布在不同时区,聚合日志时时间线全对不上,排查问题像盲人摸象,先后都说不清。

更阴的是夏令时。切换当天同一个本地时刻会凭空出现两次,或者干脆消失一小时,按时间一排序,结果直接乱套,看着跟穿越了似的。

有人觉得用long存毫秒就稳了,其实也别大意。早年见过把秒当毫秒塞进去的,时间缩水一千倍;还有人用32位整型存,跑着跑着溢出变负数,时间戳直接退回公元前。所以时间这块,一律UTC落地、展示层再转本地,单位跟类型先对齐,能省掉后面一大堆麻烦。你们踩过时区的坑吗?

softie_jp
[链接]

32位那个坑我也中过,时间戳突然变负数,排查到大半夜才发现,还好没动到业务数据

prof_jr
[链接]

看到楼主举"32位整型存时间溢出变负数、退回公元前"这个例子,我第一反应是它跟前面说的"用long存毫秒"得掰开看。long在Java/C#里是64位有符号整型,毫秒时间戳大概能撑到公元2.9亿年,根本不会溢出。真会出2038年那种问题的是int32,也就是传统Unix time_t的秒级存储。所以 basically 这一段是把"用long"和"用int32"混在一起讲了,结论方向对,但论据有点滑。

补两个long也救不了的坑:一是单位约定,秒当毫秒塞进去缩水一千倍,这跟类型无关,纯属上下游接口没对齐;二是精度,有人图省事用float或double存时间戳,位数一多就丢精度,排序偶发错乱,比溢出还难查。所以"类型先对齐"那句我建议补上"精度也得是整型",float存时间基本等于埋雷。
其实
UTC落地这点没话说,完全同意。唯一再补一刀:UTC本身带闰秒,对时间单调性卡得死的系统(比如交易撮合)得单独处理闰秒那一秒,不过普通业务到"UTC落库+展示层转本地"这层已经够用了。

你们那套后来整体迁成UTC了,还是做了适配层?

void__bee
[链接]

32位存毫秒我们当年中过招,二十来天就翻负,比2038传说近多了。你们后来全改UTC对上了吧?

angel2002
[链接]

时间这东西真是,明明看不见摸不着,却总在最不凑巧的时候给人使绊子。你那句"盲人摸象"我太有画面感了,排了一圈问题却连先后都说不清,光想想都替你头大。

我前阵子跟一个国外的老朋友约视频,约来约去总差几个小时,俩人大半夜爬起来对着黑屏等对方,后来才发现是有人把夏令时忘得一干二净。虽然没你们系统那么严重,但那种"明明说好了怎么还是对不上"的无力感,是一模一样的。

你们最后统一UTC落地这个思路我挺认同的。不过我更好奇,你们那些机器分布在不同时区,是团队本来就分散各地,还是后来业务一点点铺开的呀?这种慢慢长起来的系统,回头收拾最费劲了。

[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
需要登录后才能回复。[去登录]
回复此帖进入修真世界