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

纯干货:数据库连接耗时慢原因排查

背景

最近公司的社区相关的服务需要优化,由于对业务不熟悉,只能借助监控从一些慢接口开始尝试探索慢的原因。由于社区相关的功能务是公司小程序流量入口,所以相应的服务访问量还是比较高的。针对这类高访问的项目,任何不留神的地方都可能会引起连锁反应导致瓶颈,本次是针对此次排查提供一些我探索的方法。

慢原因

由于我们生产环境接入了阿里云的ARMS监控,所以排查效率会特别高。先列举一些比较常见的慢原因:

  • 下游接口调用慢

这个不多赘述,当时是两个原因:1. 网关慢 2. 代码没有缓存

  • 缓存获取慢

这个是命令使用不规范,使用了redis比较危险的 keys命令,后续此类场景用es代替了

  • 慢SQL

这里也是慢的主力军,比较常见的点:

  1. 索引没命中
  2. 大表之间join关联
  3. 不规范的命令比如:or、not 、like等等
  4. SQL不规范,count后面接limit
  5. 随着数据量的增长,导致平常很快的SQL,突然响应时间飙升

我觉得更多的是前期的表设计存在很大的问题,导致太多的表关联查询效率很差。

  • 获取连接数慢

这里也是我之前比较忽略的地方,也是这次比较关键的点。

连接慢的排查之路

我们使用的是阿里的druid的连接池,所以一开始并没有觉得有什么大问题。

从ARMS中找了一个比较有代表性的图:
ARMS连接数慢监控图
一共耗时12秒,一开始只觉得应该和并发请求有关,因为只有比较少量的请求会出现该情况。

这是一个查询接口,而且承载了该服务大量的请求。

通过分析链路发现了两个比较明显的问题:

- 下游的接口慢
- SQL比较耗时

嗯,双手插兜,自信回头!烟来~

经过一番优化之后,效果显著,但是还是存在几秒获取连接的情况。

这是啥情况?仔细盯着链路图,发呆了几秒,不对呀!查询接口咋还出现了commit提交事务的命令呢?

由于这个接口查询本地表的SQL并不慢,而且并没有修改数据的动作存在,转而又去看了相应的代码。方法上面也没有加上@Transaction呀?咋就把事务开了呢!思来想去,泥马不会在类上加了吧! 一看果然!!!

@Service
@Transactional(rollbackFor = Exception.class)
public class XxxxService extends AbstractUserService {
}

由于这个接口访问频率非常高,时不时会执行缓慢(有下游和本地资源不稳定的因素),开启了事务就意味着,拿到一个数据库连接之后需要执行完整个事务逻辑才会释放连接
也就是说如果当前时段比较耗时执行了3秒钟,此时并发比较高,你的连接数在这三秒内会急剧上升。
连接数上升了,事务多了,可能还会发生锁争抢,这也就是平常一个SQL你觉得必然不会慢,但它就是莫名其妙的慢了可能导致的原因。

怕了怕了,这种写法会导致接口内部的方法可能都会默认开启事务,一旦事务内部有出现下游调用或者慢操作,就会出现长事务。

此时感觉自己深陷沼泽。。。赶紧写了个工具扫描所有service类上加了@Transaction注解的功能。。逐一修复!!!

优化了一版之后,我想应该差不多了吧!
嗯,双手插兜,转身就走。不恋战~

第二天瞄了一眼,嗯,还是有提升,但是还是有几百毫秒的获取连接情况!
天哪~

又不情不愿的盯着ARMS的各种功能看【不得不说ARMS还是挺全面的】

终于在线程监控中发现端倪:
线程监控
看到这个
at com.alibaba.druid.pool.DruidAbstractDataSource.testConnectionInternal (DruidAbstractDataSource.java:1407)
心里顿时感觉应该和配置有关,通过看源码发现是到了testOnBorrow满足的逻辑,然后去看了服务相关的配置:
spring.datasource.druid.testOnBorrow=true

