# 端口管理指南 ## 端口占用问题说明 ### 常见原因 1. **进程未完全退出** - 使用 `Ctrl+C` 后进程可能仍在后台运行 - 子进程没有被正确清理 2. **TCP TIME_WAIT 状态** - TCP连接关闭后会进入 TIME_WAIT 状态 - 通常持续 30-120 秒 - 这是 TCP 协议的正常行为 3. **多个实例运行** - 启动了多个程序实例 - 没有正确关闭之前的实例 ## 解决方案 ### 方法1: 使用提供的脚本(推荐) ```bash # 清理7860端口 ./kill_port.sh 7860 # 或清理其他端口 ./kill_port.sh 8000 ``` ### 方法2: 手动清理 #### 查找占用端口的进程 ```bash # 方法1: 使用 lsof sudo lsof -i:7860 # 方法2: 使用 netstat sudo netstat -tlnp | grep 7860 # 方法3: 使用 ss sudo ss -tlnp | grep 7860 # 方法4: 使用 fuser sudo fuser 7860/tcp ``` #### 杀死进程 ```bash # 如果知道进程ID (PID) kill -9 # 一行命令清理端口 sudo lsof -ti:7860 | xargs kill -9 # 或使用 fuser sudo fuser -k 7860/tcp ``` ### 方法3: 使用改进后的 app.py 新版本的 `app.py` 已经实现了: 1. **端口复用** (`SO_REUSEADDR` 和 `SO_REUSEPORT`) - 避免 "Address already in use" 错误 - 允许快速重启服务 2. **信号处理** - 捕获 `SIGINT` (Ctrl+C) 和 `SIGTERM` 信号 - 优雅关闭服务器,释放端口 3. **自动端口清理** - 启动时检查端口占用 - 尝试自动清理占用的进程 ## 预防措施 ### 1. 正确停止服务器 ```bash # 使用 Ctrl+C 停止 # 程序会捕获信号并优雅退出 # 或发送 SIGTERM 信号 kill -15 ``` ### 2. 使用进程管理器 #### systemd(生产环境推荐) ```bash # 创建 systemd 服务文件 sudo nano /etc/systemd/system/learning-app.service ``` ```ini [Unit] Description=Interactive Learning App After=network.target [Service] Type=simple User=zhangl WorkingDirectory=/data/zhangl/code/hf/point ExecStart=/usr/bin/python3 /data/zhangl/code/hf/point/app.py Restart=on-failure KillMode=mixed KillSignal=SIGTERM TimeoutStopSec=5 [Install] WantedBy=multi-user.target ``` ```bash # 启用并启动服务 sudo systemctl daemon-reload sudo systemctl enable learning-app sudo systemctl start learning-app # 管理服务 sudo systemctl stop learning-app # 停止 sudo systemctl restart learning-app # 重启 sudo systemctl status learning-app # 查看状态 ``` #### supervisor(备选方案) ```ini [program:learning-app] directory=/data/zhangl/code/hf/point command=python3 app.py autostart=true autorestart=true user=zhangl redirect_stderr=true stdout_logfile=/var/log/learning-app.log stopasgroup=true killasgroup=true ``` ### 3. 使用虚拟终端 ```bash # 使用 screen screen -S learning-app python3 app.py # 按 Ctrl+A 然后 D 分离会话 # 重新连接 screen -r learning-app # 使用 tmux tmux new -s learning-app python3 app.py # 按 Ctrl+B 然后 D 分离会话 # 重新连接 tmux attach -t learning-app ``` ## 常用命令汇总 ```bash # 查看所有监听的端口 sudo netstat -tlnp # 查看所有Python进程 ps aux | grep python # 查看特定用户的进程 ps aux | grep zhangl # 杀死所有Python进程(危险!) # pkill -9 python3 # 查看端口连接状态 sudo netstat -an | grep 7860 # 测试端口是否可访问 nc -zv localhost 7860 telnet localhost 7860 ``` ## 故障排除 ### 问题1: 端口仍被占用 ```bash # 使用 root 权限清理 sudo lsof -ti:7860 | xargs sudo kill -9 # 或重启网络服务 sudo systemctl restart networking ``` ### 问题2: Permission denied ```bash # 确保脚本有执行权限 chmod +x kill_port.sh # 使用 sudo 运行 sudo ./kill_port.sh 7860 ``` ### 问题3: 找不到占用进程 ```bash # 可能是僵尸进程,尝试 sudo kill -9 $(ps aux | grep 'defunct' | awk '{print $2}') # 或重启系统(最后手段) sudo reboot ``` ## 监控端口使用 ```bash # 实时监控端口 watch -n 1 'sudo lsof -i:7860' # 记录端口使用日志 while true; do echo "$(date): $(sudo lsof -i:7860 | wc -l) connections" sleep 5 done >> port_monitor.log ``` ## 参考资料 - [TCP TIME_WAIT 状态详解](https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_termination) - [SO_REUSEADDR vs SO_REUSEPORT](https://stackoverflow.com/questions/14388706/how-do-so-reuseaddr-and-so-reuseport-differ) - [Linux 信号处理](https://man7.org/linux/man-pages/man7/signal.7.html)