【曹工杂谈】Mysql客户端上,时间为啥和本地差了整整13个小时,就离谱
来源:SegmentFault
时间:2023-01-25 13:30:01 161浏览 收藏
本篇文章给大家分享《【曹工杂谈】Mysql客户端上,时间为啥和本地差了整整13个小时,就离谱》,覆盖了数据库的常见基础知识,其实一个语言的全部知识点一篇文章是不可能说完的,但希望通过这些问题,让读者对自己的掌握程度有一定的认识(B 数),从而弥补自己的不足,更好的掌握它。
瞎扯一点非技术
本来今天上午就打算写的,结果中途被别的事吸引了注意力,公司和某保险公司合作推了一个医疗保险,让我们给父母买,然后我研究了半天条款;又想起来之前买的支付宝那个好医保,也买了两年多了,但是条款也不怎么懂,查了下,感觉坑不少,都做好了理赔时撕逼的打算了。
研究了公司的保险后,还是决定把支付宝那个玩意给退了。尤其是健康告知那一句:最近两年内有住院行为的,就算是不满足健康告知。
我还打电话问了我爸妈,他们也不记得几年前到底住没住过院了,反正我个人感觉心里没底。下午找支付宝,客服都半天找不到。
大家也可以多注意下。
背景
我负责的一个后台服务,负责接收客户端请求,同时写库。比如,创建一个任务,在代码里创建时间是直接new Date,然后写入数据库。然后,我用我的客户端软件去看那个创建时间的时候,是差了13个小时的。
当然了,客户端软件看着差了13个小时,但是我web界面上查看,是没啥问题的。
比如,我现在时间是21:02分,我在界面上创建了一个任务,然后我用的mysql客户端sqlyog去查看任务的创建时间:
Ftask_id Fcreate_time -------- --------------------- 4121 2021-06-19 08:02:36
咦,怎么是8点呢,和现在比,差了21 - 8 = 13个小时。
这个时区问题,一般还是和mysql的一些variable相关的,比如,我们这么查了一下,
SHOW VARIABLES LIKE '%zone%'
结果如下:
Variable_name Value ---------------- -------- system_time_zone CST time_zone SYSTEM
这个cst、system,虽然不懂,但感觉就是有点问题,这时候去某度某歌查一下,基本改改就解决了。
但是,这个mysql实例上,不止我们一个数据库,上面有几十个库,我这也不敢直接改数据库配置,万一有人专门这么配置的呢?
然后我问了下同事,他在这个实例上也有一个其他的数据库,但是比较奇怪的是,他在程序里new Date,写进来的时间,是对的。
大家都是一个组的,都是同样的mybatis框架,不至于你可以,我不可以。
我决定,找找原因。
当然了,这么明显的bug,之前没发现?那倒不是,我web界面上查出来,是对的。
虽然只是有点恶心人(mysql客户端看到的时间差了13小时,web前端没问题),但还是不能继续忍了。
mysql server错 or sqlyog客户端错
sqlyog在本机,mysql server在远端,我们可以wireshark抓包,看看mysql返回的,是不是对的
wireshark上,选择正确的网卡,捕获表达式设为:tcp port 3306,然后开抓,然后跑去sqlyog上执行select语句。
SELECT Ftask_id,Fcreate_time FROM t_task ORDER BY Fcreate_time DESC LIMIT 1;
然后,回到我们的wireshark,抓到了很多包:
然后随便找一个右键-跟踪流-tcp流,就会把对应的这个tcp连接上的包全部以ascii显示出来,正常来说,一般mysql的报文,都是明文的,可以直接看到sql语句,和返回的结果啥的,但是,我本机这个sqlyog,不知道是不是版本很高的原因,少量语句可以明文显示,其他的就不是明文。
不过吧,咱们暂时没时间和这个客户端耗着,我直接去应用所在的服务端上抓包吧,看看mysql server返回的,是什么样的。
上图那个tcpdump语句,就是抓3306端口的包,不管3306是src端口,还是dst端口。然后相关的包,写入到3306.pcap里面,然后我们sz传到windows上,用wireshark来分析。
大家注意看上图,mysql返回的就有问题,先把锅甩给mysql。
但是,mysql只是个存储,既然存的数据有问题,那是不是说明,可能我们写的有问题呢?
mysql server:谁写了个错误的时间给我,来领锅
很尴尬啊,这个时间,是我们的服务端写进去的,这样的话,我们只能继续像上图那样抓包了:
只是这次,我们要抓现行,抓写入的包,当然了,我这里为了讲解,已经提前抓了这个任务的。
看吧,果然写入有问题,说明程序有问题,我们顺便看看mybatis logger记录的sql日志。
但是,mybatis 日志里,记录的时间是对的,就是晚上9点。
ok,我们理一下,我们程序里new date,mybatis写入,记录的日志是晚上9点,没问题;但是,最终发给mysql server的包,是晚13小时的。
说明啥,可能mysql 建立的连接有点问题,我这时候去看了下本地代码的配置文件。
commondb: database: url: jdbc:mysql://xxxxxx:3306/xxxx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useTimezone=true&serverTimezone=GMT%2B8
大家看这个配置,
commondb: database: url: jdbc:mysql://xxxxxx:3306/xxxx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull
本来就没有带后面那个时区的东西。
我很怀疑,现在线上那个运行的java程序,到底commondb.database.url有没有问题,我想了好几个办法:
1、 因为是spring boot的,所以一开始用http://xx.xx.xx.xx:8080/actua...之类的端口,去查看了一下,发现访问不通。后来发现,咱们的程序,没引入spring boot的actuator的jar包,作罢。
2、本地使用jconsole、jvisualvm去连接这个运行着的java程序。
这个怎么玩呢,首先,这个运行着的程序,需要是开了这几个jvm参数:
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
然后,就可以去连接它了,用jconsole/jvisualvm都行。
具体可以参考我以前的一个博文:https://www.cnblogs.com/grey-...
当然,这个比较随机,有时可以连上,有时不行,我这次就不行,我还在本机wireshark抓了jconsole去连接这个远程java程序的包。
抓包的过滤语句:tcp port 9999。
抓到的包,是以tcp协议展示的,其实我们知道应用层的通信协议的话,可以手动右键--decode as--然后选择rmi,
没错,java自带的那个rmi,就可以看到多一些信息。
当然了,虽然多了些信息,我还是没明白为啥jconsole没连上。放弃。
jconsole不行,最终我还是只能试试arthas了,阿里的那个,连上去那个java程序后,只能看看环境变量、System Property之类的,好像对我们要看的东西,于事无补。
还记得吗,我们想看的是,commondb.database.url的值,思考了一会,最终只能暴力解决了,这个属性,好像被注入到一个bean里去了,他就是Datasource,但是想看到这个bean的值,没那么简单:
@Bean(name = DATA_SOURCE) @ConfigurationProperties(prefix = DB_CONFIG_PREFIX) @Primary public DataSource omsDbDatabase() { DataSource build = DataSourceBuilder.create().build(); return build; }
所以,最终只能jmap,把堆内存dump下来了,然后使用eclipse memoryAnalyzer来分析。
oql,大家不了解的,可以了解下,反正就是根据class来搜索内存中的对象。
配置没问题,那,问题在哪里
我这时候才想起来,既然服务器上这个java程序,配置没问题,也会出这个时区问题。那我本地,是不是也会有这个问题(按理说,我早该这么想,但是就是后知后觉),然后本地试了下,和服务器上表现一样,这时候,其实就可以慢慢debug了。
但是,暂时也没深入去debug,我只是,排除了众多因素之后,我还是很奇怪,同事那个程序,为啥发送给mysql server的时间没问题,我这个就有问题,我于是,对比了一下双方的mysql-connector-java这个依赖,发现,咦,版本不一样啊。
mysql https://blog.csdn.net/valsong...具体的根本原因,我还没仔细看,为啥两个客户端版本有这个差异,不过,大概的排查过程,就是这样了。
2021-07-19更新
如果不修改pom.xml中的mysql版本的话,可以通过如下方式解决,也可以保证写到数据库的时间是正确的。
commondb: database: url: jdbc:mysql://xxxxxx:3306/xxxxx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai username: root password: root1234 maxActive: 10 maxIdle: 5 minIdle: 1 initialSize: 1 test-while-idle: true driver-class-name: com.mysql.jdbc.Driver今天关于《【曹工杂谈】Mysql客户端上,时间为啥和本地差了整整13个小时,就离谱》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于mysql的内容请关注golang学习网公众号!
-
499 收藏
-
244 收藏
-
235 收藏
-
157 收藏
-
101 收藏
-
471 收藏
-
222 收藏
-
199 收藏
-
466 收藏
-
211 收藏
-
377 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习
-
- 英勇的唇膏
- 写的不错,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,看完之后很有帮助,总算是懂了,感谢作者分享技术文章!
- 2023-04-17 00:47:36
-
- 疯狂的乌龟
- 这篇技术文章真及时,细节满满,感谢大佬分享,码起来,关注楼主了!希望楼主能多写数据库相关的文章。
- 2023-03-10 17:01:23
-
- 傻傻的睫毛
- 太给力了,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢up主分享文章!
- 2023-02-14 20:44:19
-
- 洁净的小伙
- 好细啊,收藏了,感谢大佬的这篇文章,我会继续支持!
- 2023-02-07 05:55:41
-
- 怕孤单的鸭子
- 这篇文章真及时,太全面了,真优秀,mark,关注老哥了!希望老哥能多写数据库相关的文章。
- 2023-02-05 08:00:01
-
- 迷路的彩虹
- 这篇技术贴真是及时雨啊,师傅加油!
- 2023-02-04 19:21:42
-
- 眯眯眼的荷花
- 太详细了,已收藏,感谢up主的这篇技术文章,我会继续支持!
- 2023-02-04 15:07:18
-
- 细心的自行车
- 这篇博文真是及时雨啊,太详细了,感谢大佬分享,mark,关注作者大大了!希望作者大大能多写数据库相关的文章。
- 2023-02-03 01:12:53
-
- 欢喜的八宝粥
- 这篇技术贴真及时,师傅加油!
- 2023-01-31 21:43:03
-
- 欢呼的台灯
- 很有用,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢作者大大分享技术贴!
- 2023-01-28 18:46:40