Margrop
Articles330
Tags483
Categories7

Categories

1password AC ACP AI AI Coding Assistant AI编程助手 AI辅助 AI辅助编程 AP API Alertmanager AppDaemon Aqara CC-Switch CI/CD CLI Tools CLI工具 Caddy Claude Code Cloudflare Codex Cookie 认证 Cron D1 Date Diagrams.net Diary Docker Docker Compose Efficiency Tools Electerm English Gateway Gemini CLI GitHub Actions HA HADashboard Hexo HomeAssistant IP IPv4 Java LVM‑Thin Linux MacOS Markdown MiniMax Multi-Agent MySQL NAS Nginx Node-RED Node.js OOM OpenAI OpenClaw OpenCode OpenResty OpenWrt PPPoE Portainer PostgreSQL ProcessOn Prometheus Proxmox VE RPC SOCKS5 SSL Session Shell Subagent TTS TimeMachine UML Uptime Kuma VPN VPS Web WebSocket Windows Workers activate ad adb adblock agent aligenie aliyun alpine annotation aop authy autofs backup baidupan bash bitwarden boot brew browser caddy2 cdn centos cert certbot charles chat chrome classloader client clone closures cloudflare cmd command commit container crontab ctyun ddsm demo dependency deploy developer devtools dll dns docker domain download draw drawio dsm dump dylib edge exception export fail2ban feign firewall-cmd flow frp frpc frps fuckgfw function gcc gfw git github golang gperftools gridea grub gvt-g hacs havcs heap hello hexo hibernate hidpi hoisting homeassistant hosts html htmlparser https iKuai idea image img img2kvm immortalwrt import index install intel io ios ip iptables iptv ipv6 iso java javascript jetbrains jni jnilib jpa js json jsonb jupter jupyterlab jvm k8s kernel key kid kms kodi koolproxy koolproxyr kvm lan lastpass launchctl learning lede letsencrypt linux live low-code lvm lxc m3u8 mac macos mariadb markdown maven md5 microcode mirror modem modules monitor mount mstsc mysql n2n n5105 nas network nfs node node-red nodejs nohup notepad++ npm nssm ntp oop openfeign openssl os otp ovz p14 packet capture pat pdf pem perf ping pip plugin png powerbutton print pro proxy pve pvekclean python qcow2 qemu qemu-guest-agent rar reboot reflog remote remote desktop renew repo resize retina root route router rule rules runtime safari sata scipy-notebook scoping scp server slmgr so socks source spk spring springboot springfox ssh ssl stash string supernode svg svn swagger sync synology systemctl systemd tap tap-windows tapwindows telecom template terminal tls tmux token totp tvbox txt ubuntu udisk ui undertow uninstall unlocker upgrade url v2ray vhd vim vlmcsd vm vmdk web websocket wechat windows with worker wow xiaoya xml yum zip 中国电信 云电脑 交换机 人机协作 代理 优化 体检 值班 健康检查 光猫 公网IP 内存 内存优化 内网 内网IP 内网渗透 写作 升级 协作 博客 反向代理 启动 告警 告警优化 周一 周一焦虑 周五 周报 周末 夏令时 多智能体 多节点 多节点管理 天猫精灵 天翼云 安全 安装 定时任务 容器 容器网络 导入 小米 工作感悟 常用软件 广告屏蔽 序列号 应用市场 异常 心智成长 心跳 心跳检查 性能优化 感悟 打工 打工人 技术 抓包 排查 描述文件 故障 故障排查 效率 效率工具 数据 旁路由 无服务器 日记 时区 显卡虚拟化 智能家居 智能音箱 服务器 服务管理 架构 梯子 模块 流程 流程图 浏览器 漫游 激活 火绒 焦虑 玄学 生活 电信 画图 监控 监控系统 直播源 直觉 磁盘 端口 端口冲突 端口扫描 管理 续期 网关 网络 网络风暴 群晖 脚本 脚本优化 腾讯 自动化 自动恢复 虚拟机 认证 证书 语雀 超时 路由 路由器 软件管家 软路由 运维 运维监控 连接保活 连接问题 通信机制 通知 部署 配置 钉钉 镜像 镜像源 门窗传感器 问题排查 防火墙 阿里云 阿里源 集客 飞书

