瞎扯一点非技术

本来今天上午就打算写的,结果中途被别的事吸引了注意力,公司和某保险公司合作推了一个医疗保险,让我们给父母买,然后我研究了半天条款;又想起来之前买的支付宝那个好医保,也买了两年多了,但是条款也不怎么懂,查了下,感觉坑不少,都做好了理赔时撕逼的打算了。

研究了公司的保险后,还是决定把支付宝那个玩意给退了。尤其是健康告知那一句:最近两年内有住院行为的,就算是不满足健康告知。

我还打电话问了我爸妈,他们也不记得几年前到底住没住过院了,反正我个人感觉心里没底。下午找支付宝,客服都半天找不到。

大家也可以多注意下。

背景

我负责的一个后台服务,负责接收客户端请求,同时写库。比如,创建一个任务,在代码里创建时间是直接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

大家看这个配置,useTimezone=true&serverTimezone=GMT%2B8,一看就有点不对,什么时区,什么GMT。

我本来以为就这个问题了,但是,我们这边,程序和配置是分开打包、分开部署的,大家可以理解为:配置中心。

我去看了下线上配置,结果好像没问题,即:

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/actuator/env之类的端口,去查看了一下,发现访问不通。后来发现,咱们的程序,没引入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-wolf/p/9235073.html

当然,这个比较随机,有时可以连上,有时不行,我这次就不行,我还在本机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这个依赖,发现,咦,版本不一样啊。

        <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>

同事用的是5.1.41,我这边怎么这么高,8.0。于是,我试着改成了5.1.41,这把,果然发给mysql server的时间,就是对的了。

网上的解释

找到了大概的答案,我开始悠闲地去网上搜索答案,肯定有很多人升了版本后出这个问题啊,哈哈。我去看答案就行。

比如这里就一个,mysql-connector-java升级到8.0后保存时间到数据库出现了时差

https://blog.csdn.net/valsong/article/details/102582582

具体的根本原因,我还没仔细看,为啥两个客户端版本有这个差异,不过,大概的排查过程,就是这样了。

【曹工杂谈】Mysql客户端上,时间为啥和本地差了整整13个小时,就离谱的更多相关文章

  1. 【曹工杂谈】Mysql-Connector-Java时区问题的一点理解--写入数据库的时间总是晚13小时问题

    背景 去年写了一篇"[曹工杂谈]Mysql客户端上,时间为啥和本地差了整整13个小时,就离谱",结果最近还真就用上了. 不是我用上,是组内一位同事,他也是这样:有个服务往数据库in ...

  2. 【曹工杂谈】Maven源码调试工程搭建

    Maven源码调试工程搭建 思路 我们前面的文章<[曹工杂谈]Maven和Tomcat能有啥联系呢,都穿打补丁的衣服吗>分析了Maven大体的执行阶段,主要包括三个阶段: 启动类阶段,负责 ...

  3. 曹工杂谈--使用mybatis的同学,进来看看怎么在日志打印完整sql吧,在数据库可执行那种

    前言 今天新年第一天,给大家拜个年,祝大家新的一年里,技术突突突,头发长长长! 咱们搞技术的,比较直接,那就开始吧.我给大家看看我demo工程的效果(代码下边会给大家的): 技术栈是mybatis/m ...

  4. [PHP]利用XAMPP搭建本地服务器, 然后利用iOS客户端上传数据到本地服务器中(三. PHP端代码实现)

    一.安装XAMPP   http://www.cnblogs.com/lidongxu/p/5256330.html 二. 配置MySql http://www.cnblogs.com/lidongx ...

  5. Mysql学习笔记—时间计算、年份差、月份差、天数差(转载)

    1.获取当前日期 SELECT NOW(),CURDATE(),CURTIME(); 结果类似: 2. 获取前一天 DAY); 当前日期2018-09-17,结果: 3. 获取后一天 DAY); 当前 ...

  6. 曹工杂谈:花了两天时间,写了一个netty实现的http客户端,支持同步转异步和连接池(1)--核心逻辑讲解

    背景 先说下写这个的目的,其实是好奇,dubbo是怎么实现同步转异步的,然后了解到,其依赖了请求中携带的请求id来完成这个连接复用:然后我又发现,redisson这个redis客户端,底层也是用的ne ...

  7. 曹工杂谈:Linux服务器上,Spring Boot 原地修改 jar 包配置文件/替换class文件,免去重复上传的麻烦

    一.前言 相信很多同学有这样的需求,现在很多公司都有多地的研发中心,经常需要跨地区部署,比如,博主人在成都,但是服务器是北京的.一般城市间网络都不怎么好,上传一个几十兆的jar包那是真的慢,别说现在微 ...

  8. 曹工杂谈:Java 类加载还会死锁?这是什么情况?

    一.前言 今天事不是很多,正好在Java交流群里,看到一个比较有意思的问题,于是花了点时间研究了一下,这里做个简单的分享. 先贴一份测试代码,大家可以先猜测一下,执行结果会是怎样的: import j ...

  9. 曹工杂谈--只用一个命令,centos系统里装了啥软件,啥时候装的,全都清清楚楚

    前言 一直以来,对linux的掌握就是半桶水的状态,经常yum装个东西,结果依赖一堆东西:然后再用源码装个东西,只知道make.make install,背后干了啥也不清楚了,卸载也不方便. 这几天工 ...

