诡异至极的SQL Server推送数据到MQ日期早48小时的生产问题排查

2023-11-20

背景

  1. 应用迁移,即旧版应用下线,新版应用上线,停掉旧版应用里面的quartz任务,开启新版的xxl-job调度任务。
  2. 数据推送源头是SQL Server,目的地是MQ。

问题爆出

今天iview的自动导出任务从老系统迁移到新系统,下午2点40~近5点。导出到MQ的消息内容与预期不符,造成这段时间数据缺失。
具体来说,本来今天要导出update_time 是2022-03-02的数据,但是切新系统之后,导出的数据,update_time 是2022-02-28。
4点40之后,把导出MQ任务切换到老系统。下游任务恢复正常。

消息查询平台截图如下,从2022-03-02 14:52:00到2022-03-02 16:52:35,造成生产事故的数据有65104条。另外搜索条件支持指定业务Id,即1000004004,指的是新的应用appId。
在这里插入图片描述
还没有考虑另外一个消息发送节点:
在这里插入图片描述
随便取一条数据,看其中的两个日期字段:
在这里插入图片描述
使用时间戳在线转换,日期确实有问题:
在这里插入图片描述
完整的消息体,JSON格式化之后的数据如下:

{
  "t_dial": 34,
  "lastevent_type": "EventReleased",
  "dn": "32350",
  "cnt_hold": 0,
  "employeeid_from": "32350",
  "id": 549270452,
  "dnis": "6017365591305",
  "create_time": 1646037503096,
  "t_handle": 20,
  "is_acw": 0,
  "ud_6": "",
  "ud_7": "",
  "ud_4": "3c4bcfbc92887c2e4484bff77c633e82",
  "dial_time": 1646037451176,
  "ud_5": "",
  "is_queued": 0,
  "ud_2": "75571446",
  "ud_3": "3",
  "ud_1": "124716316",
  "lastevent_time": 1646037505487,
  "transferconnid": "",
  "ed_5": "",
  "ed_4": "0",
  "ed_3": "",
  "deleted_time": 1646037505487,
  "ed_2": "",
  "ud_8": "",
  "ed_1": "",
  "ud_9": "",
  "answer_time": 1646037485842,
  "abandon_type": "100",
  "maincalluuid": "0014MEHGOS8O19GAPC1O22LAES23RIEQ",
  "t_acw": 0,
  "release_action": "",
  "ud_19": "",
  "ud_18": "",
  "ud_17": "",
  "ud_16": "",
  "ud_15": "",
  "ud_14": "",
  "employeeid": "",
  "cnt_mute": 0,
  "ud_13": "",
  "ud_12": "",
  "ud_11": "",
  "ud_10": "",
  "update_time": 1646037503096,
  "t_conf": 0,
  "calluuid": "0014MEHGOS8O19GAPC1O22LAES23RIEQ",
  "ani": "32350",
  "call_type": 3,
  "release_time": 1646037505487,
  "cnt_conf": 0,
  "call_state": 0,
  "ud_20": "",
  "t_queued": 0,
  "is_handle": 30,
  "release_code": "2 Remote",
  "t_hold": 0,
  "connid": "00790327a1802ee1",
  "t_ring": 0,
  "transfer_type": "",
  "arrived_time": 1646037451176,
  "cnt_transfer": 0,
  "is_diverted": 0
}

可以发现几个时间都是1646037开头。
从数据源头Sql Server获取数据的查询SQL语句如下:

select 
id,
maincalluuid,
calluuid,
connid,
transferconnid,
employeeid_from,
employeeid,
dn,
ani,
dnis,
arrived_time,
queued_time,
diverted_time,
ring_time,
dial_time,
answer_time,
release_time,
deleted_time,
acw_time,
hold_time,
conf_time,
cnt_hold,
cnt_conf,
cnt_transfer,
cnt_mute,
t_queued,
t_ring,
t_dial,
t_handle,
t_acw,
t_hold,
t_conf,
call_type,
call_state,
is_queued,
is_diverted,
is_handle,
is_acw,
transfer_type,
abandon_type,
release_code,
release_action,
lastevent_time,
lastevent_type,
create_time,
update_time,
ud_1,
ud_2,
ud_3,
ud_4,
ud_5,
ud_6,
ud_7,
ud_8,
ud_9,
ud_10,
ud_11,
ud_12,
ud_13,
ud_14,
ud_15,
ud_16,
ud_17,
ud_18,
ud_19,
ud_20,
ed_1,
ed_2,
ed_3,
ed_4,
ed_5
from sip_record
where update_time >= CONVERT(varchar(10),DATEADD(MINUTE,-10,GETDATE()),120)+' '+
                cast(DATEPART(HOUR,DATEADD(MINUTE,-10,GETDATE())) as varchar(10))+':'+
                right('0'+cast((DATEPART(MINUTE,DATEADD(MINUTE,-10,GETDATE()))/10)*10 as varchar(10)),2)+':00'