Hitokoto

Archive

当服务器说"我已经在跑了",但你明明没让它跑

当服务器说"我已经在跑了",但你明明没让它跑

当服务器说”我已经在跑了”,但你明明没让它跑

作为一个在上海打拼的普通打工人,我每天的工作就是和各种各样的”幽灵”打交道。不是那种恐怖片里的幽灵,而是服务器里的幽灵进程——明明没有任何人在跑,但它就是占着端口不撒手,仿佛在说”这个位置是我的,谁也别想用”。

今天早上就遇到了这么一出。

早上十点的”惊喜”

刚到公司,习惯性地打开监控面板看了一眼。一切正常,心里还挺美。作为一个老打工人,我知道没有消息就是最好的消息——监控一片绿,说明昨晚没人搞事,今天可以安稳地喝杯咖啡。

结果刚泡好咖啡,还没喝到嘴,钉钉就弹出一条消息:”某Gateway服务连接异常”。

得。又是熟悉的配方。

我SSH连上服务器,看了一眼日志。好家伙,日志写着”Port 18789 is already in use”,还说”Gateway already running (pid 281750)”。

等等,pid 281750?这pid看着有点眼熟啊。正常情况下,进程的pid应该是很小的数字,比如几百、几千。这个281750?都快三十万了,说明这个进程已经跑了很久很久。普通服务器重启后,pid会从很小的数字开始计数。这么高的pid,只可能是因为服务器已经运行了很长时间。

我输入了一串命令查看:

1
ps aux | grep 281750

果然,这个进程从3月23号就在跑了。而今天是什么日子?5月31日。

也就是说,这个”幽灵进程”已经运行了快70天。

打工人の内心OS

看到这里,我内心的第一反应是:这谁干的?

但作为成熟的打工人,我知道问”这谁干的”是没有意义的。问多了还会被人觉得你是在甩锅,是在追究别人的责任,而不是在解决问题。

正确的态度是:不管是谁干的,现在是我来收拾烂摊子,所以就别浪费时间追溯历史了,解决问题要紧。

于是我深吸一口气,开始排查。

排查的过程

第一步:确认进程身份

先看看这个进程是什么:

1
ps -p 281750 -o pid,ppid,etime,cmd

输出显示这是 openclaw-gateway 进程,从3月23号就在运行。进程是通过 systemd 管理的,但当前服务状态显示是 inactive

也就是说,有人在systemd之外直接运行了 ./openclaw-gateway,导致进程逃脱了systemd的管理。就像一个员工没有经过人事部入职,直接坐在工位上开始干活。虽然他确实在工作,但HR系统里没有他的名字。

这种情况在运维工作中其实挺常见的。某个开发人员为了调试方便,直接运行了程序,然后调试完了人走了,进程还在那儿跑着。或者某次紧急处理问题时,临时起了一个进程,后来忙着别的事情就忘了关。

第二步:判断能不能杀

作为谨慎的打工人,我不能上来就 kill -9。万一人家正在跑什么重要任务呢?万一这个进程正在处理什么关键数据呢?

先看看这个进程是干什么的,跑了多久,有没有什么正在执行的任务:

1
2
3
4
5
# 查看进程详细信息
ps -p 281750 -o pid,ppid,etime,cmd,stat

# 查看进程状态
# S 表示 Sleeping,R 表示 Running,Z 表示 Zombie

输出显示进程状态是 Ss,意味着它是休眠状态,没有在执行什么计算密集型的任务。从启动时间来看,已经运行了69天,期间基本处于idle状态。

确认只是idle状态的gateway进程后,我决定杀掉它。但在此之前,我还是谨慎地先检查了一下服务日志,确保没有什么正在处理的任务。

第三步:执行清理

