Skip to content

Commit 6bed8dd

Browse files
committed
update:优化
1 parent 1ba8ad8 commit 6bed8dd

File tree

3 files changed

+44
-60
lines changed

3 files changed

+44
-60
lines changed

app/services/voiceprint_service.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import time
44
import psutil
55
import os
6+
import threading
67
from typing import Dict, List, Tuple, Optional
78
from modelscope.pipelines import pipeline
89
from modelscope.utils.constant import Tasks
@@ -20,6 +21,7 @@ class VoiceprintService:
2021
def __init__(self):
2122
self._pipeline = None
2223
self.similarity_threshold = settings.similarity_threshold
24+
self._pipeline_lock = threading.Lock() # 添加线程锁
2325
self._init_pipeline()
2426

2527
def _init_pipeline(self) -> None:
@@ -100,11 +102,18 @@ def extract_voiceprint(self, audio_path: str) -> np.ndarray:
100102
self._log_system_resources("推理前")
101103

102104
try:
103-
pipeline_start = time.time()
104-
logger.info("开始模型推理...")
105-
result = self._pipeline([audio_path], output_emb=True)
106-
pipeline_time = time.time() - pipeline_start
107-
logger.info(f"模型推理完成,耗时: {pipeline_time:.3f}秒")
105+
# 使用线程锁确保模型推理的线程安全
106+
with self._pipeline_lock:
107+
pipeline_start = time.time()
108+
logger.info("开始模型推理...")
109+
110+
# 检查pipeline是否可用
111+
if self._pipeline is None:
112+
raise RuntimeError("声纹模型未初始化")
113+
114+
result = self._pipeline([audio_path], output_emb=True)
115+
pipeline_time = time.time() - pipeline_start
116+
logger.info(f"模型推理完成,耗时: {pipeline_time:.3f}秒")
108117

109118
# 记录推理后系统资源
110119
self._log_system_resources("推理后")

requirements.txt

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,4 @@ uvicorn==0.29.0
1414
PyMySQL==1.1.0
1515
python-multipart==0.0.9
1616
librosa==0.10.1
17-
18-
# 高并发支持
19-
gunicorn==21.2.0
20-
gevent==23.9.1
21-
greenlet==3.0.3
22-
23-
# 性能优化
24-
orjson==3.9.10
25-
ujson==5.8.0
26-
27-
# 监控和日志
28-
prometheus-client==0.19.0
29-
structlog==23.2.0
3017
psutil==5.9.8

start_server.py

Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
#!/usr/bin/env python3
22
"""
33
生产环境启动脚本
4-
支持高并发部署
54
"""
65

76
import os
87
import sys
98
import socket
9+
import signal
10+
import uvicorn
1011
from pathlib import Path
1112

1213
# 添加项目根目录到Python路径
@@ -33,10 +34,22 @@ def get_local_ip():
3334
return "127.0.0.1"
3435

3536

37+
def signal_handler(signum, frame):
38+
"""信号处理器"""
39+
logger.info(f"收到信号 {signum},正在优雅关闭服务...")
40+
sys.exit(0)
41+
42+
3643
def main():
3744
"""主函数"""
45+
# 注册信号处理器
46+
signal.signal(signal.SIGINT, signal_handler)
47+
signal.signal(signal.SIGTERM, signal_handler)
48+
3849
try:
39-
logger.info(f"生产环境服务启动中,监听地址: {settings.host}:{settings.port}")
50+
logger.info(
51+
f"生产环境服务启动中(Uvicorn),监听地址: {settings.host}:{settings.port}"
52+
)
4053
print("=" * 60)
4154
local_ip = get_local_ip()
4255
print(
@@ -45,46 +58,21 @@ def main():
4558
)
4659
print("=" * 60)
4760

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+
)
8876

8977
except KeyboardInterrupt:
9078
logger.info("收到中断信号,正在退出服务。")

0 commit comments

Comments
 (0)