skynet线上问题查证练习记录(更新中)

cpu暴涨类

在匹配服务中新增一个死循环。

lua 复制代码
-- 玩家请求开始匹配
function CMD.start_match(uid, elo_val, name, agent_addr)
	-- ====== FAULT INJECTION (INJECTED): CPU 死循环 ======
	local _fault_counter = 0
	while true do _fault_counter = _fault_counter + 1 end
	-- ====== END FAULT INJECTION ======
	-- 防重复检查
	if uid_bucket_map[uid] then
		return { ok = false, errmsg = "already in matching queue" }
	end

	-- 找到对应的段位桶
	local bucket_name = elo.get_bucket(elo_val)
	local bucket_players_a = get_bucket_players(bucket_name)

	table.insert(bucket_players_a, {
		uid = uid,
		elo = elo_val,
		name = name,
		agent_addr = agent_addr,
		enter_time = skynet.now() / 100,
	})

	uid_bucket_map[uid] = bucket_name

	rpc.send("chat_mgr", "update_player_state", uid, "matching")

	skynet.error(string.format("[match_mgr] player enter queue: uid=%d name=%s elo=%d bucket=%s total=%d",
		uid, name, elo_val, bucket_name, get_total_queue_size()))
	return { ok = true }
end

步骤

一、先查看正常情况下的skynet的正常状态

服务列表

消息队列和cpu

内存占用情况

查看cpu使用率

bash 复制代码
# 2. 看 Battle 节点的 CPU
top -p $(pgrep -f "chatroom.*battle" | head -1) -bn1 | head -5

解析:

第一行:系统概览
复制代码
top - 21:24:02 up  1:13,  0 users,  load average: 4.99, 4.75, 4.65
字段 含义 你的值
21:24:02 当前时间 晚上 9:24
up 1:13 开机到现在 1 小时 13 分 ---
0 users 登录用户数 0(你可能是 ssh 进来的不算)
load average 面试高频考点 ⚠️ 4.99 / 4.75 / 4.65

load average 三个数字指过去 1 分钟、5 分钟、15 分钟的平均负载。 含义是:等待 CPU + 等待 IO 的进程数。你的值 4.99 意味着平均有 5 个进程排队等资源。如果机器是 4 核,那已经饱和了。

💡 面试技巧:load > CPU 核心数 → CPU 瓶颈;load 高但 CPU us 低 → IO 瓶颈。

第二行:进程统计
复制代码
任务:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
字段 含义
total 总计进程/线程
running 正在 CPU 上跑
sleeping 在等事件(网络 IO、定时器等)
stopped 被信号暂停
zombie 僵尸进程,不为 0 就要查

第三行:CPU 分解 ⭐ 最重要
复制代码
%Cpu(s):  0.0 us,  1.6 sy,  0.0 ni, 98.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

这是瓶颈区分的核心依据:

缩写 全称 含义 告警阈值
us user 用户态 CPU(你的业务代码) > 80% → 代码死循环/计算密集
sy system 内核态 CPU(系统调用) > 30% → 频繁 IO/锁竞争
ni nice 低优先级进程的 CPU 通常忽略
id idle 空闲 接近 100% = 没事
wa iowait 等磁盘 IO 的 CPU 时间 > 10% → 磁盘瓶颈
hi hardware irq 硬件中断 通常 < 1%
si software irq 软中断(网络包处理) > 5% → 网络包太多
st steal 虚拟机被宿主机偷走的 CPU 云主机关注,> 5% 不正常

你的当前状态: us=0.0, id=98.4 → CPU 几乎空闲,还没触发故障。

故障触发后你会看到: us=99.0+, id=0.0 → 用户态代码吃满 CPU,典型死循环。

记忆口诀:

复制代码
us 高 = 代码有 bug(死循环、复杂计算)
sy 高 = 系统调用太多(频繁 IO、锁)
wa 高 = 磁盘慢(数据库、日志写盘)
si 高 = 网络包太多(DDoS、广播风暴)