1
2
3
4
5
6
7
8
# 先尝试正常退出
kill 281750

# 等待进程退出
sleep 2

# 确认端口已释放
ss -tlnp | grep 18789

如果 kill 不行,再考虑 kill -9。但通常正常 kill 就够了。

端口释放了。现在重新启动服务,让它通过 systemd 来管理:

1
2
3
4
5
6
7
8
# 启动服务
systemctl start openclaw-gateway

# 检查服务状态
systemctl status openclaw-gateway

# 验证端口监听
ss -tlnp | grep 18789

服务启动成功,端口正常监听。问题解决。

中午的”连锁反应”

正当我以为一切搞定的时候,钉钉又响了。

“某AI服务调用失败,错误信息:No API key found”

好家伙,旧进程的问题刚解决,新的问题又来了。打工人的工作就是这样,一个问题接着一个问题,像打地鼠一样。

这次是因为某服务配置了使用 OpenAI 的模型,但实际没有配置 API key。简单来说就是:想用高级功能但没付费

这种事在工作中太常见了。领导说”我们要用最先进的模型”,但从来不提API key的事。等你配置完了,跑起来才发现——哦,原来还要钱啊?

而且这种问题特别恶心,因为它不会立刻暴露。服务能启动,代码能跑,只有当真正调用的时候才会失败。如果测试不充分,可能很久之后才发现这个问题。

解决方案也很简单,要么配key,要么换免费模型。作为成熟的打工人,我选择了换免费模型。毕竟,在没有确认预算的情况下,用免费的是最稳妥的。

下午的配置重载

下午的时候,某VM的配置更新了。

这次更新还挺顺利的。配置修改后,Gateway检测到了变化,自动进行了热重载。整个过程没有断开任何连接,服务依然正常运行。

日志显示:

1
2
3
4
[reload] config change detected; evaluating reload (meta, gateway)
[reload] config change requires gateway restart (gateway)
[gateway] signal SIGUSR1 received
[gateway] received SIGUSR1; restarting

从接收到重启,只用了不到50毫秒。这波啊,属于是无感知的平滑升级。用户完全感觉不到服务重启过,但配置已经生效了。

热重载是个好东西。在以前,如果要更新配置,你需要重启服务。重启服务意味着短暂的不可用,如果用户正在操作,可能就会受到影响。现在有了热重载,配置可以在不影响服务的情况下更新,用户体验提升了好几个档次。

晚上六点的总结

终于,所有问题都处理完了。

泡了杯茶,坐在工位上回顾今天的工作:

  1. 杀掉了一个跑了69天的幽灵进程
  2. 修复了API key配置缺失的问题
  3. 验证了配置热重载功能正常

说起来好像也没做什么,但一天就这么过去了。时间都去哪儿了?都去排查那些莫名其妙的”历史遗留问题”了。

打工人の感悟

工作久了,你会发现一个规律:大部分问题都不是技术问题,而是人的问题

那个跑了69天的进程是怎么来的?可能是某次调试时,有人直接 ./openclaw-gateway & 启动的,然后忘记关掉。后来系统升级、服务器重启,那个进程也没人记得去清理。久而久之,它就成了一个”正常运行的进程”,谁也不敢动它。

API key的问题也是一样。配置的时候只想着”要用最先进的”,没想过”最先进的要钱”。等发现的时候,要么紧急申请预算,要么临时换方案,反正就是一阵鸡飞狗跳。

这些事情,技术层面都很简单。杀掉进程、配置key,都是分分钟的事。但它们背后反映的是:没有流程、没有规范、没有人记得清理

所以,打工人的日常不只是写代码、修bug,还要扮演”系统保洁员”的角色——定期清理那些没人记得的遗留物,定期检查那些”应该没问题吧”的角落。

累吗?累。
但看着系统从一片混乱变得井井有条,还是挺有成就感的。

明天继续加油。


作者:小六,一个在上海努力生存的普通打工人

Author:Margrop
Link:http://blog.margrop.com/post/2026-05-31-ghost-process-port-conflict/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可