其他
系统设计中 跨时区问题 解决方案
一、背景
二、几个重要概念
时区
格林尼治时间
中国时区
UTC
GMT
UNIX时间戳
三、操作系统、数据库时区设置
3.1 Linux 中设置时区
# 获取当前时间
$ date
Fri Apr 26 15:22:16 CST 2024
# 以特定格式输出当前时间,格式字符串前以"+"开头,例如获得当前时间的epoch
$ date +%s
1714117833
# 设置当前时间
$ sudo date -s "2024-04-25 00:00:00"
Thu Apr 25 00:00:00 CST 2024
tzselect
调整时区#设置时区
tzselect
3.2 MySQL 中设置时区
-- 看下当前的mysql时区设置
show variables like "%time_zone%";
set global time_zone = '+8:00';
set time_zone = '+8:00';
[mysqld]
default-time_zone = '+8:00'
systemctl stop mysqld.service
systemctl start mysqld.service
四、系统跨时区设计
4.1 服务端中的时间处理
客户端传来的时间为客户端所在时区的当地时间,服务端接收到客户端发送的时间后,需要基于客户端相应时区转换成UTC时间才能保存到数据库。
4.2 前端中的时间
如果有需要处理跨时区的业务场景需,可以让用户选择时区,并在任何时候都将处理后的时区信息放到时间字符串中。
4.3 其它注意事项
使用环境变量配置时区信息,使用应用服务器来裁决时区(没有特别业务说明的情况下),因此确保服务器配置的时区相同。 如果是跨国交易或者数据同步的时候,根据客户端连接到的服务器来决定操作用户所属的时区。 依赖应用服务器的时区信息做时区裁决,不要依赖数据库的时区设置,数据库透明存放数据即可。 时区配置来源有操作系统、环境变量、数据库时区、Java 启动参数,建议统一使用 Java 启动参数,避免配置出错,数据库不要做时区自动转换,避免使用 TIMESTAMP 类型。 在高并发的场景中获取系统时间可能有性能问题,原因是 JVM 需要访问进入系统内核态执行指令,当高并发且不需要高精度时间时可以增加缓存,但需要权衡处理。 有时候在处理业务时,需要考虑自然月问题,需要特别注意。 关于时间同步问题中,还有一个墙上时钟和单调时钟的问题。墙上时钟是指根据日历获取时间,会受到时间校对回拨的问题,而单调时钟是指系统启动后的秒数,它不会回拨。在使用 NTP 服务时,可以配置为 NTPD 模式,通过调慢时间频率避免回拨。
五、补充知识:夏令时、冬令时
本文参考资料:
https://en.wikipedia.org/wiki/Time_zone https://zh.wikipedia.org/wiki/ISO_8601 https://www.rfc-editor.org/rfc/rfc3339 https://datatracker.ietf.org/doc/html/rfc5545 https://en.wikipedia.org/wiki/System_time https://www.iplocate.com/ https://en.wikipedia.org/wiki/Timestamp
·END·
相关阅读:
有没有那么一瞬间,你也曾有过“失业焦虑”? 浅析分布式系统中的补偿机制设计问题 聊聊分布式日志系统的设计与实践 执行个 DEL 竟然也会阻塞 Redis?深挖一下果然不简单 一文带你看通透,MySQL事务ACID四大特性实现原理
专注架构技术研究,一起跨越职业瓶颈!
关注公众号,免费领学习资料
如果您觉得还不错,欢迎关注和转发~