1
1
#!/usr/bin/env python3
2
2
"""
3
3
生产环境启动脚本
4
- 支持高并发部署
5
4
"""
6
5
7
6
import os
8
7
import sys
9
8
import socket
9
+ import signal
10
+ import uvicorn
10
11
from pathlib import Path
11
12
12
13
# 添加项目根目录到Python路径
@@ -33,10 +34,22 @@ def get_local_ip():
33
34
return "127.0.0.1"
34
35
35
36
37
+ def signal_handler (signum , frame ):
38
+ """信号处理器"""
39
+ logger .info (f"收到信号 { signum } ,正在优雅关闭服务..." )
40
+ sys .exit (0 )
41
+
42
+
36
43
def main ():
37
44
"""主函数"""
45
+ # 注册信号处理器
46
+ signal .signal (signal .SIGINT , signal_handler )
47
+ signal .signal (signal .SIGTERM , signal_handler )
48
+
38
49
try :
39
- logger .info (f"生产环境服务启动中,监听地址: { settings .host } :{ settings .port } " )
50
+ logger .info (
51
+ f"生产环境服务启动中(Uvicorn),监听地址: { settings .host } :{ settings .port } "
52
+ )
40
53
print ("=" * 60 )
41
54
local_ip = get_local_ip ()
42
55
print (
@@ -45,46 +58,21 @@ def main():
45
58
)
46
59
print ("=" * 60 )
47
60
48
- # 使用gunicorn启动,支持高并发
49
- import gunicorn .app .base
50
-
51
- class StandaloneApplication (gunicorn .app .base .BaseApplication ):
52
- def __init__ (self , app , options = None ):
53
- self .options = options or {}
54
- self .application = app
55
- super ().__init__ ()
56
-
57
- def load_config (self ):
58
- config = {
59
- key : value
60
- for key , value in self .options .items ()
61
- if key in self .cfg .settings and value is not None
62
- }
63
- for key , value in config .items ():
64
- self .cfg .set (key .lower (), value )
65
-
66
- def load (self ):
67
- return self .application
68
-
69
- options = {
70
- "bind" : f"{ settings .host } :{ settings .port } " ,
71
- "workers" : 1 , # 单进程模式,避免模型重复加载
72
- "worker_class" : "uvicorn.workers.UvicornWorker" , # 使用UvicornWorker支持ASGI
73
- "worker_connections" : 1000 , # 每个worker的连接数
74
- "max_requests" : 1000 , # 每个worker处理的最大请求数
75
- "max_requests_jitter" : 100 , # 随机抖动,避免同时重启
76
- "timeout" : 120 , # 请求超时时间
77
- "keepalive" : 2 , # keep-alive连接数
78
- "preload_app" : True , # 预加载应用
79
- "access_log_format" : '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(D)s' ,
80
- "accesslog" : "-" , # 访问日志输出到stdout
81
- "errorlog" : "-" , # 错误日志输出到stderr
82
- "loglevel" : "info" ,
83
- }
84
-
85
- from app .application import app
86
-
87
- StandaloneApplication (app , options ).run ()
61
+ # 使用Uvicorn启动,配置优化
62
+ uvicorn .run (
63
+ "app.application:app" ,
64
+ host = settings .host ,
65
+ port = settings .port ,
66
+ reload = False , # 生产环境关闭热重载
67
+ workers = 1 , # 单进程模式,避免模型重复加载
68
+ access_log = True , # 开启访问日志
69
+ log_level = "info" ,
70
+ timeout_keep_alive = 30 , # keep-alive超时
71
+ timeout_graceful_shutdown = 300 , # 优雅关闭超时
72
+ limit_concurrency = 1000 , # 并发连接限制
73
+ limit_max_requests = 1000 , # 最大请求数限制
74
+ backlog = 2048 , # 连接队列大小
75
+ )
88
76
89
77
except KeyboardInterrupt :
90
78
logger .info ("收到中断信号,正在退出服务。" )
0 commit comments