This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
# +======================================================================
|
||||
# | 模块: 启动引导层
|
||||
# | 说明: 解析命令行参数、创建应用并启动 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()
|
||||
Reference in New Issue
Block a user