嗯嗯嗯,去官网上看了相关的解释;

配置默认值说明
testOnBorrowtrue申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testWhileIdlefalse建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效
timeBetweenEvictionRunsMillis1分钟(1.0.14)有两个含义:1) Destroy线程会检测连接的间隔时间,如果连接空闲时间大于等于minEvictableIdleTimeMillis则关闭物理连接。2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明
  • druid github 配置参考
  • druid github 通用配置

想想也是,如果每次获取连接都去校验是否有效,这不纯纯浪费么。通常一般99%的校验都是浪费,倒不如指定的超时时间去校验一次,当然各有取舍,极端情况可能会出现连接时效的问题,但影响应该也不大。

嗯,双手… 放好,战斗还没有结束,多观察几天再看看!

另外再补充一个阿里云的jedis的最佳实践吧

还有一个扫描@Transaction注解的方法:

import cn.hutool.core.lang.ClassScanner;
import cn.hutool.core.lang.Filter;
import org.springframework.transaction.annotation.Transactional;import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;public class TransactionPonintCase {public static void main(String[] args) {List<Class> clazzList= new ArrayList<>();List<String> methodList= new ArrayList<>();Set<Class<?>> classes = ClassScanner.scanAllPackage("你要扫描的包", new Filter<Class<?>>() {@Overridepublic boolean accept(Class<?> aClass) {boolean annotationPresent = aClass.isAnnotationPresent(Transactional.class);if(annotationPresent){clazzList.add(aClass);return true;}for (Method declaredMethod : aClass.getDeclaredMethods()) {if(declaredMethod.isAnnotationPresent(Transactional.class)){methodList.add(declaredMethod.getDeclaringClass().getName()+"."+declaredMethod.getName());}}return annotationPresent;}});System.out.println(">>>>>>>>>>>>>>>>> 类级别注解 <<<<<<<<<<<<<<<<<<<<<");for (Class<?> aClass : classes) {System.out.println(aClass.getName());}System.out.println(">>>>>>>>>>>>>>>>> 方法級別注解 <<<<<<<<<<<<<<<<<<<<<");for (String name : methodList) {System.out.println(name);}}
}

相关文章:

纯干货:数据库连接耗时慢原因排查

背景 最近公司的社区相关的服务需要优化&#xff0c;由于对业务不熟悉&#xff0c;只能借助监控从一些慢接口开始尝试探索慢的原因。由于社区相关的功能务是公司小程序流量入口&#xff0c;所以相应的服务访问量还是比较高的。针对这类高访问的项目&#xff0c;任何不留神的地…...

【OneNet】| stm32+esp8266-01s—— OneNet初体验 | 平台注册及设备创建 | demo使用

系列文章目录 失败了也挺可爱&#xff0c;成功了就超帅。 文章目录 前言1. OneNet平台注册2. 创建多协议接入设备3. 硬件连接4. 下载并运行Demo4.1 Demo下载4.2 运行Demo本小节结束 前言 最近准备耍下 Onenet平台 。下载了官方demo 遇到几个问题 1、创建接入设备 因为平台网页…...

解决win无法删除多层嵌套文件夹

起因&#xff1a;昨天研究jpackage工具&#xff0c;不小心搞得一个文件夹里嵌套了好几百个文件夹&#xff0c;用win自己的删除删不掉&#xff0c;shiftdel直接删除也不行&#xff0c;直接弹窗删除错误&#xff1b; 后来用电脑管家下载了个“文件粉碎”&#xff0c;添加目录&am…...

用Vue简单开发一个学习界面

文章目录 一.首先创建我们的Vue文件夹二.源代码BodyDemoHearderDemoHomeDemoMarkdownDemoFileManager.jsMain.js&#xff08;注意绑定&#xff09;APP源代码 效果图&#xff08;按钮功能&#xff09;新增二级菜单&#xff08;v-for&#xff09;需要的可以私信 一.首先创建我们的…...

