服务器时差问题引发的问题思考与解决

背景:博主目前所在的公司出现了一个特别严重的情况:多台 Web 服务器之间的时钟不同步。导致数据库的时钟与服务器时钟之间存在时差。刚好我们的活动要根据一个用户签到来送福利。一个用户一天只能签到一次。用户在凌晨前面几秒签到了。但是,Web 服务器却判定为了第二天签到。数据库的时间却在昨天。导致最终福利赠送环境出现了逻辑不对应的情况。

1)时差危害
根据自己所经历分析,时差在很多不涉及到跟钱相关的系统当中影响几乎可以忽略不计。但是,博主所在的公司是一家从事类似于余额宝类型的金融服务公司。国家金融办对金融服务公司在数据上面的要求是非常严格的。每一笔数据都必须知道它的来龙去脉。

像本文背景中说到的。签到活动的服务器由于时钟不同步,服务器的时钟快于当前互联网时钟。于是,在凌晨之前的几秒操作,就被服务器判定为是第二天了。这样,签到成功的数据就是第二天的了。然而,我们的数据部门在做数据核对的时候。发现同一天签到一次,却赠送了两次福利。这显然就违背了数据的合理性。

所以,我们在做与钱相关的项目时。一定要考虑凌晨这个临界值的问题。

2)时差问题解决
既然我们知道了是因为时差问题导致了业务的判定问题。那么就容易解决这个问题了。

2.1)服务器与数据库时钟定时同步
Linux 服务器环境用如下命令可以同步服务器时钟:

$ ntpdate ntp1.aliyun.com

这行命令的意思是以阿里云的时钟为基准更服务器时间更新。因为,我们用的是阿里云的服务器和数据库。所以,这样做是最合理的。

然而,我们不可能每次都手工执行。最好是每天都能同步一次。或每周同步一次。此时,我们可以把这行命令与定时器 Crontab 结合使用。

推荐每天同步一次。避免太久同步导致时钟误差过大,而导致程序数据对应上面出现较大的缺口。

2.2)业务上限制临界值
即使我们的服务器时钟与数据库时钟都同步了。但是,依然避免不了本文中背景所提到的问题。

例如,我们在 23:59:59 秒进行签到。但是,我们的签到程序可能虽然 1 秒(含)以上。那么,程序结束之后,时间就变成了 00:00:00 了。此时就属于第二天了。

我们谁都不能保证程序能在一个合理的时间完成。所以,我们必须在业务当中处理好这种对时间临界值很敏感的需求。

处理方案:
业务在判定的时候,限制每天的 23:59:00 ~ 00:00:59 这个时间段不允许签到这样的业务操作。直接提示:“业务正在例行维护,请于 3 分钟后重试”。

以上就是博主寒冰在实际开发中遇到的时差问题,以及怎样解决这个时差的经验总结。如有不对之处,请指正!

博主 2011 年创建了一个《PHP 初学者官方群》,目前群成员 500 人左右。群号:168159147。为了防止广告,设置为付费入群。欢迎大家加入讨论技术!

标签: 无

精彩评论
  1. 分布式环境下,始终差异始终没法避免。

    1. 你说得很对。我们能做的就是尽量避免或缩小这种差距带来的影响。

发表评论: