Spaces:
Running
Running
| # 端口管理指南 | |
| ## 端口占用问题说明 | |
| ### 常见原因 | |
| 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 <PID> | |
| # 一行命令清理端口 | |
| 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 <PID> | |
| ``` | |
| ### 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) | |