优化重启环境功能

This commit is contained in:
jingrow 2025-11-02 13:41:12 +08:00
parent f36d41550c
commit ba8d366237

View File

@ -294,37 +294,55 @@ async def restart_environment(request: Request):
is_production = str(getattr(settings, "environment", "development")).lower() == "production"
reload_enabled = (not is_production) and bool(getattr(settings, "backend_reload", True))
# 最佳实践:开发环境优先使用 reload生产环境使用命令重启
if reload_enabled:
# 开发模式:通过修改被监控的 Python 文件时间戳来触发 uvicorn reload
# 这是最快、最轻量的方式,不需要重启整个进程
try:
# 获取当前文件路径system.py 在 reload_dir 中)
current_file = Path(__file__)
# 修改文件时间戳来触发 uvicorn 的文件变化检测
# 这会触发 uvicorn 的自动重启
current_time = os.path.getmtime(current_file)
# touch 文件:更新访问和修改时间
# 修改文件时间戳触发 uvicorn 的文件变化检测,自动重启
os.utime(current_file, (current_time + 1, current_time + 1))
logger.info(f"已通过修改文件时间戳触发 uvicorn reload系统将在稍后自动重启")
logger.info("已通过文件时间戳触发 uvicorn reload系统将在稍后自动重启")
return # 成功则直接返回
except Exception as e:
logger.error(f"通过文件时间戳触发重启失败: {str(e)}")
# 回退到信号方式
try:
current_pid = os.getpid()
os.kill(current_pid, signal.SIGTERM)
logger.info("已发送重启信号")
except Exception as sig_error:
logger.error(f"发送重启信号也失败: {str(sig_error)}")
else:
# 生产模式:发送信号
logger.warning(f"通过文件时间戳触发重启失败: {str(e)},将尝试命令重启")
# 回退方案:使用命令重启(更可靠,适用于生产环境或 reload 失败时)
try:
import subprocess
from jingrow.utils.path import get_root_path
root_path = get_root_path()
dev_script = root_path / "dev.sh"
if dev_script.exists():
# 只重启后端,不重启前端
# 在后台执行,避免阻塞
subprocess.Popen(
["bash", str(dev_script), "backend"],
cwd=str(root_path),
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
start_new_session=True # 在新会话中运行,避免被父进程关闭
)
logger.info("已执行后端重启命令")
else:
# 如果 dev.sh 不存在,尝试直接重启当前进程
logger.warning("未找到 dev.sh 脚本,尝试发送重启信号")
current_pid = os.getpid()
os.kill(current_pid, signal.SIGTERM)
logger.info("已发送重启信号")
except Exception as e:
logger.error(f"命令重启失败: {str(e)}")
# 最后的回退:发送信号
try:
current_pid = os.getpid()
os.kill(current_pid, signal.SIGTERM)
logger.info("生产模式:已发送重启信号")
except Exception as e:
logger.error(f"发送重启信号失败: {str(e)}")
logger.warning("无法通过信号重启,请手动重启服务")
logger.info("已发送重启信号(最后回退方案)")
except Exception as sig_error:
logger.error(f"所有重启方式都失败: {str(sig_error)}")
logger.warning("无法自动重启,请手动重启服务")
# 启动后台任务
asyncio.create_task(delayed_restart())