CentOS7迁移到TencentOS3.3 引发程序报错“Clock moved backwards. Refusing to generate id“

一、 背景
某个客户为满足信创条件,特将CentOS 7.X的版本迁移到TencentOS 3.3 的操作系统上。

采用的数据库是TDSQL 3.3 集中式版本。

TencentOS 2.4-3.3 系列主要是为了解决CentOS 7.9 后版本停服而引发的安全、升级等相关问题而衍生出的满足信创的操作系统,在腾讯历经数十年的打磨。

二、 问题的产生与排查

  1. “Clock moved backwards. Refusing to generate id” 该问题由系统时间变慢导致。
  2. 默认配置了腾讯时钟服务器同步,采用chrony的工具进行的同步。
  3. chrony 启动中。
  4. 应用程序兼容chrony。手动强制同步时间后,应用程序正常。

上面四点已经很明显,就是出在系统时间变慢上。
三、系统POC 测试验证
在这里插入图片描述
在这里插入图片描述
说明:按照上面的两幅图可以看出,chrony 是正在运行的状态,但是Leap status : Not synchronised 处于未同步状态。

# 查看已同步的客户端
chronyc clients
# 立即同步时间
chronyc makestep  
# 检查偏移量(Offset接近0)
chronyc tracking    
# 查看源状态(^*^表示当前同步源)
chronyc sources -v   

解决方案:
第一:通过调整参数
cat /etc/chrony.conf
server x.x.x.x iburst minpoll 5 maxpoll 5
参数解释:
minpoll:最小获取时间同步为2 的5次方,也就是32秒
maxpoll:最大获取时间同步为2 的5次方,也就是32秒

重启chrony.cnf 服务
systemctl restart chronyd

第二:配置crontab 任务

          • chronyc makestep
          • sleep 30; chronyc makestep

第三:配置本地chrony 时钟服务器,解决网络问题
服务端

vi /etc/chrony.conf
# 添加本地时钟源(无外网时作为时间源)
server 127.127.1.0 iburst
# 允许客户端网段访问
allow X.X.X.0/24
# 启用本地时钟层级(仅服务器端配置)
local stratum 10
logchange 0.5
Rtcsync
logdir /var/log/chrony
driftfile /var/lib/chrony/drift
makestep 1.0 3
#注释掉,无法使用chronyc clients 
#Noclientlog
#启动服务
systemctl restart chronyd

客户端

vi /etc/chrony.conf
# 指向时间服务器IP
server X.X.X.X iburst

#启动服务
systemctl restart chronyd
# 立即同步时间
chronyc makestep  

public synchronized String nextId() { long timestamp = timeGen(); //获取当前毫秒数 //如果服务器时间有问题(时钟后退) 报错。 if (timestamp < lastTimestamp) { throw new RuntimeException(String.format( "Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); } //如果上次生成时间和当前时间相同,在同一毫秒内 if (lastTimestamp == timestamp) { //sequence自增,因为sequence只有12bit,所以和sequenceMask相一下,去掉高位 sequence = (sequence + 1) & sequenceMask; //判断是否溢出,也就是每毫秒内超过4095,当为4096时,sequenceMask相,sequence就等于0 if (sequence == 0) { timestamp = tilNextMillis(lastTimestamp); //自旋等待到下一毫秒 } } else { sequence = 0L; //如果和上次生成时间不同,重置sequence,就是下一毫秒开始,sequence计数重新从0开始累加 } lastTimestamp = timestamp; long suffix = (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence; String datePrefix = DateFormatUtils.format(timestamp, "yyyyMMddHHMMssSSS"); return datePrefix + suffix; } protected long tilNextMillis(long lastTimestamp) { long timestamp = timeGen(); while (timestamp <= lastTimestamp) { timestamp = timeGen(); } return timestamp; } protected long timeGen() { return System.currentTimeMillis(); } private byte getLastIP(){ byte lastip = 0; try{ InetAddress ip = InetAddress.getLocalHost(); byte[] ipByte = ip.getAddress(); lastip = ipByte[ipByte.length - 1]; } catch (UnknownHostException e) { e.printStackTrace(); } return lastip; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值