Oracle数据库从入门到精通系列之五:数据文件

Oracle数据库从入门到精通系列之五:数据文件 一、数据文件二、Oracle数据库存储分配单位三、Oracle数据库文件系统机制四、段五、区段六、块七、表空间八、Oracle数据库存储层次体系小结一、数据文件 数据文件和重做文件是数据库中最重要的文件,数据最终会存储在这些文件中。…...

使用MockJS进行前端开发中的数据模拟

在前端开发中&#xff0c;有时我们需要在没有后端接口的情况下进行前端页面的开发和测试。这时&#xff0c;我们可以使用MockJS来模拟数据&#xff0c;以便进行开发和调试。MockJS是一个用于生成随机数据和拦截Ajax请求的JavaScript库&#xff0c;它能够帮助我们快速搭建起一个…...

Ex-ChatGPT本地部署+Azure OpenAI接口配置+docker部署服务

Ex-ChatGPT项目分为 Ex-ChatGPT 和 WebChatGPTEnhance 两部分&#xff0c;Ex-ChatGPT启动后是个web服务&#xff0c;通过访问ip端口体验&#xff1b; WebChatGPTEnhance可编译生成一个浏览器插件&#xff0c;Chrome或者Microsoft edge浏览器可以安装该插件&#xff0c;点击该插…...

【收藏】FP独立站建站安心收款经验分享

前几天有个客户咨询我&#xff0c;跟我说了他的疑问。他是在阿里巴巴国际站上面做鞋服&#xff0c;但看到同行在独立站上铺fp&#xff0c;所以他想问问&#xff1a;怎么建立一个独立站并在上面成功推出fp呢&#xff1f;今天&#xff0c;我就来跟有类似诉求的朋友们分享一下&…...

python:绘制GAM非线性回归散点图和拟合曲线

作者&#xff1a;CSDN _养乐多_ 本文将介绍使用python语言绘制广义线性模型&#xff08;Generalized Additive Model&#xff0c;GAM&#xff09;非线性回归散点图和拟合曲线。并记录了计算RMSE、ubRMSE、R2、Bias的代码。 文章目录 一、GAM非线性回归详解二、代码三、计算RM…...

每日算法(第十四期)

儿童节了也要好好学习鸭。 先来回顾一下上期的问题及答案&#xff1a; 「反转链表」&#xff08;Reverse Linked List&#xff09;。 题目描述&#xff1a; 反转一个单链表。 以下是对应的JavaScript实现&#xff1a; function reverseList(head) {let prev null;let curr he…...

uboot的使用

目录 串口调试 1.uboot模式 自启动模式&#xff1a; 交互模式 2.uboot帮助命令 3.uboot环境变量 4.uboot常用环境变量 5.uboot网络传输命令 6.uboot存储器访问命令 7.uboot自启动环境变量 串口调试 1.串口连接开发板&#xff0c;通过 "设备管理器" 获取对…...

学习HCIP的day.09

目录 一、BGP&#xff1a;边界网关路由协议 二、BGP特点&#xff1a; 三、BGP数据包 四、BGP的工作过程 五、名词注解 六、BGP的路由黑洞 七、BGP的防环机制—水平分割 八、BGP的基本配置 一、BGP&#xff1a;边界网关路由协议 是一种动态路由协议&#xff0c;且是…...

Electron-Builder Windows系统代码签名

前言 项目打包签名是两年前做的了&#xff0c;使用Electron-Bulder&#xff0c;打包工具版本迭代较少&#xff0c;倒是electron版本更新飞快&#xff0c;目前官方推荐使用Electron Forge进行打包&#xff0c;后续再对两者进行对比&#xff0c;重新整理现在的实现方案。 签名简…...

数据分析概述

数据分析概述 数据的性质数据的概念数据与信息的区别和联系 数据的类型按照度量尺度分按时间状况分 什么是数据分析数据分析的重要性数据分析的内容数据分析作用 数据分析的基本流程典型的数据分析的流程 数据分析方法对比分析法分组分析法定量数据分布分析——具体事例 结构分…...