and update_time < CONVERT(varchar(10),GETDATE(),120)+' '+cast(DATEPART(HOUR,GETDATE()) as varchar(10)) + ':'+ right('0'+cast(DATEPART(MINUTE,GETDATE())- DATEPART(MINUTE,GETDATE())%10 as varchar(10)),2)+':00'

将此SQL拿到DataGrip执行,没有任何问题:
在这里插入图片描述
查询出来的时间就是系统当前时间往前15分钟左右。

至于上面的时间跨度,第二天继续排查此问题。。

排查

这是什么鬼问题???

没了主见,无头苍蝇。

甚至莫名其妙,修改系统的时间,然后执行此SQL,结果还是正常的时间。

能不能在本地调试程序?

本地使用原有的测试Sql Server数据源,推送数据到MQ,问题没有复现。

发现本地居然可以连接这个生产环境的Sql Server数据源,开搞。
在这里插入图片描述
在连接SQL Server,获取到的数据就不正常。为啥DataGrip连接数据源获取数据是OK的??一开始没有往这方面想,折腾很久

MQ消息体看到的是时间戳,可以理解为一个大整数?调试代码修改如下,结果报错:
在这里插入图片描述
datetime2,这是什么数据类型?以这个关键词和48小时在Google搜索。

好家伙,网络搜到如下类似问题:
how-is-sql-servers-timestamp2-supposed-to-work-in-jdbc

The datetime2 is always 2 days (48 hours) before the expected time.

The test is the same for both datetime and datetime2, but the datetime2 test fails with a date that is 2 days prior.

但是这里面没有给出可行的解决方案。除了建议使用jTDS驱动

这是BUG??

没有找到sqljdbc4的官方GitHub仓库?

然后发现microsoft不再维护sqljdbc4驱动,而是在维护新的驱动版本:

<<dependency>
    <groupId>com.microsoft.sqlserver</groupId>
    <artifactId>mssql-jdbc</artifactId>
    <version>10.2.0.jre8</version>
</dependency>

去sqljdbc4的升级版驱动GitHub仓库,即mssql-jdbc里面搜issue。

也提到类似的问题

但是我使用此驱动时,报错信息:

java.lang.Exception: com.microsoft.sqlserver.jdbc.SQLServerException: 驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target”。 ClientConnectionId:e914fd2b-51f2-4939-bda2-9ffdb8b03207

参考文档,将之前可以连接成功的URL:jdbc:sqlserver://10.121.31.116:2433;databaseName=gene_cdr;改成jdbc:sqlserver://10.121.31.116:2433;databaseName=gene_cdr;integratedSecurity=true;encrypt=true;trustServerCertificate=true,结果报错:
java.lang.Exception: com.microsoft.sqlserver.jdbc.SQLServerException: 没有为集成身份验证配置驱动程序

而且假使真的使用这个驱动,还有乱七八糟的版本适配矩阵以及可能带来的各种问题

此时才再考虑使用jTDS。DataGrip使用的驱动是jTDS:在这里插入图片描述

<dependency>
    <groupId>net.sourceforge.jtds</groupId>
    <artifactId>jtds</artifactId>
    <version>1.3.1</version>
</dependency>

而程序目前使用的驱动是:

<dependency>
    <groupId>com.microsoft.sqlserver</groupId>
    <artifactId>sqljdbc4</artifactId>
    <version>4.0</version>
</dependency>

修改驱动。还是不行??

