大循环引起CPU负载过高
一、问题背景
环境:jdk1.8 + tomcat7
在一次发布时,cpu
出现负载过高,其负载突破200%
,并且响应时间也大幅度超时。
二、问题分析
【1】发布前做过压测,并没有发现cpu
异常升高的现象,所以其可能与生产环境的请求相关。
【2】通过cat
观察thread dump
虽然发现http
线程数有所增加,并且存在block
线程数,但是观察锁竞争详情,发现其均是框架代码正常的锁竞争,比如序列化获取时间需要拿到format
对象锁,另外也对排除dead lock
的可能。
【3】由于测试环境无法复现,所以尝试使用镜像机器,并在惊喜机器中复现cpu
上升的问题,由于设计到cpu load
的问题,选择使用性能实验室中的cpu 火焰图,观察cpu
热点代码。
【4】通过观察火焰图,发现String::equalsIgnoreCase
方法位于顶层,且宽度想对较大,也就是说工具在采样cpu
执行的代码时,很大一部分都采样到该函数,说明cpu
的资源集中在这个函数上。
纵轴表示栈帧深度,横轴表示代码占用CPU/内存的比例,点击可以查看详情。
三、问题排查
【1】根据火焰图分析调用栈,发现String::equalsIgnoreCase
代码位于业务代码中的循环中。
// 获取所有的城市
List<CityDataModel> cities = cityService.allCities();
for (CityDataModel city : cities) {if (city.getCityCode().equalsIgnoreCase(flight.getDepartCity())) {dCountry = city.getCountryCode();}if (city.getCityCode().equalsIgnoreCase(flight.getArriveCity())) {aCountry = city.getCountryCode();}
}
【2】通过在测试环境调用该请求,发现其循环的数据时所有的城市列表,而列表的长度可达到12000,而且该循环本身被执行12
此,String::equalsIgnoreCase
方法执行了20w
次,这是一个非常典型的大循环代码,并且通过记录日志发现,在生产中该代码平均每次请求都会调用24w
次左右,所有导致cpu
资源都集中在该方法上,使得cpu load
大幅度提高。
CPU
负载定义为在单个时间点使用或等待使用一个内核的进程数。在单核系统,我们的CPU
平均负载始终低于0.7
。这表明每个需要使用CPU
的进程都可以立即使用它,而无需等待。如果CPU
平均负载大于1
,则表示有进程需要使用CPU
,但由于CPU
不可用,目前无法使用。在多处理器系统中高于1
的平均负载不会成为问题,因为有更多内核可用。
CPU
使用率是CPU
处理非空闲任务所花费的时间百分比 。例如单核CPU 1s
内非空闲态运行时间为0.8s
,那么它的CPU
使用率就是80%
;双核CPU 1s
内非空闲态运行时间分别为0.4s
和0.6s
,那么,总体CPU
使用率就是(0.4s + 0.6s) / (1s * 2) = 50%
,其中2
表示CPU
核数,多核CPU
同理。CPU
使用率只能在指定的时间间隔内测量。我们可以通过将空闲时间的百分比从100
中减去来确定CPU
使用率。
CPU load
和CPU
使用率更多可以参考:CPU使用率和负载
四、问题总结
问题解决方案: 由于代码中大循环非常小号cpu
资源,通过分析这里String::equalsIgnoreCase
方法的作用在于遍历判断获取数据,优先使用hashmap
代替,用空间换时间,经过修复后重新发布,cpu
利用率明显下降,恢复正常。
思考总结:
【1】使用循环时需要特别注意大循环,有限使用O(1)
的hashmap
,大循环对于cpu
性能的压榨问题表现的淋淋尽致。
【2】镜像机器由于是使用生产流量转发,所以高度贴近生产实际发布,所以每次发布前,先使用镜像机器预发布,可以尽可能的将潜在问题暴露出来,性能实验室中提供了cpu
热点,内存分配热点和锁竞争热点的Flamegraph
,在预发布中遇到问题时也可以更加直观地帮助解决问题,也不会对实际生产机器造成影响。
【3】此次发布前,虽然在测试环境进行了压测,但是并没有复现问题,分析原因,其与特定的压测请求相关,由于在压测时使用的请求没有经过某些代码分支,使得循环的次数想对较少,使得在测试环境中并没有压测出该问题,在压测时,可以尝试使用不同的请求压测并结合镜像机器的预发布来杜绝这种潜在问题发生。
相关文章:

大循环引起CPU负载过高
一、问题背景 环境:jdk1.8 tomcat7 在一次发布时,cpu出现负载过高,其负载突破200%,并且响应时间也大幅度超时。 二、问题分析 【1】发布前做过压测,并没有发现cpu异常升高的现象,所以其可能与生产环境的请…...

[Java]微服务治理
注册中心原理 注册中心可以统一管理项目中的所有服务 服务治理中的三个角色分别是什么? 服务提供者: 暴露服务接口,供其它服务调用服务消费者: 调用其它服务提供的接口注册中心: 记录并监控微服务各实例状态,推送服务变更信息 消费者如何知道提供者的…...

深入解析C语言中的extern关键字:语法、工作原理与高级应用技巧
引言 在C语言中,extern 关键字是一个强大的工具,用于声明外部变量和函数,使得这些变量和函数可以在多个源文件之间共享。理解 extern 的工作原理和最佳实践对于编写模块化、可维护的代码至关重要。本文将深入探讨 extern 关键字的各个方面&a…...

元器件封装
元器件封装类型 为什么越来越多用贴片元件,而不是插件元件 为什么越来越多用贴片元件,而不是插件元件 1.体积小、质量小、容易保存和运输; 2.容易焊接和拆卸。抗震效果好。 贴片元件不用过孔,用锡少。直插元件最麻烦的就是拆卸&a…...