随机推荐

  1. layui图片上传

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <title>up ...

  2. JavaScript中DOM与BOM的区别

    1.BOM BOM全称为Brower Object Model,中文翻译为浏览器对象模型,提供了独立于内容而与浏览器窗口进行交互的对象.描述了与浏览器进行交互的方法和接口.通过BOM可以用来获取或设置 ...

  3. 玩转直播系列之RTMP协议和源码解析(2)

    一.背景 实时消息传输协议(Real-Time Messaging Protocol)是目前直播的主要协议,是Adobe公司为Flash播放器和服务器之间提供音视频数据传输服务而设计的应用层私有协议. ...

  4. 有趣的css—简单的下雨效果2.0版

    简单的下雨效果2.0版 前言 笔者上一篇发布的文章有趣的css-简单的下雨效果中有位老哥给我提了一个很棒的建议,大致意思是波纹应该产生于雨滴的消失处. 这是按照老哥的建议完善后的效果图: 由于我制作G ...

  5. 【Matlab】BFSK的调制与解调仿真

    写在前面 本篇是[Matlab]BASK的调制与解调仿真的下篇,考虑到阅读体验,故另开一篇分享将BFSK的调制与解调仿真. 索引 写在前面 一.BFSK的调制 1.1 异频载波生成 1.2 信号合并 ...

  6. Python正则表达式的七个使用范例

    本文由 伯乐在线 - 左手的灵魂 翻译.未经许可,禁止转载!英文出处:thegeekstuff.欢迎加入翻译组.http://blog.jobbole.com/74844/ 作为一个概念而言,正则表达 ...

  7. Java·Maven的安装与配置

    阅文时长 | 0.58分钟 字数统计 | 937.6字符 主要内容 | 1.引言&背景 2.Maven的下载与安装 3.Maven全局配置 4.Settings.xml文件的配置 5.远程仓库 ...

  8. [笔记] 《c++ primer》显示器程序 Chapter7

    补充Sales_data没有体现出的其他类特性 Screen.h 1 #include <string> 2 #include <iostream> 3 4 class Scr ...

  9. linux自动化交互脚本expect详解set timeout 5是 意思是在expect语句中,5s后超时,不再作出选择。

    linux自动化交互脚本expect详解  更新时间:2020年10月21日 10:13:20   作者:lendsomething     这篇文章主要介绍了linux自动化交互脚本expect的相 ...

  10. gcc 版本

    $ gcc --versiongcc (Ubuntu 5.4.0-6kord1~16.04.4k2) 5.4.0 20160609Copyright (C) 2015 Free Software Fo ...