实际上是可以的:
在这里插入图片描述
如上图,需要注意的点:

  1. 修改连接SQL Server数据源的URL地址,因为sqljdbc4驱动和jTDS连接同一个数据源,URL不一样;
  2. 修改驱动的完整包路径,sqljdbc4是com.microsoft.sqlserver.jdbc.SQLServerDriver,jTDS是net.sourceforge.jtds.jdbc.Driver

断点调试发现,此时可以获取到正取的时间。

在这里插入图片描述

在这里插入图片描述

日期格式数据调整;
https://www.cnblogs.com/alsf/p/6148927.html

在这里插入图片描述

灵魂拷问

旧版工程和新版工程代码有何区别?
旧版代码不贴出来,写得一坨屎。
贴一张断点调试截图:
在这里插入图片描述
可以发现时间也是提前48小时。
MQ消息查询平台,发送IP,172.20.10.46是我的本机IP,业务ID是旧版应用工程的appId。调试时忘记select top 1 *,一下子发送几千条数据。可见测试环境,时间也是不对的。
在这里插入图片描述
旧版应用生产环境,没有问题,要不然早炸锅。消息查询平台截图如下,确实没有问题:
在这里插入图片描述

在这里插入图片描述

该数据源版本信息:
select @@version
执行结果:

Microsoft SQL Server 2012 (SP1) - 11.0.3000.0 (X64)
Oct 19 2012 13:38:57
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.2 <X64> (Build 9200: ) (Hypervisor)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

诡异至极的SQL Server推送数据到MQ日期早48小时的生产问题排查 的相关文章

  • 为什么 Hashtable 不允许空键或空值?

    正如 JDK 文档中所指定的 Hashtable 不允许空键或空值 HashMap 允许一个空键和任意数量的空值 为什么是这样 Hashtable 是较旧的类 通常不鼓励使用它 也许他们看到了对 null 键的需要 更重要的是 null 值
  • 使用itext java库复制时pdf文件大小大大增加

    我正在尝试使用 Java 中的 itextpdf 库将现有的 pdf 文件复制到一些新文件中 我使用的是 itextpdf 5 5 10 版本 我在两种方式上都面临着不同的问题 PDFStamper 和 PdfCopy 当我使用 PDFSt
  • 来自行号的方法名称

    给定特定类源代码 Java C 的行号 是否有一种简单的方法来获取它所属的方法的名称 如果它落入其中 大概使用抽象语法树 这对于将 checkstyle 的输出限制为仅触及的方法很有用 我假设您必须使用抽象语法树来执行 Line gt Me
  • IBM Websphere MQ - 用于 Tomcat 部署的 EJB 和 MDB 迁移

    我已经为此苦苦挣扎了很长一段时间 我有一个 IBM Websphere MQ 它使用 EJB 和 MDB 以下是配置ejb mdb的地方
  • 在java代码中创建postgresql表

    我有一个与 postgreSQL 数据库连接的 java 代码 现在 我希望当它连接到数据库时 我还将创建数据库表 但我的问题是 它不会创建数据库 我不知道问题是什么 这是我的代码 Statement st null ResultSet r
  • 如何将webview内容划分为多个页面

    我必须使用 Android 上的 PdfDocument 从 webView 创建 PDF https developer android com reference android graphics pdf PdfDocument htm
  • Java 错误和警告列表

    在哪里 如何获得所有 java 和 javac 的错误和警告消息的列表 This http mindprod com jgloss compileerrormessages html我认为页面是您所需要的
  • java中高效的输入流到字符串方法

    因此 我在 Java 中的 诚然非常简单 应用程序上运行探查器 令我惊讶的是 仅次于需要在时间上发出 HTTP 请求的方法的是我的方法 inputStreamToString方法 目前它的定义如下 public static String
  • Android 信号 11 (SIGSEGV),代码 1 (SEGV_MAPERR) libwebviewchromium.so

    对于 android 4 4 我多次收到 Native crash at system lib libwebviewchromium so 错误 以下是设备包括 Xperia Z1 SO 01F 16 30 2 Galaxy Tab4 7
  • 使用正则表达式验证电子邮件的最大长度

    我找到了用于电子邮件验证的正则表达式 a z0 9 a z0 9 a z0 9 a z0 9 a z 2 4 我希望电子邮件的最大长度为 20 个字符 因此我将其更改为 a z0 9 a z0 9 a z0 9 a z0 9 a z 2 4
  • 扩展多个类

    我知道 Java 不支持多重继承 因为不允许扩展多个类 我只是想知道我的问题是否有解决方法 我有一个名为CustomAction需要扩展两个抽象类 BaseAction and QuoteBaseAction 我无法更改这些抽象类中的任何一
  • 如何获取 JDBC 中 UPDATE 查询影响的所有行?

    我有一项任务需要使用更新记录PreparedStatement 一旦记录被更新 我们知道更新查询返回计数 即受影响的行数 但是 我想要的不是计数 而是受更新查询影响的行作为响应 或者至少是受影响的行的 id 值列表 这是我的更新查询 UPD
  • 始终将双精度舍入

    我怎么总是能把一个double to an int 并且永远不要将其四舍五入 我知道Math round double 但我希望它始终向上舍入 所以如果是的话3 2 四舍五入为 4 您可以使用Math ceil method 请参阅Java
  • BigDecimal汇总统计

    我有一个 BigDecimal 列表 List
  • Java 8:如何创建毫秒、微秒或纳秒的 DateTimeFormatter?

    我需要创建格式化程序来解析具有可选的毫秒 微米或纳秒分数的时间戳 例如 对于我的需求 我看到以下机会 DateTimeFormatter formatter new DateTimeFormatterBuilder append DateT
  • 如何更改 JAX-WS Web 服务的地址位置

    我们目前已经公开了具有以下 URL 的 JAX RPC Web 服务 http xx xx xx xx myservice MYGatewaySoapHttpPort wsdl http xx xx xx xx myservice MYGa
  • 如何在不使用 -cp 开关的情况下在 Groovy 中自动加载数据库 jar?

    我想简化调用 Oracle 数据库的 Groovy 脚本的执行 如何将 ojdbc jar 添加到默认类路径以便我可以运行 groovy RunScript groovy 代替 groovy cp ojdbc5 jar RunScript
  • 用于生成 ISO 文件的 Maven 插件

    有没有可以生成ISO镜像的maven插件 我需要获取一些模块的输出 主要是包含 jar 的 zip 文件 并将它们组合成一个 ISO 映像 Thanks 现在有一个 ISO9660 maven 插件可以完成这项工作 https github
  • 假布尔值=真?

    我在一本书中找到了这段代码 并在 Netbeans 中执行了它 boolean b false if b true System out println true else System out println false 我只是不明白为什
  • FetchType.LAZY 不适用于休眠中的 @ManyToOne 映射

    简而言之 我的 Child 类与 Parent 类之间存在多对一的关系 我想加载所有的孩子 而不必加载他们的父母详细信息 我的孩子班级是 Entity public class Child implements Serializable I

