sycommon-python-lib 0.1.46__py3-none-any.whl → 0.1.56b5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sycommon/config/Config.py +6 -2
- sycommon/config/RerankerConfig.py +1 -0
- sycommon/database/async_base_db_service.py +36 -0
- sycommon/database/async_database_service.py +96 -0
- sycommon/llm/__init__.py +0 -0
- sycommon/llm/embedding.py +149 -0
- sycommon/llm/get_llm.py +246 -0
- sycommon/llm/llm_logger.py +126 -0
- sycommon/llm/llm_tokens.py +119 -0
- sycommon/logging/async_sql_logger.py +65 -0
- sycommon/logging/kafka_log.py +21 -9
- sycommon/logging/logger_levels.py +23 -0
- sycommon/middleware/context.py +2 -0
- sycommon/middleware/traceid.py +155 -32
- sycommon/notice/__init__.py +0 -0
- sycommon/notice/uvicorn_monitor.py +195 -0
- sycommon/rabbitmq/rabbitmq_client.py +144 -152
- sycommon/rabbitmq/rabbitmq_pool.py +213 -479
- sycommon/rabbitmq/rabbitmq_service.py +77 -127
- sycommon/services.py +78 -75
- sycommon/synacos/feign.py +18 -7
- sycommon/synacos/feign_client.py +26 -8
- sycommon/synacos/nacos_service.py +18 -2
- sycommon/tools/merge_headers.py +97 -0
- sycommon/tools/snowflake.py +290 -23
- {sycommon_python_lib-0.1.46.dist-info → sycommon_python_lib-0.1.56b5.dist-info}/METADATA +15 -10
- {sycommon_python_lib-0.1.46.dist-info → sycommon_python_lib-0.1.56b5.dist-info}/RECORD +30 -18
- {sycommon_python_lib-0.1.46.dist-info → sycommon_python_lib-0.1.56b5.dist-info}/WHEEL +0 -0
- {sycommon_python_lib-0.1.46.dist-info → sycommon_python_lib-0.1.56b5.dist-info}/entry_points.txt +0 -0
- {sycommon_python_lib-0.1.46.dist-info → sycommon_python_lib-0.1.56b5.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import json
|
|
3
3
|
from typing import (
|
|
4
|
-
Callable, Coroutine, Dict, List, Optional, Type, Union, Any
|
|
4
|
+
Callable, Coroutine, Dict, List, Optional, Type, Union, Any
|
|
5
5
|
)
|
|
6
6
|
from pydantic import BaseModel
|
|
7
7
|
from aio_pika.abc import AbstractIncomingMessage, ConsumerTag
|
|
@@ -18,11 +18,11 @@ logger = SYLogger
|
|
|
18
18
|
|
|
19
19
|
class RabbitMQService:
|
|
20
20
|
"""
|
|
21
|
-
RabbitMQ
|
|
22
|
-
|
|
21
|
+
RabbitMQ服务封装,管理多个客户端实例(适配单通道连接池)
|
|
22
|
+
核心特性:基于单通道连接池复用资源,简化状态管理,依赖原生自动重连
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
|
-
#
|
|
25
|
+
# 保存多个客户端实例(共享单通道,仅维护配置差异)
|
|
26
26
|
_clients: Dict[str, RabbitMQClient] = {}
|
|
27
27
|
# 保存消息处理器
|
|
28
28
|
_message_handlers: Dict[str, Callable[[
|
|
@@ -37,8 +37,6 @@ class RabbitMQService:
|
|
|
37
37
|
_consumer_events: Dict[str, asyncio.Event] = {}
|
|
38
38
|
# 存储消费者标签
|
|
39
39
|
_consumer_tags: Dict[str, ConsumerTag] = {}
|
|
40
|
-
# 跟踪已初始化的队列
|
|
41
|
-
_initialized_queues: Set[str] = set()
|
|
42
40
|
# 异步锁,确保初始化安全
|
|
43
41
|
_init_locks: Dict[str, asyncio.Lock] = {}
|
|
44
42
|
# 标记是否有监听器和发送器
|
|
@@ -46,7 +44,7 @@ class RabbitMQService:
|
|
|
46
44
|
_has_senders: bool = False
|
|
47
45
|
# 消费启动超时设置
|
|
48
46
|
CONSUMER_START_TIMEOUT = 30 # 30秒超时
|
|
49
|
-
#
|
|
47
|
+
# 连接池实例(单通道)
|
|
50
48
|
_connection_pool: Optional[RabbitMQConnectionPool] = None
|
|
51
49
|
# 服务关闭标记
|
|
52
50
|
_is_shutdown: bool = False
|
|
@@ -56,11 +54,10 @@ class RabbitMQService:
|
|
|
56
54
|
_connection_monitor_task: Optional[asyncio.Task] = None
|
|
57
55
|
# 重连配置
|
|
58
56
|
RECONNECT_INTERVAL = 15 # 重连基础间隔(秒)
|
|
59
|
-
MAX_RECONNECT_ATTEMPTS = 10 # 最大连续重连次数
|
|
60
57
|
|
|
61
58
|
@classmethod
|
|
62
59
|
def init(cls, config: dict, has_listeners: bool = False, has_senders: bool = False) -> Type['RabbitMQService']:
|
|
63
|
-
"""初始化RabbitMQ
|
|
60
|
+
"""初始化RabbitMQ服务(支持集群配置),同时创建单通道连接池"""
|
|
64
61
|
from sycommon.synacos.nacos_service import NacosService
|
|
65
62
|
|
|
66
63
|
# 防止重复初始化
|
|
@@ -98,7 +95,7 @@ class RabbitMQService:
|
|
|
98
95
|
|
|
99
96
|
@classmethod
|
|
100
97
|
async def _init_connection_pool(cls):
|
|
101
|
-
"""
|
|
98
|
+
"""初始化单通道连接池(异步操作,带重试)"""
|
|
102
99
|
if cls._connection_pool or not cls._config or cls._is_shutdown:
|
|
103
100
|
return
|
|
104
101
|
|
|
@@ -112,7 +109,7 @@ class RabbitMQService:
|
|
|
112
109
|
|
|
113
110
|
global_prefetch_count = cls._config.get('prefetch_count', 2)
|
|
114
111
|
|
|
115
|
-
#
|
|
112
|
+
# 创建单通道连接池(已移除channel_pool_size参数)
|
|
116
113
|
cls._connection_pool = RabbitMQConnectionPool(
|
|
117
114
|
hosts=hosts_list,
|
|
118
115
|
port=cls._config.get('port', 5672),
|
|
@@ -121,11 +118,14 @@ class RabbitMQService:
|
|
|
121
118
|
virtualhost=cls._config.get('virtual-host', "/"),
|
|
122
119
|
app_name=cls._config.get("APP_NAME", ""),
|
|
123
120
|
prefetch_count=global_prefetch_count,
|
|
121
|
+
heartbeat=cls._config.get('heartbeat', 30),
|
|
122
|
+
connection_timeout=cls._config.get('connection_timeout', 30),
|
|
123
|
+
reconnect_interval=cls._config.get('reconnect_interval', 5),
|
|
124
124
|
)
|
|
125
125
|
|
|
126
126
|
# 初始化连接池
|
|
127
127
|
await asyncio.wait_for(cls._connection_pool.init_pools(), timeout=30)
|
|
128
|
-
logger.info("RabbitMQ
|
|
128
|
+
logger.info("RabbitMQ单通道连接池初始化成功")
|
|
129
129
|
|
|
130
130
|
except Exception as e:
|
|
131
131
|
logger.error(f"RabbitMQ连接池初始化失败: {str(e)}", exc_info=True)
|
|
@@ -136,7 +136,7 @@ class RabbitMQService:
|
|
|
136
136
|
|
|
137
137
|
@classmethod
|
|
138
138
|
async def _monitor_connections(cls):
|
|
139
|
-
"""
|
|
139
|
+
"""连接监控任务:定期检查所有客户端连接状态,依赖连接池原生重连"""
|
|
140
140
|
logger.info("RabbitMQ连接监控任务启动")
|
|
141
141
|
while not cls._is_shutdown:
|
|
142
142
|
try:
|
|
@@ -146,40 +146,25 @@ class RabbitMQService:
|
|
|
146
146
|
if not cls._connection_pool or not cls._connection_pool._initialized:
|
|
147
147
|
continue
|
|
148
148
|
|
|
149
|
-
#
|
|
150
|
-
|
|
149
|
+
# 检查连接池本身状态
|
|
150
|
+
pool_alive = await cls._connection_pool.is_alive
|
|
151
|
+
if not pool_alive:
|
|
152
|
+
logger.error("RabbitMQ连接池已断开,等待原生自动重连")
|
|
153
|
+
continue
|
|
154
|
+
|
|
155
|
+
# 检查所有客户端连接(单通道场景下,客户端状态依赖通道有效性)
|
|
151
156
|
for client_name, client in list(cls._clients.items()):
|
|
152
157
|
try:
|
|
153
|
-
# 双重校验连接状态(客户端内部校验 + 连接池连接校验)
|
|
154
158
|
client_connected = await client.is_connected
|
|
155
|
-
|
|
156
|
-
client._channel_conn and client._channel_conn.is_closed)
|
|
157
|
-
|
|
158
|
-
if not client_connected or not conn_connected:
|
|
159
|
+
if not client_connected:
|
|
159
160
|
logger.warning(
|
|
160
|
-
f"客户端 '{client_name}'
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
# 重连前先清理无效资源
|
|
165
|
-
await cls._clean_client_resources(client)
|
|
166
|
-
|
|
167
|
-
# 执行重连(带重试)
|
|
168
|
-
reconnect_success = await cls._reconnect_client(client_name, client)
|
|
169
|
-
if reconnect_success:
|
|
170
|
-
logger.info(f"客户端 '{client_name}' 重连成功")
|
|
171
|
-
else:
|
|
172
|
-
logger.error(f"客户端 '{client_name}' 重连失败,将继续监控")
|
|
173
|
-
|
|
161
|
+
f"客户端 '{client_name}' 连接异常,触发重连")
|
|
162
|
+
asyncio.create_task(
|
|
163
|
+
cls._reconnect_client(client_name, client))
|
|
174
164
|
except Exception as e:
|
|
175
165
|
logger.error(
|
|
176
166
|
f"监控客户端 '{client_name}' 连接状态失败: {str(e)}", exc_info=True)
|
|
177
167
|
|
|
178
|
-
# 检查连接池状态(如果连接池已关闭,重新初始化)
|
|
179
|
-
if not await cls._connection_pool.is_alive:
|
|
180
|
-
logger.error("RabbitMQ连接池已关闭,尝试重新初始化")
|
|
181
|
-
asyncio.create_task(cls._init_connection_pool())
|
|
182
|
-
|
|
183
168
|
except Exception as e:
|
|
184
169
|
logger.error("RabbitMQ连接监控任务异常", exc_info=True)
|
|
185
170
|
await asyncio.sleep(cls.RECONNECT_INTERVAL) # 异常后延迟重启监控
|
|
@@ -188,19 +173,16 @@ class RabbitMQService:
|
|
|
188
173
|
|
|
189
174
|
@classmethod
|
|
190
175
|
async def _clean_client_resources(cls, client: RabbitMQClient):
|
|
191
|
-
"""
|
|
176
|
+
"""清理客户端无效资源(单通道场景下仅重置状态,无需归还通道)"""
|
|
192
177
|
try:
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
# 释放通道到连接池
|
|
198
|
-
await cls._connection_pool.release_channel(client._channel, client._channel_conn)
|
|
199
|
-
logger.debug("客户端无效资源释放成功")
|
|
178
|
+
# 先停止消费(避免消费中操作资源)
|
|
179
|
+
if client._consumer_tag:
|
|
180
|
+
await client.stop_consuming()
|
|
181
|
+
logger.debug("客户端无效资源清理完成(单通道无需归还)")
|
|
200
182
|
except Exception as e:
|
|
201
183
|
logger.warning(f"释放客户端无效资源失败: {str(e)}")
|
|
202
184
|
finally:
|
|
203
|
-
#
|
|
185
|
+
# 强制重置客户端状态(通道由连接池自动恢复)
|
|
204
186
|
client._channel = None
|
|
205
187
|
client._channel_conn = None
|
|
206
188
|
client._exchange = None
|
|
@@ -209,48 +191,38 @@ class RabbitMQService:
|
|
|
209
191
|
|
|
210
192
|
@classmethod
|
|
211
193
|
async def _reconnect_client(cls, client_name: str, client: RabbitMQClient) -> bool:
|
|
212
|
-
"""
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
await asyncio.sleep(cooldown)
|
|
194
|
+
"""客户端重连(依赖连接池原生重连,仅重建客户端资源)"""
|
|
195
|
+
if cls._is_shutdown or not await cls._connection_pool.is_alive:
|
|
196
|
+
return False
|
|
216
197
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
# 执行重连
|
|
220
|
-
await client.connect()
|
|
198
|
+
# 重连冷却
|
|
199
|
+
await asyncio.sleep(cls.RECONNECT_INTERVAL)
|
|
221
200
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if client_name in cls._message_handlers:
|
|
226
|
-
# 先停止旧的消费任务
|
|
227
|
-
if client_name in cls._consumer_tasks:
|
|
228
|
-
old_task = cls._consumer_tasks[client_name]
|
|
229
|
-
if not old_task.done():
|
|
230
|
-
old_task.cancel()
|
|
231
|
-
try:
|
|
232
|
-
await asyncio.wait_for(old_task, timeout=5)
|
|
233
|
-
except:
|
|
234
|
-
pass
|
|
235
|
-
# 启动新的消费任务
|
|
236
|
-
await cls.start_consumer(client_name)
|
|
237
|
-
return True
|
|
238
|
-
else:
|
|
239
|
-
logger.warning(
|
|
240
|
-
f"客户端 '{client_name}' 重连尝试 {attempt+1} 失败:资源未完全初始化")
|
|
241
|
-
except Exception as e:
|
|
242
|
-
logger.error(
|
|
243
|
-
f"客户端 '{client_name}' 重连尝试 {attempt+1} 失败: {str(e)}", exc_info=True)
|
|
201
|
+
try:
|
|
202
|
+
# 清理旧资源
|
|
203
|
+
await cls._clean_client_resources(client)
|
|
244
204
|
|
|
245
|
-
|
|
205
|
+
# 执行重连(客户端内部会从连接池获取新通道)
|
|
206
|
+
await client.connect()
|
|
246
207
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
208
|
+
# 验证重连结果
|
|
209
|
+
if await client.is_connected:
|
|
210
|
+
logger.info(f"客户端 '{client_name}' 重连成功")
|
|
211
|
+
# 如果是消费者,重新启动消费
|
|
212
|
+
if client_name in cls._message_handlers:
|
|
213
|
+
await cls.start_consumer(client_name)
|
|
214
|
+
return True
|
|
215
|
+
else:
|
|
216
|
+
logger.warning(f"客户端 '{client_name}' 重连失败:资源未完全初始化")
|
|
217
|
+
return False
|
|
218
|
+
except Exception as e:
|
|
219
|
+
logger.error(f"客户端 '{client_name}' 重连失败: {str(e)}", exc_info=True)
|
|
220
|
+
# 重连失败后,由监控任务再次触发(避免死循环)
|
|
221
|
+
return False
|
|
250
222
|
|
|
251
223
|
@classmethod
|
|
252
224
|
async def _create_client(cls, queue_name: str, **kwargs) -> RabbitMQClient:
|
|
253
|
-
"""
|
|
225
|
+
"""创建客户端实例(适配单通道连接池的RabbitMQClient)"""
|
|
254
226
|
if cls._is_shutdown:
|
|
255
227
|
raise RuntimeError("RabbitMQService已关闭,无法创建客户端")
|
|
256
228
|
|
|
@@ -285,7 +257,7 @@ class RabbitMQService:
|
|
|
285
257
|
f"允许创建: {create_if_not_exists}"
|
|
286
258
|
)
|
|
287
259
|
|
|
288
|
-
#
|
|
260
|
+
# 创建客户端实例(适配精简版RabbitMQClient参数)
|
|
289
261
|
client = RabbitMQClient(
|
|
290
262
|
connection_pool=cls._connection_pool,
|
|
291
263
|
exchange_name=cls._config.get(
|
|
@@ -301,15 +273,9 @@ class RabbitMQService:
|
|
|
301
273
|
prefetch_count=kwargs.get('prefetch_count', 2),
|
|
302
274
|
)
|
|
303
275
|
|
|
304
|
-
#
|
|
276
|
+
# 连接客户端(单通道场景下快速连接)
|
|
305
277
|
await client.connect()
|
|
306
278
|
|
|
307
|
-
# 监听器客户端连接后延迟1秒,确保消费状态就绪(仅首次启动)
|
|
308
|
-
if not is_sender and create_if_not_exists:
|
|
309
|
-
logger.info(
|
|
310
|
-
f"监听器客户端 '{processed_queue_name}' 连接成功,延迟1秒启动消费(解决启动时序问题)")
|
|
311
|
-
await asyncio.sleep(1)
|
|
312
|
-
|
|
313
279
|
return client
|
|
314
280
|
|
|
315
281
|
@classmethod
|
|
@@ -317,7 +283,7 @@ class RabbitMQService:
|
|
|
317
283
|
cls,
|
|
318
284
|
client_name: str = "default", **kwargs
|
|
319
285
|
) -> RabbitMQClient:
|
|
320
|
-
"""获取或创建RabbitMQ
|
|
286
|
+
"""获取或创建RabbitMQ客户端(单通道池,线程安全)"""
|
|
321
287
|
if cls._is_shutdown:
|
|
322
288
|
raise RuntimeError("RabbitMQService已关闭,无法获取客户端")
|
|
323
289
|
|
|
@@ -353,7 +319,7 @@ class RabbitMQService:
|
|
|
353
319
|
await client.connect()
|
|
354
320
|
return client
|
|
355
321
|
else:
|
|
356
|
-
logger.info(f"客户端 '{client_name}'
|
|
322
|
+
logger.info(f"客户端 '{client_name}' 连接已断开,重新连接")
|
|
357
323
|
if not is_sender:
|
|
358
324
|
client.create_if_not_exists = True
|
|
359
325
|
await client.connect()
|
|
@@ -375,16 +341,9 @@ class RabbitMQService:
|
|
|
375
341
|
cls._clients[client_name] = client
|
|
376
342
|
return client
|
|
377
343
|
|
|
378
|
-
#
|
|
344
|
+
# 监听器逻辑(单通道支持多队列声明,无需跟踪已初始化队列)
|
|
379
345
|
kwargs['create_if_not_exists'] = True
|
|
380
346
|
|
|
381
|
-
# 检查队列是否已初始化
|
|
382
|
-
if initial_queue_name in cls._initialized_queues:
|
|
383
|
-
logger.info(f"队列 '{initial_queue_name}' 已初始化,直接创建客户端")
|
|
384
|
-
client = await cls._create_client(initial_queue_name, **kwargs)
|
|
385
|
-
cls._clients[client_name] = client
|
|
386
|
-
return client
|
|
387
|
-
|
|
388
347
|
# 创建并连接客户端
|
|
389
348
|
client = await cls._create_client(
|
|
390
349
|
initial_queue_name,
|
|
@@ -400,17 +359,12 @@ class RabbitMQService:
|
|
|
400
359
|
if not client._queue:
|
|
401
360
|
raise Exception(f"无法创建队列 '{initial_queue_name}'")
|
|
402
361
|
|
|
403
|
-
# 记录已初始化的队列
|
|
404
|
-
final_queue_name = client.queue_name
|
|
405
|
-
if final_queue_name:
|
|
406
|
-
cls._initialized_queues.add(final_queue_name)
|
|
407
|
-
|
|
408
362
|
cls._clients[client_name] = client
|
|
409
363
|
return client
|
|
410
364
|
|
|
411
365
|
@classmethod
|
|
412
366
|
async def setup_senders(cls, senders: List[RabbitMQSendConfig], has_listeners: bool = False, **kwargs) -> None:
|
|
413
|
-
"""
|
|
367
|
+
"""设置消息发送器(适配单通道客户端)"""
|
|
414
368
|
if cls._is_shutdown:
|
|
415
369
|
logger.warning("服务已关闭,无法设置发送器")
|
|
416
370
|
return
|
|
@@ -475,7 +429,7 @@ class RabbitMQService:
|
|
|
475
429
|
|
|
476
430
|
@classmethod
|
|
477
431
|
async def setup_listeners(cls, listeners: List[RabbitMQListenerConfig], has_senders: bool = False, **kwargs) -> None:
|
|
478
|
-
"""
|
|
432
|
+
"""设置消息监听器(适配单通道客户端)"""
|
|
479
433
|
if cls._is_shutdown:
|
|
480
434
|
logger.warning("服务已关闭,无法设置监听器")
|
|
481
435
|
return
|
|
@@ -544,7 +498,7 @@ class RabbitMQService:
|
|
|
544
498
|
queue_name: str,
|
|
545
499
|
handler: Callable[[MQMsgModel, AbstractIncomingMessage], Coroutine[Any, Any, None]], **kwargs
|
|
546
500
|
) -> None:
|
|
547
|
-
"""
|
|
501
|
+
"""添加消息监听器(线程安全,单通道场景)"""
|
|
548
502
|
if cls._is_shutdown:
|
|
549
503
|
logger.warning("服务已关闭,无法添加监听器")
|
|
550
504
|
return
|
|
@@ -569,7 +523,7 @@ class RabbitMQService:
|
|
|
569
523
|
|
|
570
524
|
@classmethod
|
|
571
525
|
async def start_all_consumers(cls) -> None:
|
|
572
|
-
"""
|
|
526
|
+
"""启动所有已注册的消费者(单通道场景,避免阻塞)"""
|
|
573
527
|
if cls._is_shutdown:
|
|
574
528
|
logger.warning("服务已关闭,无法启动消费者")
|
|
575
529
|
return
|
|
@@ -579,7 +533,7 @@ class RabbitMQService:
|
|
|
579
533
|
|
|
580
534
|
@classmethod
|
|
581
535
|
async def start_consumer(cls, client_name: str) -> None:
|
|
582
|
-
"""
|
|
536
|
+
"""启动指定客户端的消费者(单通道消费,需确保回调非阻塞)"""
|
|
583
537
|
if cls._is_shutdown:
|
|
584
538
|
logger.warning("服务已关闭,无法启动消费者")
|
|
585
539
|
return
|
|
@@ -622,20 +576,15 @@ class RabbitMQService:
|
|
|
622
576
|
if cls._is_shutdown:
|
|
623
577
|
return
|
|
624
578
|
|
|
625
|
-
# 监听器启动消费前额外延迟1秒
|
|
626
|
-
if cls._has_listeners and not client_name.startswith("sender-"):
|
|
627
|
-
logger.info(f"消费者 '{client_name}' 准备启动,延迟1秒等待消费状态就绪")
|
|
628
|
-
await asyncio.sleep(1)
|
|
629
|
-
|
|
630
579
|
# 创建停止事件
|
|
631
580
|
stop_event = asyncio.Event()
|
|
632
581
|
cls._consumer_events[client_name] = stop_event
|
|
633
582
|
|
|
634
|
-
#
|
|
583
|
+
# 定义消费任务(单通道场景下,消费回调需非阻塞)
|
|
635
584
|
async def consume_task():
|
|
636
585
|
try:
|
|
637
586
|
# 启动消费,带重试机制
|
|
638
|
-
max_attempts =
|
|
587
|
+
max_attempts = 3
|
|
639
588
|
attempt = 0
|
|
640
589
|
consumer_tag = None
|
|
641
590
|
|
|
@@ -671,7 +620,9 @@ class RabbitMQService:
|
|
|
671
620
|
# 记录消费者标签
|
|
672
621
|
cls._consumer_tags[client_name] = consumer_tag
|
|
673
622
|
logger.info(
|
|
674
|
-
f"消费者 '{client_name}'
|
|
623
|
+
f"消费者 '{client_name}' 开始消费(单通道),tag: {consumer_tag},"
|
|
624
|
+
f"注意:消费回调需非阻塞,避免影响其他客户端"
|
|
625
|
+
)
|
|
675
626
|
|
|
676
627
|
# 等待停止事件
|
|
677
628
|
await stop_event.wait()
|
|
@@ -731,7 +682,7 @@ class RabbitMQService:
|
|
|
731
682
|
|
|
732
683
|
@classmethod
|
|
733
684
|
async def get_sender(cls, queue_name: str) -> Optional[RabbitMQClient]:
|
|
734
|
-
"""
|
|
685
|
+
"""获取发送客户端(适配单通道池)"""
|
|
735
686
|
if cls._is_shutdown:
|
|
736
687
|
logger.warning("服务已关闭,无法获取发送器")
|
|
737
688
|
return None
|
|
@@ -781,7 +732,7 @@ class RabbitMQService:
|
|
|
781
732
|
data: Union[BaseModel, str, Dict[str, Any], None],
|
|
782
733
|
queue_name: str, **kwargs
|
|
783
734
|
) -> None:
|
|
784
|
-
"""
|
|
735
|
+
"""发送消息到指定队列(单通道场景下快速发送)"""
|
|
785
736
|
if cls._is_shutdown:
|
|
786
737
|
raise RuntimeError("RabbitMQService已关闭,无法发送消息")
|
|
787
738
|
|
|
@@ -853,7 +804,7 @@ class RabbitMQService:
|
|
|
853
804
|
).model_dump_json()
|
|
854
805
|
}
|
|
855
806
|
|
|
856
|
-
#
|
|
807
|
+
# 发送消息(单通道场景下依赖原生异步确认)
|
|
857
808
|
await sender.publish(
|
|
858
809
|
message_body=mq_message.model_dump_json(),
|
|
859
810
|
headers=mq_header,
|
|
@@ -866,7 +817,7 @@ class RabbitMQService:
|
|
|
866
817
|
|
|
867
818
|
@classmethod
|
|
868
819
|
async def shutdown(cls, timeout: float = 15.0) -> None:
|
|
869
|
-
"""
|
|
820
|
+
"""优雅关闭所有资源(单通道场景下简化关闭流程)"""
|
|
870
821
|
async with cls._shutdown_lock:
|
|
871
822
|
if cls._is_shutdown:
|
|
872
823
|
logger.info("RabbitMQService已关闭,无需重复操作")
|
|
@@ -898,18 +849,18 @@ class RabbitMQService:
|
|
|
898
849
|
except Exception as e:
|
|
899
850
|
logger.error(f"关闭消费者 '{client_name}' 失败: {str(e)}")
|
|
900
851
|
|
|
901
|
-
# 3.
|
|
852
|
+
# 3. 关闭所有客户端(单通道场景下客户端关闭仅清理状态)
|
|
902
853
|
for client in cls._clients.values():
|
|
903
854
|
try:
|
|
904
855
|
await client.close()
|
|
905
856
|
except Exception as e:
|
|
906
857
|
logger.error(f"关闭客户端失败: {str(e)}")
|
|
907
858
|
|
|
908
|
-
# 4.
|
|
859
|
+
# 4. 关闭连接池(单通道池关闭会释放所有资源)
|
|
909
860
|
if cls._connection_pool and cls._connection_pool._initialized:
|
|
910
861
|
try:
|
|
911
862
|
await cls._connection_pool.close()
|
|
912
|
-
logger.info("RabbitMQ
|
|
863
|
+
logger.info("RabbitMQ单通道连接池已关闭")
|
|
913
864
|
except Exception as e:
|
|
914
865
|
logger.error(f"关闭连接池失败: {str(e)}")
|
|
915
866
|
|
|
@@ -919,7 +870,6 @@ class RabbitMQService:
|
|
|
919
870
|
cls._consumer_tasks.clear()
|
|
920
871
|
cls._consumer_events.clear()
|
|
921
872
|
cls._consumer_tags.clear()
|
|
922
|
-
cls._initialized_queues.clear()
|
|
923
873
|
cls._sender_client_names.clear()
|
|
924
874
|
cls._init_locks.clear()
|
|
925
875
|
cls._config = None
|