Files
DjangoAdmin_Tornado_EleVue/src/bootstrap.py
T
gitadmin fda0fe1a53
CI / lint (push) Canceled after 0s
CI / test (push) Canceled after 0s
签入版本
2026-09-16 10:08:07 +08:00

118 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# +======================================================================
# | 模块: 启动引导层
# | 说明: 解析命令行参数、创建应用并启动 HTTP 服务,
# | 注册信号处理实现优雅关闭
# +======================================================================
"""启动引导程序。
- 解析命令行参数(--port)
- 创建应用并启动 HTTP 服务
- 注册信号处理实现优雅关闭
"""
# ----------------------------------------------------------------------
# 导入依赖
# 涵盖:信号处理、Tornado HTTP 服务与事件循环、命令行参数工具、
# 应用/数据库/邮件/Redis 配置、日志器
# ----------------------------------------------------------------------
import signal
import tornado.httpserver
import tornado.ioloop
from tornado.options import define, options, parse_command_line
from config.app import TORNADO_ENV, TORNADO_HOST, TORNADO_NAME, TORNADO_PORT
from config.database import DB_PASSWORD
from config.email import MAIL_PASSWORD
from config.redis import REDIS_PASSWORD
from core.logger import logger
# ============================================================
# 命令行参数定义
# ============================================================
define('port', default=TORNADO_PORT, help='run on the given port', type=int)
# ======================================================================
# 启动 Banner
# ======================================================================
_BANNER = r"""
____ _ _
| _ \ _ _ __ _ _ __ ___ (_) _ __ __ _ _ __ __| |
| | | || | | | / _` || '__| / __|| || '_ \ / _` || '__| / _` |
| |_| || |_| || (_| || | | (__ | || |_) || (_| || | | (_| |
|____/ \__,_| \__,_||_| \___||_|| .__/ \__,_||_| \__,_|
|_|
Tornado + EleVue 企业级管理框架
"""
# ======================================================================
# 启动服务
# ======================================================================
def main():
"""启动服务。"""
# 延迟导入应用工厂,避免与根目录入口模块同名冲突
from app import create_app
# 打印启动 Banner
print(_BANNER)
parse_command_line()
app = create_app()
# 预热 ip2region 离线库,避免首个日志落库时在事件循环上加载阻塞
try:
from common.utils.ip2region import preload
preload()
except Exception:
logger.warning("ip2region 预热失败(将延迟到首次查询时加载)")
# 生产环境安全提醒(签名密钥已在 config.auth 启动校验中 fail-close;此处对其它
# 敏感凭据做软告警,提示确认来源,不阻断启动)
if TORNADO_ENV.strip().lower() == "production":
for name, value in (("DB_PASSWORD", DB_PASSWORD),
("REDIS_PASSWORD", REDIS_PASSWORD),
("MAIL_PASSWORD", MAIL_PASSWORD)):
if not value:
logger.warning("生产环境检测到 %s 为空,请确认凭据来源(环境变量 / 密钥管理服务)", name)
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
# 启动任务调度器并加载运行中任务
from modules.job.scheduler import init_scheduler
init_scheduler()
logger.info("服务启动成功 → http://%s:%s", TORNADO_HOST, options.port)
ioloop = tornado.ioloop.IOLoop.current()
# ============================================================
# 优雅关闭回调
# ============================================================
def _shutdown():
"""收到退出信号时关闭调度器并停止事件循环。"""
logger.info("收到退出信号,正在优雅关闭...")
from modules.job.scheduler import shutdown_scheduler
shutdown_scheduler()
ioloop.stop()
# ============================================================
# 注册信号处理(优雅关闭)
# ============================================================
for sig in (signal.SIGINT, signal.SIGTERM):
try:
signal.signal(sig, lambda s, f: ioloop.add_callback_from_signal(_shutdown))
except (ValueError, AttributeError, OSError):
pass
ioloop.start()
# ======================================================================
# 入口
# ======================================================================
if __name__ == '__main__':
main()