随机推荐

  • 6.SSH框架整合及简单使用示例

    6 SSH框架整合 ssh spring spring mvc hibernate 6 1 整合的场所 web xml 跟 5 ssm框架 整合类似 可以对照学习 通过监听器配置hibernate 通过servlet配置mvc web xm
  • 设计模式之观察者模式(Observer)摘录

    23种GOF设计模式一般分为三大类 创建型模式 结构型模式 行为模式 创建型模式抽象了实例化过程 它们帮助一个系统独立于如何创建 组合和表示它的那些对象 一个类创建型模式使用继承改变被实例化的类 而一个对象创建型模式将实例化委托给另一个对象
  • 2021蓝桥杯模拟赛-跳跃

    题目 题目链接 题解 动态规划 算是比较基础的状态方程和状态定义 但是难点在于处理负权重的情况 代码 include
  • 通过微信小程序实现登录功能

    后端服务器可以在CSDN上开通 价格优惠 CSDN开发云 https img home csdnimg cn images 20220518054835 png https dev csdn net activity utm source
  • Java多线程(7):并发_线程同步_队列与锁(Synchronized)

    一 并发举例 线程不安全 1 两个人同时操作一张银行卡 如何保证线程安全 2 多个人同时购买一张火车票 谁能买到 二 并发特点 1 同一个对象 2 被多个线程操作 3 同时操作 三 如何保证线程安全 线程同步 队列 锁 1 使用队列的技术一
  • 走路步数怎么在屏幕上显示_华为走步步数不在屏幕上显示如何设置

    展开全部 1 打开手机的设置选项 找到 安全和隐私一栏 点击进入 2 进入后下拉屏幕 32313133353236313431303231363533e4b893e5b19e31333365666262找到并且选择 锁屏和密码 3 进入后在
  • idapython常用api记录7.0

    2019 02 13 idapython常用api记录 以下代码片段可以在ida的output窗口中测试用 需要引入相关的模块即可 import idaapi import idc import idautils 后续需要使用的程序代码指令
  • VUE 出现Access to XMLHttpRequest at 'http://192.168.88.228/login/Login?phone=19939306484&password=111'...

    报错如上图 解决办法首先打开 config gt index js 粘贴 如下图代码 https www baidu com 换成要访问的的api域名 注意只要域名就够了 不是整个api地址 代码 效果图 如下 更改完以后 还需要我们把sr
  • JDK1.8中HashMap的底层实现原理

    1 创建HashMap对象 public HashMap new一个hashmap 加载因子为默认的0 75f this loadFactor DEFAULT LOAD FACTOR all other fields defaulted 2
  • React中非受控组件-ref与受控组件理解

    内容 受控组件是通过 React 组件的状态来控制表单元素的值 非受控组件是通过手动操作 DOM 的方式来控制 此时 需要用到一个新的概念 ref ref 用来在 React 中获取 DOM 元素 非受控组件 ref ref的使用格式 步骤
  • list,tensor,numpy相互转化

    使用Pytorch的过程中 经常涉及到变量需要在list numpy和tensor之间自由转化 1 1 list 转 numpy ndarray np array list 1 2 numpy 转 list list ndarray tol
  • python3.7安装tkinter模块_Mac安装tkinter模块问题解决方法

    class Python lt Formula desc Interpreted interactive object oriented programming language homepage https www python org
  • ABAP--新语法--Open SQL--第四天-- From Table

    From Table Internal Table 在 ABAP 7 52 后 支持将内表作为数据源使用 内表作为数据源使用时 需要定义别名并使用转义符 该用法可以用来代替 FOR ALL ENTRIES IN 但FROM 语句中最多使用一
  • java脚本引擎Groovy实战

    前言 互联网时代随着业务的飞速发展 不仅产品迭代 更新的速度越来越快 个性化需求也是越来越多 如何快速的满足各种业务的个性化需求是我们要重点思考的问题 我们开发的系统如何才能做到热部署 不重启服务就能适应各种规则变化呢 实现业务和规则的解耦
  • APP环信集成 -JAVA后端

    环信的集成有两种方式 一种是先创建IM账号 然后在创建客服账号 在客服账号中新建渠道中 点击关联IM账号 这样创造出的关联以IM为主 收费要收取客服和IM两项费用 官方论坛里有给出这种方式的JAVA demo这里不过的赘述 这种场景适用于类
  • object.definepProperty使用方法,vue2双向绑定原理

    首先要介绍的是definepProperty的三个参数 object definepProperty 对象名 属性名 属性值 再者要介绍的就是属性值了 object definepProperty person age value 18 此
  • 【微服务架构设计】微服务不是魔术:处理超时

    微服务很重要 它们可以为我们的架构和团队带来一些相当大的胜利 但微服务也有很多成本 随着微服务 无服务器和其他分布式系统架构在行业中变得更加普遍 我们将它们的问题和解决它们的策略内化是至关重要的 在本文中 我们将研究网络边界可能引入的许多棘
  • std::chrono::steady_clock 实现精准休眠

    include
  • 【PAT】B1032 挖掘机技术哪家强 (20 分)_C语言实现

    1 挖掘机技术哪家强 20 分 为了用事实说明挖掘机技术到底哪家强 P A T PAT PAT 组织了一场挖掘机技能大赛 现请你根据比赛结果统计出技术最强的那个学校 输入格式 输入在第 1
  • 诡异至极的SQL Server推送数据到MQ日期早48小时的生产问题排查

    背景 应用迁移 即旧版应用下线 新版应用上线 停掉旧版应用里面的quartz任务 开启新版的xxl job调度任务 数据推送源头是SQL Server 目的地是MQ 问题爆出 今天iview的自动导出任务从老系统迁移到新系统 下午2点40