程序出问题怎么查,以及如何让它不掉线

上一篇把程序跑起来了,但好日子没几天。第一天你 ssh 进去想看一眼,结果什么都没有,程序不知道什么时候挂了。第二天终于跑住了,你一关终端窗口,它又没了。服务器上的程序活得像个需要人盯着的孩子,问题就出在你对「进程、日志、端口、终端」这几件事没有完整的认识。这篇把排查和保活一起讲透,学完你的程序才真正算「部署完成」。

问题来了,先搞清楚程序还活着没

判断程序生死,靠的是 ps 这个查看进程的命令。aux 三个字母的组合表示显示所有进程的完整信息,

bash 复制代码
ps aux | grep python

grep python 是从输出里筛选关键词。看到一行包含你程序名的记录,说明它还活着,第二列的数字是它的进程号(PID),后面排查和杀进程都要用到。什么都没有,说明已经退出了。

还有一种「活着但没反应」的状态,程序进程在,但服务没响应。这种时候就不该再看进程了,往下走,看日志和端口。

病根基本都在日志里

程序把运行情况写进日志文件,这是排查的第一现场。实时跟踪日志输出,

bash 复制代码
tail -f 你的日志文件路径

-f 表示持续跟踪,新写入的内容会实时滚出来。看完按 Ctrl+C 退出跟踪。

按惯例讲,日志不是垃圾信息,崩溃前最后几行往往直接写着原因。最常见的两种,没找到文件,路径配置错;连不上外部服务,数据库或 API 的地址、端口不对。大多数程序挂掉,根因就藏在这几行里。

顺带提一句,服务器的资源情况也值得瞄一眼,

bash 复制代码
free -h    # 看内存
df -h      # 看磁盘

程序突然「不知道为什么崩了」,很多时候是内存被吃满或者磁盘写满了。你想想看,程序一崩就去看代码,但资源和日志往往先于代码暴露真相。这两个命令的输出是即时的,内存看 free -h 的 available 列,磁盘看 df -h 的 Use% 列,超过 90% 就该动手清理了。先看资源再看代码,很多玄学问题当场就破了案。

端口被占,web 服务的老事故

如果你的程序要对外提供服务,会监听一个端口。端口被占用是 web 类应用的经典事故,比如你昨天部署的另一个服务还占着 8000,新程序自然起不来,报错可能是「Address already in use」也可能是别的,反正看日志不一定能一眼看出来。

查看本机端口监听情况,

bash 复制代码
ss -tlnp

ss 是查看网络连接的命令,-t 只看 TCP,-l 只看监听中的,-n 显示数字端口,-p 显示占用进程。看到目标端口后面跟着别的程序名,就是它把路堵了。

三件套到此就齐了,ps 看进程、tail 看日志、ss 看端口。它们针对的是三类不同的问题,进程不在了是程序崩溃,进程在但服务没反应是内部错误或资源耗尽,端口被占是新起的服务起不来。记住了这个对应关系,排查就不会像无头苍蝇。

排查铁律,先确认问题类型,再选对应工具。进程、日志、端口,三类问题三件工具,别用错方向。

杀掉僵住的进程

程序僵住了,比如卡在死循环里,这时候的诉求从「查」变成「杀」。还是用前面学的,找到进程号再动手,

bash 复制代码
ps aux | grep 你的程序

kill 进程号        # 正常终止
kill -9 进程号     # 强制杀掉,最后手段

kill 默认发温和的终止信号,给了程序善后时间。-9 是强制击杀,用于前面那招无效的情况。注意别把 PID 搞错,杀错进程是新手最容易犯的事故。

让程序脱离你的终端

回到开头那个问题,程序明明起来了,一关 SSH 窗口就消失。原因是终端关闭时,系统会给这个终端下的所有进程发一个挂断信号(SIGHUP),进程收到信号就默认退出了。

逃出这个限制有两个手段,

bash 复制代码
python main.py &          # 后台运行

nohup python main.py &    # 后台运行 + 忽略挂断信号

& 把进程丢到后台,nohup 让进程无视终端的关闭信号。配合日志重定向,程序就彻底脱离了你的终端,

bash 复制代码
nohup python main.py > app.log 2>&1 &

这条命令的每一个零件都值得记住,> 是输出重定向,2>&1 表示把报错也一并写进日志,末尾的 & 是后台运行。之后不管终端怎么关,程序照跑,日志都进 app.log

但 nohup 有个短板,它只管「不死」,不管「想不想让它休」。程序占着前台,你想再进服务器做点别的事都难,更别说回头再看一眼程序界面。想要重新看到程序舍不得放的输出,得靠 tmux。

tmux,把整个终端会话托管起来

tmux(terminal multiplexer,终端复用器)是跑在服务器上的一个守护进程,它把你打开的终端窗口托管起来,即使 SSH 连接断开,窗口和里面跑的程序依旧留在服务器上。