状态空间方程离散化(Matlab符号函数)卡尔曼
// 卡尔曼滤波(4):扩展卡尔曼滤波 - 知乎 // // matlab 连续系统状态空间表达式的离散化&状态转移矩阵求解_matlab状态方程离散化-CSDN博客 // // // %https://blog.csdn.net/weixin_44051006/article/details/107007916 clear all; clc; syms R1 R2 C1 C…...
软件设计师-计算机网络
OSI网络模型 物理层,提供原始物理通路。数据交换的单位是二进制,bit,比特流,设备有中继器,集线器数据连输层,把原始不可靠的物理层链接变成无差错的数据通道,并解决多用户竞争问题。传送单位是帧ÿ…...

SpringBoot操作Elasticsearch
SpringBoot操作Elasticsearch SpringData框架简化Java代码连接ES的过程 官网:https://spring.io/projects/spring-data/ 以上列表中都是Spring Data支持连接的数据源 添加依赖 已经添加过了 <!--添加SpringDataES的依赖--><dependency><groupId&…...
阿里云aliyun gradle安装包下载地址
阿里云 查找你要下载的安装包 macports-distfiles-gradle安装包下载_开源镜像站-阿里云 https://mirrors.aliyun.com/macports/distfiles/gradle/gradle-8.9-bin.zip 腾讯 https://mirrors.cloud.tencent.com/gradle/ https://mirrors.cloud.tencent.com/gradle/ https…...

【设计模式】创建型设计模式-工厂模式的实现
工厂模式实现 定义例子UML类图理解Java代码实现总结 定义 工厂方法模式定义了一个接口用于创建对象,该模式由子类决定实例化哪个工厂类。该模式把类的实例化推迟到了子类。 例子 通过一个公共的类方法来管理画图对象的创建。 UML类图理解 Java代码实现 定义接口…...
【分布式】CAP理论
CAP定理的核心要点: CAP定理指出,任何一个分布式系统在面对网络分区(Partition)的情况下,最多只能同时满足以下三个特性中的两个: 一致性(Consistency): 所有节点在同一…...
市域社会治理现代化解决方案-2
1. 社会治理现代化背景 市域社会治理现代化旨在通过制度化、科学化、规范化、程序化和精细化的治理体系,实现社会治理能力的提升。该方案强调市一级的统筹协调和资源技术优势,以有效应对新型社会矛盾和风险挑战。 2. 社会治理面临的问题 当前社会治理在实践中存在诸多问题…...

谷歌浏览器的自动翻译功能如何开启
在当今全球化的网络环境中,能够流畅地浏览不同语言的网页是至关重要的。谷歌浏览器(Google Chrome)提供了一项强大的自动翻译功能,可以帮助用户轻松跨越语言障碍。本文将详细介绍如何开启和使用谷歌浏览器的自动翻译功能ÿ…...

Linux设置socks代理
公司里绝大多数主机已经禁止外网访问,仅保留一台主机设置socks作为代理服务器。如下为对socks这一概念的学习整理 什么是socks 是一种OSI模型下会话层的协议,位于表示层与传输层之间,作用是: exchanges network packets between…...

【ACM出版】第四届信号处理与通信技术国际学术会议(SPCT 2024)
& 第四届信号处理与通信技术国际学术会议(SPCT 2024) 2024 4th International Conference on Signal Processing and Communication Technology 2024年12月27-29日 中国深圳 www.icspct.com 第四届信号处理与通信技术国际学术会议&#x…...
蓝队技术学习
声明: 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文 章。本文只涉及学习内容,其他的都与本人无关,切莫逾越法律红线, 否则后果自负 蓝队技术基础 1.企业网络架构:企业技术和信息团队的管理架构因企业而异。 CIO(Chief Informa…...

openpyxl处理Excel模板,带格式拷贝行和数据填入
本文中用openpyxl操作Excell 模板,进行行拷贝和数据填充. 主要涉及单元格格式的拷贝,合并单元格的拷贝,行高和列宽的处理. 将模板表格分为三部分,头部,中间循环填充部分,尾部.模板参数中设置头部高度,循环部分高度,剩余为尾部. 拷贝时先拷贝填充头部 ,然后根据数据循环拷贝填…...

无法在带有 WHM/cPanel 的 Ubuntu 22.04 服务器上安装 PHP 7.x – 缺少软件包
问题 正在使用Ubuntu 22.04设置服务器,并使用WHM/cPanel管理多个帐户和配置。我的目标是在服务器上安装 PHP 7.4(或更早的版本,如 PHP 7.3),因为我的一些应用程序与 PHP 8.x 不兼容。问题是,每当我尝试安装…...

数据结构-递归函数的调用栈过程
这道题考察的是递归函数的调用栈过程。 逐步分析程序的执行过程: main() 函数首先被调用,此时栈底是 main() 的信息。main() 函数调用 S(1),此时 S(1) 的信息被压入栈中,位于 main() 之上。S(1) 函数内部调用 S(0),因…...

在 WPF 中,如何实现数据的双向绑定?
在 WPF 中,数据绑定是一个非常重要的特性,它允许 UI 与数据源之间自动同步。双向绑定是一种常见的绑定方式,当数据源更新时,UI 会自动更新;同样,当 UI 中的元素(如文本框)发生改变时…...
pyinstaller 打包 playwright -- 如何将浏览器打包到程序中
start 最近玩了玩 playwright,记录一下遇到的问题。 1. 如何在 python 中使用 安装 pip install playwright安装浏览器驱动 playwright install查看浏览器驱动安装的位置 playwright install --dry-run2. 如何将浏览器打包的程序中 先找到我们使用 pip 安装…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...