当前位置: 首页 > news >正文

服务器时区与数据库时区不一致导致时间bug记录

1、背景

 一个活动,需要按照自然月刷新,每月一期,以活动开始当月作为第一期,每期可配置不同数据。问题出现在:活动开始时间为本月,但是查询用户数据发现当前为第二期,反复查看代码,确定计算期数逻辑无问题,十分诡异。期数计算代码如下:

protected int getPeriod(Date begin, Date now) {// DateUtil为工具类,format方法将时间转化为 yyyy-MM-dd格式String beginTime = DateUtil.format(begin, DateUtil.FORMATTER_YYYYMMDD_STR);String nowTime = DateUtil.format(now, DateUtil.FORMATTER_YYYYMMDD_STR);int beginYear = Integer.valueOf(beginTime.substring(0, 4));int nowYear = Integer.valueOf(nowTime.substring(0, 4));int beginMonth = (beginTime.charAt(5) - '0') * 10 + (beginTime.charAt(6) - '0');int nowMonth = (nowTime.charAt(5) - '0') * 10 + (nowTime.charAt(6) - '0');// 计算期数(可能出现跨年,需要考虑年份)return nowMonth + 12 * (nowYear - beginYear) - beginMonth + 1;}

2、排查

 服务为分布式架构,有多个节点,发现只有少数节点会产生异常数据(本次活动只配置了一期,计算结果为第二期时会因拿不到配置数据而空指针,根据报错日志判断)。查看配置数据,发现活动开始时间为本月1日00点00分00秒,因此数个小时的时差即会导致月份出现偏差,猜测服务器时区问题,date -R检查服务器时区,正常节点与异常节点时区一致,暂时不考虑时区问题。
 配置数据会加载进内存,当修改配置数据时,会修改有改动表的版本号,定时任务根据表版本号去刷新配置。考虑是配置人员中途改过数据,定时任务出现问题导致配置没有更新。观察日志,发现刷新配置的时间异常,时区与机器时区不一致。
 date -R 结果(+0900 东九区):

Wed, 12 Jun 2024 22:59:25 +0900

 服务器日志时间:

2024-06-12T01:17:22.506+0000

3、结论

 出现错误的原因为:进程时区与数据库时区没有保持一致,导致进程内时间与实际要配置的时间出现偏差,最终导致计算出错。

4、总结

 (1)临界点时间(跨天、跨月、跨年)极易受时区影响导致极大误差,出现时间问题时可第一时间查看时区问题
 (2)机器时区与进程时区并不总是一致,需要摆脱这个惯性思维,用其他方式(如日志)确定进程时区。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Flutter-使用MethodChannel 实现与iOS交互
  • Three.js做了一个网页版的我的世界
  • C++方法封装成dll及C#调用示例
  • Spring Boot + Mybatis Plus实现登录注册
  • UbuntuServer 22.04.4安装GitLab
  • 生成式人工智能 - 本地windows 11 + PyCharm运行stable diffusion流程简述
  • C++类与对象(拷贝与类的内存管理)
  • Ubuntu 22.04 下 CURL 分块上传文件(C++)
  • AIRNet模型使用与代码分析(All-In-One Image Restoration Network)
  • 【小白学Python】自定义图片的生成(二)
  • 用Python绘制yolo训练结果比较图-论文需要
  • 鸿蒙轻内核A核源码分析系列六 MMU协处理器(1)
  • 【稳定检索/投稿优惠】2024年智慧金融与财务管理国际会议(SFFM 2024)
  • C#操作MySQL从入门到精通(21)——删除数据
  • C# 设置PDF表单不可编辑、或提取PDF表单数据
  • [译]如何构建服务器端web组件,为何要构建?
  • ComponentOne 2017 V2版本正式发布
  • k8s如何管理Pod
  • Laravel核心解读--Facades
  • maya建模与骨骼动画快速实现人工鱼
  • Median of Two Sorted Arrays
  • Mybatis初体验
  • React Native移动开发实战-3-实现页面间的数据传递
  • scala基础语法(二)
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • sessionStorage和localStorage
  • Vue 重置组件到初始状态
  • webpack4 一点通
  • 彻底搞懂浏览器Event-loop
  • 代理模式
  • 利用DataURL技术在网页上显示图片
  • 前端攻城师
  • 移动端唤起键盘时取消position:fixed定位
  • 云大使推广中的常见热门问题
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • 正则表达式-基础知识Review
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #前后端分离# 头条发布系统
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (译)计算距离、方位和更多经纬度之间的点
  • (转载)hibernate缓存
  • *p++,*(p++),*++p,(*p)++区别?
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .NET Core 和 .NET Framework 中的 MEF2
  • .net 反编译_.net反编译的相关问题
  • .NET 中 GetProcess 相关方法的性能
  • .NET6 开发一个检查某些状态持续多长时间的类
  • .NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
  • @staticmethod和@classmethod的作用与区别
  • [ Python ]使用Charles对Python程序发出的Get与Post请求抓包-解决Python程序报错问题