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

排查和解决服务器cpu过载的问题

背景

最近几天发现服务器经常在某个时间段cpu突然过载 老板发了几次消息让排查一下问题原因。这台服务器主要是作为api调用的服务器,所以一旦出现问题就可能会影响客户。

服务器相关

阿里云服务器 24核48GB 公网带宽为5Mbps; 一台负载均衡的服务器 16核 32GB
服务器上的项目为php Laravel和golang项目作为api接口

排查思路

1.看下是网络攻击还是瞬时网络请求过多导致的(大概率为网络请求过多)
2.看下cpu过载期间请求最多的接口是哪几个,该接口是否有报错和慢查询。
3.查看laravel的项目日志 看下时候有报错

初步诊断

1.查看阿里云记录的日志发现cpu过载期间的请求数量是普通情况下的4到5倍,且查看日志只有数据库超时连接的错误(这个应该是请求数量过多 数据库连接数太多导致的) 查看过载情况下laravel接口15分钟段内请求数量为125766和闲时的15分钟内为49192
2.cpu过载时使用top命令查看发现占用cpu最多的进程是php-fpm
3.查看php-fpm的慢日志分析;慢日志存放目录为(www/server/php/73/var/log/slow.log)
tail -f slow.log #监控当前的慢日志
4.监控慢日志发现有慢日志如下内容

点击查看代码
[24-Jul-2025 17:30:52]  [pool www] pid 28728
script_filename = /www/wwwroot/name.jiaoguanyi.cn/public/index.php
[0x00007fdc2861e570] hasChildren() /www/wwwroot/name.jiaoguanyi.cn/vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php:78
[0x00007fdc2861e500] hasChildren() unknown:0
[0x00007fdc2861e4b0] next() unknown:0
[0x00007fdc2861e460] next() unknown:0
[0x00007fdc2861e410] next() unknown:0
[0x00007ffe21de3cf0] ???() /www/wwwroot/name.jiaoguanyi.cn/vendor/laravel/framework/src/Illuminate/Session/FileSessionHandler.php:109
[0x00007fdc2861e370] gc() /www/wwwroot/name.jiaoguanyi.cn/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php:133
[0x00007fdc2861e2f0] collectGarbage() /www/wwwroot/name.jiaoguanyi.cn/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php:60
[0x00007fdc2861e220] handle() /www/wwwroot/name.jiaoguanyi.cn/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:151
[0x00007fdc2861e150] Illuminate\Pipeline\{closure}() /www/wwwroot/name.jiaoguanyi.cn/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
[0x00007fdc2861e090] Illuminate\Routing\{closure}() /www/wwwroot/name.jiaoguanyi.cn/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php:66
[0x00007fdc2861df60] handle() /www/wwwroot/name.jiaoguanyi.cn/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:151
[0x00007fdc2861de90] Illuminate\Pipeline\{closure}() /www/wwwroot/name.jiaoguanyi.cn/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
[0x00007fdc2861ddd0] Illuminate\Routing\{closure}() /www/wwwroot/name.jiaoguanyi.cn/vendor/fideloper/proxy/src/TrustProxies.php:57
[0x00007fdc2861dd30] handle() /www/wwwroot/name.jiaoguanyi.cn/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:151
[0x00007fdc2861dc60] Illuminate\Pipeline\{closure}() /www/wwwroot/name.jiaoguanyi.cn/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
[0x00007fdc2861dba0] Illuminate\Routing\{closure}() /www/wwwroot/name.jiaoguanyi.cn/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:31
[0x00007fdc2861daf0] handle() /www/wwwroot/name.jiaoguanyi.cn/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:151
[0x00007fdc2861da20] Illuminate\Pipeline\{closure}() /www/wwwroot/name.jiaoguanyi.cn/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
[0x00007fdc2861d960] Illuminate\Routing\{closure}() /www/wwwroot/name.jiaoguanyi.cn/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:31

分析了下这个慢日志的原因是 session文件过多 于是我手动查看了下目前session文件一共有多少个
ls -l /www/wwwroot/name.jiaoguanyi.cn/storage/framework/sessions | wc -l
显示有513065个 50多万个!session文件过多会导致GC执行缓慢

cpu过载的关键原因

通过慢日志查询到了当前项目session过多的问题。那么为什么session文件过多会导致cpu过载呢?这里就不得不提到laravel项目的session垃圾回收机制。
垃圾回收机制(以文件驱动为例)

  1. 扫描 Session 存储目录(默认在 storage/framework/sessions/)
  2. 检查每个 Session 文件的上次修改时间(mtime)。
  3. 如果当前时间减去修改时间大于 SESSION_LIFETIME(过期),则删除该文件。
    为什么文件驱动会导致性能问题?
    laravel使用session来存储用户的状态信息(如用户登录状态)当你的环境配置为SESSION_DRIVER=file时候会在/storage/framework/sessions的目录下生成对应的文件来存储,而且laravel的垃圾回收会扫描session存储目录、检查每个session文件的上次修改时间(mtime)、 如果当前时间减去修改时间大于 SESSION_LIFETIME(过期),则删除该文件。
  • I/O 密集:当 Session 文件数量很大时,扫描整个目录并检查每个文件的修改时间会消耗大量 I/O 资源。
  • 递归扫描:如果使用 Symfony Finder 组件(如你日志中显示的),它可能会递归扫描目录(尽管你的 Session 文件应该都在同一级目录),但每个文件的系统调用都很昂贵。

解决session文件过的的问题

思路:
1.把当前旧的session文件清理掉
2.改用高效的session驱动 如redis
3.调整session GC的概率

清理旧的session文件
点击查看代码
# 手动清理过期 Session
cd /www/wwwroot/name.jiaoguanyi.cn/storage/framework/sessions/
find . -type f -mmin +120 -delete  # 删除2小时前的文件
更改session驱动为redis

在.env文件中修改(前提是该项目已经支持redis)
SESSION_DRIVER=redis

调整session GC的概率

修改 config/session.php
'lottery' => [1, 10000], // 从 1/100 改为 1/10000 触发概率

http://www.wooajung.com/news/35408.html

相关文章:

  • C. Not Assigning
  • 基于运维编排实现服务器故障自愈
  • 49.底层逻辑
  • 28-48.雪中捍刀行
  • K8s Pod 多种数据存储方式
  • 14Java基础之抽象类、接口
  • 深入解析:mac电脑安装 nvm 报错如何解决
  • 洛谷 P12078 [OOI 2025] Best Runner 题解
  • 远程git ssh配置1
  • 7月24日总结
  • VIRTUBOX BUG
  • 精通Python PDF裁剪:从入门到专业的三重境界
  • 如何在群晖虚拟机快速部署线上web网站并实现公网访问
  • 向他人分享我的音频
  • - BigBosscyb - 博客园
  • 整体二分
  • 闲来无事
  • - daydreamer_zcxnb - 博客园
  • - Redamancy_Lydic - 博客园
  • - darling331 - 博客园
  • - kintsgi - 博客园
  • TIM外部中断
  • LPC总线设计及其仿真验证
  • Fluent许可证类型
  • 多值依赖
  • Windows 验证耳机输入是否正常
  • ABC典题总结
  • springboot项目解决报错:spring boot application in default package
  • LaTeX中为何推荐substack而不使用\atop?
  • 手机网页版浏览器seo案例分析及解析