网络编程初识

如果这篇有没接触过的知识点&#xff0c;请转到网络编程先导知识_小梁今天敲代码了吗的博客-CSDN博客 目录 IPv4和IPv6的概念&#xff1a; 子网掩码 默认网关 ping命令 端口 OSI网络分层模型 TCP/IP四层模型 字节序转换函数 IP地址转换 上一篇介绍了网络编程的先导知…...

软考A计划-试题模拟含答案解析-卷十二

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…...

I.MX RT1170加密启动详解(1):Encrypted Boot image组成

使用RT1170芯片构建的所有平台一般都是高端场合&#xff0c;我们需要考虑软件的安全需求。该芯片集成了一系列安全功能。这些特性中的大多数提供针对特定类型攻击的保护&#xff0c;并且可以根据所需的保护程度配置为不同的级别。这些特性可以协同工作&#xff0c;也可以独立工…...

Linux---用户切换命令(su命令、sudo命令、exit命令)

1. su命令 root用户拥有最大的系统操作权限&#xff0c;而普通用户在许多地方的权限是受限的。 普通用户的权限&#xff0c;一般在其HOME目录内是不受限的。 一旦出了HOME目录&#xff0c;大多数地方&#xff0c;普通用户仅有只读和执行权限&#xff0c;无修改权限。 su 是…...

手机图片怎么提取文字?高效渠道一览

随着智能手机的普及&#xff0c;我们现在可以随时随地使用手机拍照记录生活中的点滴。然而&#xff0c;有时候我们拍照之后可能需要提取图片中的文字&#xff0c;比如拍下的菜谱、公告、名片等等。这时&#xff0c;我们就需要使用手机图片提取文字的功能。 - 采用OCR技术拍照识…...

Elasticsearch 聚合数据结果不精确问题解决方案

Elasticsearch 聚合数据结果不精确 背景 近期我们项目中出现使用ES聚合某个索引的数据取TOP 10的数据和相同条件下查询所有数据然后按数据量排序取的TOP 10的数据不一致的问题。 下面我们简单分析一下这个问题&#xff0c;列出一些常见的解决方案。 问题 Elasticsearch分片…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解

文章目录 一、开启慢查询日志&#xff0c;定位耗时SQL1.1 查看慢查询日志是否开启1.2 临时开启慢查询日志1.3 永久开启慢查询日志1.4 分析慢查询日志 二、使用EXPLAIN分析SQL执行计划2.1 EXPLAIN的基本使用2.2 EXPLAIN分析案例2.3 根据EXPLAIN结果优化SQL 三、使用SHOW PROFILE…...

RushDB开源程序 是现代应用程序和 AI 的即时数据库。建立在 Neo4j 之上

一、软件介绍 文末提供程序和源码下载 RushDB 改变了您处理图形数据的方式 — 不需要 Schema&#xff0c;不需要复杂的查询&#xff0c;只需推送数据即可。 二、Key Features ✨ 主要特点 Instant Setup: Be productive in seconds, not days 即时设置 &#xff1a;在几秒钟…...

Linux入门(十五)安装java安装tomcat安装dotnet安装mysql

安装java yum install java-17-openjdk-devel查找安装地址 update-alternatives --config java设置环境变量 vi /etc/profile #在文档后面追加 JAVA_HOME"通过查找安装地址命令显示的路径" #注意一定要加$PATH不然路径就只剩下新加的路径了&#xff0c;系统很多命…...

【Qt】控件 QWidget

控件 QWidget 一. 控件概述二. QWidget 的核心属性可用状态&#xff1a;enabled几何&#xff1a;geometrywindows frame 窗口框架的影响 窗口标题&#xff1a;windowTitle窗口图标&#xff1a;windowIconqrc 机制 窗口不透明度&#xff1a;windowOpacity光标&#xff1a;cursor…...