作者:京东批发 董方酉
引言
利用衰弱度是反馈利用衰弱水平的指标,它将零碎指标分类为根底资源、容器、利用、报警配置、链路这几项,收集了一系列零碎利用的指标,并对指标进行打分。
利用衰弱度的每一项指标显示着零碎在某一方面可能存在的隐患和平安问题;因而进步利用衰弱度对于系统监控具备重要意义。知其然需知其所以然,理解利用衰弱度中的指标背地的隐患,对于咱们理解和晋升零碎安全性很有帮忙。
笔者作为后端研发工程师,同时在推动组内利用衰弱度提高的同时,基于遇到的问题景象,联合利用衰弱度进行分析,将逐个总结一系列利用衰弱度隐患分析;
第一篇,咱们来分析下容易被人漠视的数据库时区设置项可能导致的隐患。
一、利用衰弱度查看项
数据库连接池配置中,通过解析源代码获取,反对 DBCP1.X,DBCP2.X,Ali Durid,HikariCP 四种连接池;配置监测有以下几项
危险示例如下图所示:
connectTimeout、SocketTimeout 和 时区 三个指标是连接池数据源的 url 中解析失去, 如:mysql://xxx.jd.com:3358/jdddddb_0?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&connectTimeout=1000&socketTimeout=3000&serverTimezone=Asia/Shanghai
其中,时区设置容易被人漠视;疏忽设置会带来什么样的隐患呢?
二、遇到的问题
1、景象
在 2023 年 3 月 12 日(3 月的第二个周日),零碎 UMP 监控报警,提醒如下
2、问题起因
Mysql 驱动:mysql-connector-java 降级到 8 版本后。将数据库工夫解析到 java 工夫,须要获取数据库的时区。如果数据库连贯中指定时区,则会用该时区,否则可能会应用零碎时区
可通过 select @@time\_zone 语句查问,如果返回 SYSTEM,则阐明数据库没有设置时区,应用 select @@system\_time_zone 语句可查问得出零碎默认时区,为 CST。
CST 时区为美国中部工夫,因为美国有夏令时和非夏令时
CST 非夏令时对应 UTC-06:00,夏令时对应 UTC-05:00。
美国的夏令时,从每年 3 月第 2 个星期天凌晨开始,到每年 11 月第 1 个星期天凌晨完结。
以 2023 年为例:
夏令时开始工夫调整前:2023 年 03 月 12 日星期日 02:00:00,工夫向前拨一小时.
调整后:2023 年 03 月 12 日星期日 03:00:00
夏令时完结工夫调整前:2023 年 11 月 05 日星期日 02:00:00,工夫往回拨一小时.
调整后:2023 年 11 月 05 日星期日 01:00:00
这象征这:CST 没有 2023-03-12 02:00:00~2023-03-12 03:00:00 这个区间的工夫。会有两个 2023-11-05 01:00:00~2023-11-05 02:00:00 区间的工夫。
因而,在获取信息时会抛出“SQLException: HOUR\_OF\_DAY: 2 -> 3”异样。
3、批改计划
数据库连贯地址中设置数据时区:serverTimezone=Asia/Shanghai
三、工夫相干的其余隐患
1、据钻研试验反馈,设置时区为默认时可能有性能问题,往往须要指定时区。
2、应用 timestamp 类型时需注意工夫偏差:
timestamp 类型的工夫范畴 between ‘1970-01-01 00:00:01’ and ‘2038-01-19 03:14:07’,超出这个范畴则值记录为 ’0000-00-00 00:00:00’,该类型的一个重要特点就是保留的工夫与时区密切相关,UTC(Universal Time Coordinated)规范,指的是经度 0 度上的规范工夫,我国日常生活中时区以首都北京所处的东半球第 8 区为基准,对立应用东 8 区工夫(俗称北京工夫),比 UTC 要早 8 个小时,时区设置也遵循此规范,因而对应过去 timestamp 的工夫范畴则应校准为 ’1970-01-01 08:00:01’ and ‘2038-01-19 11:14:07’,也就是说东八区的 1970-1-1 08:00:01 等同于 UTC1970-1-1 00:00:01。
3、尽量应用 dateTime 格局而非 timestamp:
有一些状况须要留神不要应用 timestamp 存储工夫:
• 生日:生日必定会有早于 1970 年的,会超出 timestamp 的范畴
• 有效期截止工夫:timestamp 的最大工夫是 2038 年,如果用来存相似身份证的有效期截止工夫,营业执照的截止工夫等就不适合。
• 业务生存工夫:互联网时代倒退快,业务工夫很可能在 2038 年还在持续经营。
四、数据库连贯设置的其余隐患
1、连接数设置
(1) 介绍
数据库连接池在初始化时将创立肯定数量的数据库连贯放到连接池中,这些数据库连贯的数量是由最小数据库连接数制约。无论这些数据库连贯是否被应用,连接池都将始终保障至多领有这么多的连贯数量。连接池的最大数据库连贯数量限定了这个连接池能占有的最大连接数,当应用程序向连接池申请的连接数超过最大连贯数量时,这些申请将被退出到期待队列中。
由此看来,当数据库最大连接数设置不够大时,则会呈现某些报表或须要查询数据库的申请失败,因为连接数不够不能被解决,从而报错。当呈现大量并发的报表申请,且连接池的最大连接数不够用时,一些用户的申请就无奈解决,这样也就从另一个层面影响了整个我的项目解决吞吐量的能力,限度了我的项目的性能和效率。
(2)设置准则
既能保障我的项目失常应用时对数据库连接数的要求,又能爱护 DBS 的平安和稳固。
(3)查问形式:
查问最大连接数命令:show variables like’%max_connections%’;
查问以后数据库已建设连接数:show status like ‘Threads_connected’;
(4)倡议:
MYSQL 官网给出了一个设置最大连接数的倡议比例:
Max_used_connections / max_connections * 100% ≈ 85%
即已应用的连接数占总下限的 85% 左右。
2、超时工夫设置
(1)介绍
一次残缺的申请包含三个阶段:1、建设连贯 2、数据传输 3、断开连接
connect timeout: 如果与服务器 (这里指数据库) 申请建设连贯的工夫超过 ConnectionTimeOut,就会抛 ConnectionTimeOutException,即服务器连贯超时,没有在规定的工夫内建设连贯。在数据库连贯设置中,connectTimeout 示意期待和 MySQL 数据库建设 socket 链接的超时工夫,默认值 0,示意不设置超时,单位毫秒。
socket timeout: 如果与服务器连贯胜利,就开始数据传输了。如果服务器解决数据用时过长,超过了 SocketTimeOut,就会抛出 SocketTimeOutExceptin,即服务器响应超时,服务器没有在规定的工夫内返回给客户端数据。在数据库连贯设置中,socketTimeout 示意客户端和 MySQL 数据库建设 socket 后,读写 socket 时的期待的超时工夫,linux 零碎默认的 socketTimeout 为 30 分钟。
(2)隐患
拜访数据库超工夫太长,拜访数据量大或者扫描的数据量太大,导致数据库长时间无响应。链接被占用无奈开释,会导致线程池被占满。因而,为了可能及时开释占用链接,其余业务对数据库拜访不受影响,所以要正当设置数据库拜访超时工夫。
JDBC 的 socket timeout 在数据库被忽然停掉或是产生网络谬误(因为设施故障等起因)时非常重要。因为 TCP/IP 的构造起因,socket 没有方法探测到网络谬误,因而利用也无奈被动发现数据库连贯断开。如果没有设置 socket timeout 的话,利用在数据库返回后果前会无期限地等上来,这种连贯被称为 dead connection。
为了防止 dead connections,socket 必须要有超时配置。socket timeout 能够通过 JDBC 设置,socket timeout 可能防止利用在产生网络谬误时产生无休止期待的状况,缩短服务生效的工夫。
(3)倡议
个别状况,倡议配置 connectTimeout=60000,单位毫秒。倡议配置 socketTimeout=60000,单位毫秒。具体配置因零碎而异。
总结
容易被忽视的数据库连贯利用衰弱度查看项,背地有着时区、超时工夫、连接数设置不当可能带来的隐患;依据利用理论状况并遵循设置准则进行正当设置,满足利用衰弱度查看项,能力防患于未然。