区别在哪,nohup 是「让程序活下来」,tmux 是「让整个终端会话活下来」。其实这俩不冲突,只是解决两个不同层面的问题。前者你只能靠日志确认程序状态,后者你可以随时再连回去,重新看到那个界面,继续跟程序交互。

终端会话与进程存活是两件事,tmux 管的是前者,nohup 管的是后者。

Ubuntu 20.04 之后基本都自带 tmux,没有就一条命令安装,

bash 复制代码
sudo apt install -y tmux

tmux 的日常操作只有三个,新建会话、离开会话、回到会话。

bash 复制代码
tmux new -s myapp

python main.py

-s myapp 是给会话起名,之后按名字找它。程序开始在会话里跑起来后,按 Ctrl+B 再按 D,脱离会话。这是 tmux 的核心操作,先按组合键,松开,再按 D,不要一起按。

此时你又回到了普通 SSH 命令行,但程序还在那个会话里继续跑。下次登录服务器,随时回到会话,

bash 复制代码
tmux attach -t myapp

程序的原界面立刻出现在你眼前,就跟从未离开过一样。不再需要了,先 attach 进去退出程序,或直接删会话,

bash 复制代码
tmux kill-session -t myapp

会话活着的时候,里面还有几个高频操作值得记下。

快捷键 作用
Ctrl+B 然后 D 脱离会话,程序继续跑
Ctrl+B 然后 C 在会话里开一个新终端窗口
Ctrl+B 然后 N 切换到下一个窗口
Ctrl+B 然后 0-9 直接跳到对应编号的窗口

打开多个窗口这个能力很实用。一个窗口跑程序盯日志,另一个窗口继续敲命令操作服务器,互不干扰,这是纯 nohup 方案给不了的自由度。

坦率讲,tmux 适合「手工挂机」场景,但有一类需求它管不了。服务器重启、程序崩溃自动拉起、开机自启,这些 tmux 都做不到,那是 systemd 的领域。

维度 tmux systemd
本质 终端会话托管 系统服务管理
适配场景 手动挂机、开发调试 生产服务、开机自启
崩溃自动重启 不行 可以
学习成本 低,一篇学会 较高,要写配置

判断标准很简单,自己手动跑着玩的工具用 tmux。要 7x24 对外提供服务、机器重启后要自动恢复的,去学 systemd 服务文件。

生产级的路还有多远

两篇的路走到这里收个尾。回头看全套流程,买的是一台永远在线的电脑,进出靠 SSH,文件靠 tar 和 scp,环境靠 venv 和镜像源,出问题靠 ps、tail、ss 三件套,保活靠 nohup 和 tmux。每一步解决的其实都是同一件事,让程序离开你的电脑也能可靠运行。

  • 进程不在了查 ps,服务没反应查 tail,端口被占查 ss,先分型再动手
  • free 和 df 瞄一眼资源,很多玄学崩溃当场破案
  • nohup 让进程活,tmux 让会话活,两者搭配各司其职
  • tmux 三连,new 建会话、attach 回会话、kill 删会话,Ctrl+B 是总开关
  • 要崩溃自动拉起、开机自启,从 systemd 入门开始

再往下进阶的方向也给你列好。域名解析与 Nginx 反向代理,让服务有名字、走 80/443 端口;crontab 定时任务,让服务器到点自动干活;systemd 服务化,把生产级保活讲透。服务器这扇门已经推开了,剩下的路走得越深越好玩。

相关推荐
论迹复利23 分钟前
FreeRTOS 在 RISC-V 上是如何“点火“的 —— 从 main() 到第一个任务的完整链路
java·开发语言·risc-v
张宇Joaquin43 分钟前
鲲鹏统一并行加速库KUPL--众核并行能力介绍
java·开发语言·网络
宸津-代码粉碎机1 小时前
AI攻防战升级!基于Spring AI构建Java应用自动免疫安全体系
java·大数据·开发语言·人工智能·python·安全·spring
倔强的石头_1 小时前
连接数失控排查:从数据库会话、应用线程池到连接池泄漏
数据库
爱喝水的鱼丶2 小时前
SAP-ABAP:ABAP 用户出口开发规范与避坑指南:10 类典型错误与运维方案
运维·性能优化·sap·abap·增强·经验交流·出口
hzxpaipai2 小时前
企业官网技术架构拆解:前端、后台、数据库、服务器如何协同
前端·数据库·架构
博、、2 小时前
从零构建智慧场馆解决方案:架构设计与开发实践
大数据·运维
敢敢是只喵i2 小时前
给现有业务系统接 AI 助手,入口怎么选?网页聊天、自动化任务与本地 Agent 对比
运维·人工智能·ai·开源·自动化·安全架构
2601_963749102 小时前
越华环保集团数字化污水治理:端边云采集架构与平台对接实现
java·大数据·架构
xcLeigh3 小时前
Go入门:整数类型的溢出与安全边界
java·安全·golang