优化重启环境功能
This commit is contained in:
parent
f36d41550c
commit
ba8d366237
@ -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())
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user