Linux 用户登录时间与高占用后台进程处理
太阳作者太阳
原创内容采用 CC-4.0 协议发布,转载请注明出处
Linux进程systemd运维

Linux 用户登录时间与高占用后台进程处理

背景

这次服务器上占用资源较高的是另一个本地用户启动的后台进程。处理目标不是马上强杀,而是先确认这个用户是否还在使用机器,再判断进程是不是由服务管理器托管,最后停止服务并关闭自启。

定位高占用进程

先用 ps 查目标进程的所属用户、PID、父进程、运行时间和资源占用。真正需要处理的是某个用户级后台进程,CPU 占用明显高于同组的其他进程。

ps -eo user,pid,ppid,stat,etime,%cpu,%mem,cmd | grep -E 'PROCESS_KEYWORD' | grep -v grep

同机还存在其他相关进程,但它们当时资源占用很低,不是本次要处理的目标。

确认用户最近登录时间

目标用户最近一次登录发生在较早之前,且登录持续时间很短。

last -F TARGET_USER | head

这说明该用户不是最近通过终端持续使用这个进程。

再用 lastlog 复核,最后登录时间与 last 的记录一致。

lastlog -u TARGET_USER

确认当前是否有人在线

w 显示当前没有登录用户。结合上面的登录记录,可以判断目标用户当前没有在线使用这个进程。

w TARGET_USER

确认进程来源

目标进程的父进程是该用户的 /lib/systemd/systemd --user。这说明它不是一个普通临时命令,而是用户级 systemd 管理的后台服务。

ps -u TARGET_USER -o pid,ppid,stat,etime,%cpu,%mem,cmd --sort=-%cpu | head -30

loginctl user-status 进一步确认了对应的用户级 systemd 服务名。同时该用户启用了 linger,所以即使用户没有登录,user systemd 也可以在后台运行服务。

loginctl user-status TARGET_USER

停止服务

因为进程来自用户级 systemd,优先用 systemctl --user stop 停服务,而不是直接 kill -9

这里需要指定目标用户的 XDG_RUNTIME_DIR,否则从其他用户或 sudo 环境里操作 user systemd 时,可能找不到正确的用户运行时目录。

sudo -u TARGET_USER XDG_RUNTIME_DIR=/run/user/TARGET_UID systemctl --user stop SERVICE_NAME

停止后再查一次进程,确认目标进程已经退出:

ps -eo user,pid,ppid,stat,etime,%cpu,%mem,cmd | grep -E 'PROCESS_KEYWORD' | grep -v grep

关闭开机自启

停止服务只影响当前运行状态。如果不关闭 enable,机器重启后它仍可能再次启动。

关闭这个服务的用户级自启:

sudo -u TARGET_USER XDG_RUNTIME_DIR=/run/user/TARGET_UID systemctl --user disable SERVICE_NAME

确认是否关闭:

sudo -u TARGET_USER XDG_RUNTIME_DIR=/run/user/TARGET_UID systemctl --user is-enabled SERVICE_NAME

如果输出是 disabled,说明该用户级服务的自启已经关闭。

可选:关闭 linger

目标用户当前是 Linger=yes。这表示用户退出登录后,系统仍允许该用户的 user systemd 常驻运行。

如果确认目标用户不需要任何后台用户服务,可以关闭 linger:

sudo loginctl disable-linger TARGET_USER

这一步影响的是目标用户的所有 user systemd 后台服务,不只是本次处理的单个服务。如果只想关闭这一个服务,执行 systemctl --user disable SERVICE_NAME 就够了。

结论

这次不是直接杀进程的问题,而是另一个本地用户下的 user systemd 服务在后台运行:

  • 高占用进程来自另一个本地用户的后台服务。
  • 目标用户当前没有在线登录。
  • 该进程由用户级 systemd 管理。
  • 该用户启用了 linger,因此服务可以在用户退出后继续运行。

正确处理顺序是:确认用户不在线,确认服务来源,停止对应的用户级服务,再 disable 这个用户级服务的自启。只有服务命令不可用时,才考虑用 kill 作为兜底。