| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- #!/usr/bin/env python3
- """
- LQAdminPlatform 服务启动脚本
- 用于启动 FastAPI 应用服务器
- """
- import sys
- import os
- import socket
- import logging
- # 添加项目根目录到Python路径
- current_dir = os.path.dirname(os.path.abspath(__file__))
- project_root = os.path.dirname(current_dir)
- sys.path.insert(0, project_root)
- # 导入配置
- from src.app.core.config import config_handler
- def check_port(host: str, port: int) -> bool:
- """
- 检查端口是否可用
-
- Args:
- host: 主机地址
- port: 端口号
-
- Returns:
- bool: 端口可用返回True,否则返回False
- """
- with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
- try:
- s.bind((host, port))
- return True
- except OSError:
- return False
- def find_available_port(host: str, start_port: int = 8000, max_port: int = 8010) -> int:
- """
- 查找可用端口
-
- Args:
- host: 主机地址
- start_port: 起始端口
- max_port: 最大端口
-
- Returns:
- int: 可用端口号,如果没有找到返回None
- """
- for port in range(start_port, max_port + 1):
- if check_port(host, port):
- return port
- return None
- def main():
- """主函数:启动服务器"""
- import uvicorn
-
- # 配置日志
- logging.basicConfig(
- level=logging.INFO,
- format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
- )
- logger = logging.getLogger(__name__)
-
- # 获取配置
- host = config_handler.get("admin_app", "HOST", "0.0.0.0")
- port = config_handler.get_int("admin_app", "PORT", 8000)
- reload = config_handler.get_bool("admin_app", "RELOAD", True)
- debug = config_handler.get_bool("admin_app", "DEBUG", True)
-
- # 检查端口是否可用
- if not check_port(host, port):
- logger.warning(f"⚠️ 端口 {port} 已被占用,正在查找可用端口...")
- available_port = find_available_port(host, port, port + 10)
- if available_port:
- port = available_port
- logger.info(f"✅ 找到可用端口: {port}")
- else:
- logger.error(f"❌ 未找到可用端口 (尝试范围: {port}-{port+10})")
- logger.error("请检查是否有其他服务占用了端口,或手动指定其他端口")
- sys.exit(1)
-
- # 打印启动信息
- logger.info("=" * 70)
- logger.info(f"🚀 正在启动 {config_handler.get('admin_app', 'APP_NAME', '后台管理')} v{config_handler.get('admin_app', 'APP_VERSION', '1.0.0')}")
- logger.info("=" * 70)
- logger.info(f"📍 服务地址: http://{host}:{port}")
- logger.info(f"📚 API文档: http://{host}:{port}/docs")
- logger.info(f"📖 ReDoc文档: http://{host}:{port}/redoc")
- logger.info(f"🔧 调试模式: {'开启' if debug else '关闭'}")
- logger.info(f"🔄 热重载: {'开启' if reload else '关闭'}")
- logger.info("=" * 70)
-
- # 启动服务器
- try:
- uvicorn.run(
- "src.app.server.app:app",
- host=host,
- port=port,
- reload=reload,
- log_level=config_handler.get("admin_app", "LOG_LEVEL", "INFO").lower(),
- access_log=True,
- use_colors=True
- )
- except KeyboardInterrupt:
- logger.info("\n👋 服务已停止")
- except Exception as e:
- logger.error(f"❌ 服务启动失败: {e}", exc_info=True)
- sys.exit(1)
- if __name__ == "__main__":
- main()
|