第四、五行:内存
复制代码
MiB Mem :   3876.0 total,    112.2 free,   2192.3 used,   1571.5 buff/cache
MiB Swap:   2048.0 total,   2045.5 free,      2.5 used.   1408.1 avail Mem
字段 含义 你的值
total 总内存 3.8 GB
free 完全空闲 112 MB(看着少但正常)
used 已用 2.2 GB
buff/cache Linux 用空闲内存做文件缓存,可随时释放 1.5 GB
avail Mem 实际可用 = free + 可释放的 cache 1.4 GB ✅
Swap used 用了多少交换分区 2.5 MB(几乎没用,好事)

💡 free 低别紧张,看 available。 Linux 会尽可能把空闲内存用作文件缓存,这是正常的。只有 available 持续下降才说明内存不够。


🎯 排查时你只需要看这三个
text 复制代码
排查 CPU 问题  → 看 %Cpu 那行:us 高 = 代码问题,sy 高 = 系统调用
排查 IO 问题   → 看 %Cpu 那行:wa 高 = 等磁盘
排查内存问题  → 看 Mem 那行:available 持续下降 = 内存泄漏
排查负载      → 看 load average:超过 CPU 核数 = 系统过载
二、查看哪个进程cpu占用

使用top

看出是skynet的一个进程

接着查看skynet是谁

复制代码
cat /proc/{PID}/cmdline | tr '\0' ' '

PID填写top查询到的异常进程id

确定是battle进程有问题

bash 复制代码
# 对 battle 进程采样 10 秒,看 CPU 时间花在哪里
sudo perf top -p 8999

看收集结果,cpu全在跑lua解释器

由于我的linux无法使用pstack,为了不折腾环境,就是用gdb

bash 复制代码
# gdb 是 pstack 的底层,直接用它看 Lua 调用栈
sudo gdb -p $(pgrep -f "battle" | head -1) -batch -ex "thread apply all bt" 2>/dev/null | grep -A 5 "lua"

输出中找包含 luaD_precall 或 luaV_execute 的栈帧,附近会有关键线索。

但实际还是看不出来

于是就必须开启debug_console来查证问题

bash 复制代码
dbgcmd 10 TASK

但遇到问题,使用dbgcmd指令会在cpu暴涨时卡住无法使用,我试了下再正常情况,是能正常输出.

dbgcmd 10 TASK 没输出意味着:match_mgr 已经彻底卡死,拒绝处理任何消息------包括调试命令。

💡 核心学习点:Skynet 的死循环服务 = 彻底失联。dbgcmd、inject、TASK 都走 skynet.call,服务必须在消息循环中才能响应。死循环 = 消息循环被卡住 = 所有 debug 命令超时。

我后续的解决方案就是引入metrics模块,监控rpc组件哪个操作耗时非常高,就直接定位。暂时没有找到其他查证手段。

相关推荐
笨鸟先飞的橘猫8 天前
skynet——RPC 超时机制优化方案
游戏·rpc·skynet
笨鸟先飞的橘猫8 天前
skynet热更新实现问题与排错记录
学习·lua·skynet
笨鸟先飞的橘猫3 个月前
skynet——上下文管理
skynet
笨鸟先飞的橘猫3 个月前
skynet——网络模块学习
网络·学习·skynet
笨鸟先飞的橘猫4 个月前
skynet——sharetable学习
学习·skynet
笨鸟先飞的橘猫4 个月前
skynet——分布式支持
分布式·skynet
笨鸟先飞的橘猫4 个月前
skynet监控实践
监控·skynet
Huanzhi_Lin5 个月前
skynet笔记
笔记·lua·skynet·actor·actor模型
笨鸟先飞的橘猫6 个月前
MMO游戏中的“跨服团队副本”匹配与状态同步系统
分布式·学习·游戏·lua·skynet