amqplib-init 1.2.4 → 1.3.0
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.
- package/CHANGELOG.md +101 -0
- package/README.md +44 -2
- package/dist/amqplib-init.cjs.js +1 -0
- package/dist/amqplib-init.cjs.js.map +1 -0
- package/dist/amqplib-init.esm.js +1 -0
- package/dist/amqplib-init.esm.js.map +1 -0
- package/dist/amqplib-init.umd.js +1 -0
- package/dist/amqplib-init.umd.js.map +1 -0
- package/index.d.ts +88 -0
- package/module/AutoReloader.js +12 -42
- package/module/ConfigResolver.js +0 -1
- package/module/ConnectionManager.js +40 -9
- package/module/MessageProcessor.js +27 -11
- package/package.json +40 -5
- package/demo.js +0 -5
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [1.3.0] - 2026-01-24
|
|
4
|
+
|
|
5
|
+
### 🔥 Breaking Changes
|
|
6
|
+
- **移除 PM2 依赖**: 不再支持 `pmId` 配置参数和自动 PM2 重启功能
|
|
7
|
+
- **移除 shelljs 依赖**: 不再需要 shelljs 包
|
|
8
|
+
|
|
9
|
+
### ✨ 新增功能
|
|
10
|
+
- **重连次数限制**: 实现 `maxReconnectAttempts` 配置,防止无限重连
|
|
11
|
+
- **消息超时处理**: 实现 `messageTimeout` 配置,超时自动 Reject
|
|
12
|
+
- **UMD/ESM 支持**: 支持 CommonJS (require) 和 ES Module (import)
|
|
13
|
+
- **TypeScript 支持**: 添加完整的类型定义文件
|
|
14
|
+
- **连接统计**: 新增 `getStats()` 方法获取连接统计信息
|
|
15
|
+
- **代码混淆压缩**: 使用 Terser 进行代码混淆和压缩,保护源码
|
|
16
|
+
|
|
17
|
+
### ✨ 改进
|
|
18
|
+
- **AutoReloader 模块优化**:
|
|
19
|
+
- 移除 `_executeReload()` 方法(PM2 重启逻辑)
|
|
20
|
+
- 重命名 `_checkAndReload()` 为 `_checkQueueStatus()`(仅监控,不重启)
|
|
21
|
+
- 移除 `pmId` 参数依赖
|
|
22
|
+
|
|
23
|
+
- **ConfigResolver 模块优化**:
|
|
24
|
+
- 移除默认配置中的 `pmId: 0`
|
|
25
|
+
|
|
26
|
+
- **ConnectionManager 模块优化**:
|
|
27
|
+
- 添加重连计数器和最大重连次数限制
|
|
28
|
+
- 改进重连日志,显示重连进度
|
|
29
|
+
- 新增 `getStats()` 方法
|
|
30
|
+
|
|
31
|
+
- **MessageProcessor 模块优化**:
|
|
32
|
+
- 使用 `Promise.race` 实现消息处理超时
|
|
33
|
+
- 改进超时错误日志
|
|
34
|
+
|
|
35
|
+
- **更清晰的日志**:
|
|
36
|
+
- 队列监控日志更加简洁明了
|
|
37
|
+
- 添加注释说明使用 Supervisor 管理服务
|
|
38
|
+
- 重连日志显示进度 (第 X/Y 次)
|
|
39
|
+
|
|
40
|
+
### 📝 迁移指南
|
|
41
|
+
|
|
42
|
+
#### 从 1.2.x 升级到 1.3.0
|
|
43
|
+
|
|
44
|
+
**旧代码 (使用 PM2):**
|
|
45
|
+
```javascript
|
|
46
|
+
amqplib.init({
|
|
47
|
+
amqpLink,
|
|
48
|
+
channelName,
|
|
49
|
+
prefetch: 10,
|
|
50
|
+
pmId: 123, // ❌ 不再支持
|
|
51
|
+
autoReload: 60000,
|
|
52
|
+
callback: (content) => { /* ... */ }
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**新代码 (使用 Supervisor):**
|
|
57
|
+
```javascript
|
|
58
|
+
amqplib.init({
|
|
59
|
+
amqpLink,
|
|
60
|
+
channelName,
|
|
61
|
+
prefetch: 10,
|
|
62
|
+
// pmId 参数已移除
|
|
63
|
+
autoReload: 60000, // 仅监控队列状态,不自动重启
|
|
64
|
+
callback: (content) => { /* ... */ }
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**服务管理:**
|
|
69
|
+
```bash
|
|
70
|
+
# 旧方式 (PM2)
|
|
71
|
+
pm2 reload <app-id>
|
|
72
|
+
|
|
73
|
+
# 新方式 (Supervisor)
|
|
74
|
+
supervisorctl restart <service-name>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 🎯 为什么移除 PM2?
|
|
78
|
+
|
|
79
|
+
1. **架构统一**: 项目已全面迁移到 Supervisor 管理所有服务
|
|
80
|
+
2. **简化依赖**: 减少不必要的依赖包(shelljs)
|
|
81
|
+
3. **更好的控制**: Supervisor 提供更强大的进程管理和监控能力
|
|
82
|
+
4. **避免冲突**: 防止 PM2 和 Supervisor 同时管理导致的问题
|
|
83
|
+
|
|
84
|
+
### 📦 依赖变更
|
|
85
|
+
|
|
86
|
+
**移除:**
|
|
87
|
+
- `shelljs: ^0.8.5`
|
|
88
|
+
|
|
89
|
+
**保留:**
|
|
90
|
+
- `amqplib: ^0.10.4`
|
|
91
|
+
- `axios: ^1.6.0`
|
|
92
|
+
- `chalk-style: ^1.0.3`
|
|
93
|
+
- `happy-help: ^1.0.1`
|
|
94
|
+
- `js-base64: ^3.7.7`
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## [1.2.4] - 之前版本
|
|
99
|
+
- 支持15分钟长任务
|
|
100
|
+
- 模块化架构
|
|
101
|
+
- 自动重连机制
|
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
- **错误处理** - 智能处理空消息和格式错误的消息,防止阻塞
|
|
12
12
|
- **自动重载** - 支持自动重载监控
|
|
13
13
|
- **配置灵活** - 支持多种配置方式和自动配置获取
|
|
14
|
+
- **代码保护** - 打包后代码经过混淆和压缩,保护源码安全
|
|
14
15
|
|
|
15
16
|
## 📦 安装
|
|
16
17
|
|
|
@@ -20,7 +21,7 @@ npm install amqplib-init
|
|
|
20
21
|
|
|
21
22
|
## 🔧 快速开始
|
|
22
23
|
|
|
23
|
-
###
|
|
24
|
+
### CommonJS (Node.js require)
|
|
24
25
|
|
|
25
26
|
```javascript
|
|
26
27
|
const { init } = require('amqplib-init');
|
|
@@ -31,12 +32,53 @@ await init({
|
|
|
31
32
|
amqpLink: 'amqp://localhost:5672',
|
|
32
33
|
callback: async (message) => {
|
|
33
34
|
console.log('收到消息:', message);
|
|
34
|
-
// 处理消息逻辑
|
|
35
35
|
await processMessage(message);
|
|
36
36
|
}
|
|
37
37
|
});
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
### ES Module (import)
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
import { init, AMQPInitializer } from 'amqplib-init';
|
|
44
|
+
|
|
45
|
+
// 方式1: 使用 init 函数
|
|
46
|
+
await init({
|
|
47
|
+
channelName: 'my-queue',
|
|
48
|
+
amqpLink: 'amqp://localhost:5672',
|
|
49
|
+
callback: async (message) => {
|
|
50
|
+
console.log('收到消息:', message);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// 方式2: 使用类实例
|
|
55
|
+
const initializer = new AMQPInitializer();
|
|
56
|
+
await initializer.init({
|
|
57
|
+
channelName: 'my-queue',
|
|
58
|
+
amqpLink: 'amqp://localhost:5672',
|
|
59
|
+
callback: async (message) => {
|
|
60
|
+
console.log('收到消息:', message);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### TypeScript
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { init, AmqplibInitOptions } from 'amqplib-init';
|
|
69
|
+
|
|
70
|
+
const options: AmqplibInitOptions = {
|
|
71
|
+
channelName: 'my-queue',
|
|
72
|
+
amqpLink: 'amqp://localhost:5672',
|
|
73
|
+
prefetch: 10,
|
|
74
|
+
callback: async (message: any) => {
|
|
75
|
+
console.log('收到消息:', message);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
await init(options);
|
|
80
|
+
```
|
|
81
|
+
|
|
40
82
|
### 高级用法
|
|
41
83
|
|
|
42
84
|
```javascript
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("axios"),t=require("chalk-style"),s=require("amqplib"),n=require("happy-help");function i(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}const o=e,a=t;var c=class{constructor(){this.defaultConfig={channelName:"node-test-channel",prefetch:1,callback:()=>{},finish:()=>{},amqpLink:"",amqpAutoLink:"",heartbeat:60,timeout:3e5,delay:0,autoReload:0,queryHook:()=>{},initHook:()=>{},durable:!0,messageTimeout:9e5,reconnectDelay:5e3,maxReconnectAttempts:10}}resolveConfig(e={}){return{...this.defaultConfig,...e}}async resolveAmqpLink(e,t){if(!e)return t;try{a.log(`正在从 ${e} 获取连接信息...`);const s=await o.post(e),{info:n}=s.data;if(this._validateConnectionInfo(n)){const e=`amqp://${n.AMQPLIB_USER}:${n.AMQPLIB_PWD}@${n.AMQPLIB_PUB}:${n.AMQPLIB_PORT}`;return a.log(`✅ 自动获取连接信息成功: ${e}`),e}return a.error("❌ 获取的连接信息不完整,使用默认连接地址"),t}catch(e){return a.error("❌ 获取连接信息失败:",e.message),a.log("使用默认连接地址继续..."),t}}_validateConnectionInfo(e){return e&&e.AMQPLIB_USER&&e.AMQPLIB_PWD&&e.AMQPLIB_PUB&&e.AMQPLIB_PORT}};const r=s,h=t,l=n;var g=class{constructor(e){this.config=e,this.connection=null,this.channel=null,this.amqpLink="",this.reconnectInProgress=!1,this.reconnectAttempts=0,this.maxReconnectAttempts=e.maxReconnectAttempts||10}setAmqpLink(e){this.amqpLink=e}async initialize(){const{channelName:e,durable:t,prefetch:s,heartbeat:n,timeout:i,initHook:o,reconnectDelay:a}=this.config;try{return this.connection=await r.connect(this.amqpLink,{heartbeat:n,timeout:i}),this.channel=await this.connection.createChannel(),await this.channel.assertQueue(e,{durable:t}),await this.channel.prefetch(s),await o({channel:this.channel,connection:this.connection}),h.log(`已连接到RabbitMQ,频道: ${e}`),this._setupConnectionEvents(),this.channel}catch(e){throw h.error("初始化RabbitMQ连接时出错:",e),e}}async reconnect(){if(this.reconnectInProgress)return h.log("重连已在进行中,跳过此次重连请求"),this.channel;if(this.reconnectAttempts>=this.maxReconnectAttempts)return h.error(`❌ 已达到最大重连次数 ${this.maxReconnectAttempts},停止重连`),h.error("请检查 RabbitMQ 服务状态或网络连接"),null;this.reconnectInProgress=!0,this.reconnectAttempts++;try{h.error(`🔄 连接丢失,正在尝试第 ${this.reconnectAttempts}/${this.maxReconnectAttempts} 次重连...`),await this._cleanupOldChannel();const e=(this.config.reconnectDelay||5e3)/1e3;return await l.sleep(e),await this.initialize(),this.reconnectAttempts=0,h.log(`✅ 已重新连接到RabbitMQ,频道: ${this.config.channelName}`),this.channel}catch(e){if(h.error(`❌ 第 ${this.reconnectAttempts} 次重连失败:`,e.message),this.reconnectAttempts<this.maxReconnectAttempts){const e=this.config.reconnectDelay||5e3;setTimeout(()=>{this.reconnectInProgress=!1,this.reconnect()},e)}else h.error("❌ 已达到最大重连次数,停止重连");throw e}finally{this.reconnectInProgress=!1}}getChannel(){return this.channel}getConnection(){return this.connection}isConnected(){return this.connection&&this.channel&&!this.connection.connection.destroyed}async close(){try{this.channel&&(await this.channel.close(),this.channel=null),this.connection&&(await this.connection.close(),this.connection=null),h.log("RabbitMQ连接已关闭")}catch(e){h.error("关闭连接时出错:",e.message)}}_setupConnectionEvents(){this.connection.on("error",e=>{h.error("连接错误:",e.message),this.reconnect().catch(e=>{h.error("重连失败:",e.message)})}),this.connection.on("close",()=>{h.error("与RabbitMQ的连接已关闭"),this.reconnect().catch(e=>{h.error("重连失败:",e.message)})})}async _cleanupOldChannel(){if(this.channel){try{await this.channel.close()}catch(e){h.log("关闭旧channel时出错:",e.message)}this.channel=null}}getStats(){return{isConnected:this.isConnected(),reconnectAttempts:this.reconnectAttempts,maxReconnectAttempts:this.maxReconnectAttempts,reconnectInProgress:this.reconnectInProgress}}};const u=t,m=n;var p=class{constructor(e){this.config=e,this.processingMessages=new Set}async startConsuming(e){const{channelName:t,callback:s,delay:n}=this.config;return u.log(`开始消费: ${t}`),await e.consume(t,async t=>{null!==t?await this._handleMessage(t,e,s,n):u.log("收到null消息,队列可能为空或连接中断")},{noAck:!1}),()=>{this.processingMessages.clear(),u.log("已清理消息处理状态")}}async _handleMessage(e,t,s,n){const i=e.fields.deliveryTag;if(this.processingMessages.has(i))u.log(`消息 ${i} 已在处理中,跳过`);else{if(this.processingMessages.add(i),!this._isValidMessageContent(e))return u.log(`⚠️ 收到无效消息 ${i},内容为空或无法解析,自动确认以防止阻塞`),void this._acknowledgeMessage(e,t,i,0);try{const o=JSON.parse(e.content.toString());u.log(`🪴 队列收到消息: ${JSON.stringify(o)}`);const a=Date.now(),c=new Promise((e,t)=>{setTimeout(()=>{t(new Error(`消息处理超时 (${this.config.messageTimeout}ms)`))},this.config.messageTimeout)});try{await Promise.race([s(o),c]);const r=Date.now()-a;u.log(`☘️ 消息处理完成,延迟: ${n}ms,总时间: ${r}ms`),this._acknowledgeMessage(e,t,i,n)}catch(s){s.message.includes("超时")?u.error(`⏰ 消息 ${i} 处理超时 (${this.config.messageTimeout}ms)`):u.log("‼️ 处理消息返回错误:",s.message),await this._rejectMessage(e,t,i)}}catch(s){u.log("‼️ 处理消息时出错:",s.message),await this._rejectMessage(e,t,i)}}}_isValidMessageContent(e){try{if(!e||!e.content)return!1;const t=e.content.toString();return!(!t||""===t.trim())&&("null"!==t.toLowerCase()&&"undefined"!==t.toLowerCase()&&(JSON.parse(t),!0))}catch(e){return!1}}_acknowledgeMessage(e,t,s,n){this.processingMessages.has(s)&&setTimeout(()=>{try{t.ack(e),this.processingMessages.delete(s),u.log(`✅ 消息 ${s} 已确认`)}catch(e){u.error(`ACK消息 ${s} 时出错:`,e.message),this.processingMessages.delete(s)}},n)}async _rejectMessage(e,t,s){if(await m.sleep(5),this.processingMessages.has(s))try{t.reject(e,!0),this.processingMessages.delete(s),u.log(`❌ 消息 ${s} 已拒绝并重新排队`)}catch(e){u.error(`拒绝消息 ${s} 时出错:`,e.message),this.processingMessages.delete(s)}}clearProcessingMessages(){this.processingMessages.clear(),u.log("已清理所有消息处理状态")}getProcessingCount(){return this.processingMessages.size}};const d=t;const f=c,M=g,w=p,y=class{constructor(e){this.config=e,this.intervalId=null,this.isRunning=!1}start(e){const{autoReload:t,channelName:s,queryHook:n}=this.config;t<=0?d.log("自动重载功能未启用"):this.isRunning?d.log("自动重载监控已在运行中"):(this.isRunning=!0,d.log(`启动队列监控,间隔: ${t}ms`),this.intervalId=setInterval(async()=>{try{await this._checkQueueStatus(e,s,n)}catch(e){d.error("队列状态检查时出错:",e.message)}},t))}stop(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=null,this.isRunning=!1,d.log("自动重载监控已停止"))}restart(e){this.stop(),this.start(e)}isActive(){return this.isRunning}async _checkQueueStatus(e,t,s){try{const{messageCount:n}=await e.checkQueue(t),i=await s();d.log(`队列 ${t} 中有 ${n} 条消息,钩子状态: ${i?1:0}`)}catch(e){d.error("检查队列状态时出错:",e.message)}}getConfig(){return{autoReload:this.config.autoReload,isRunning:this.isRunning,intervalId:null!==this.intervalId}}},P=t;class AMQPInitializer{constructor(){this.configResolver=new f,this.connectionManager=null,this.messageProcessor=null,this.autoReloader=null,this.config=null}async init(e={}){try{this.config=this.configResolver.resolveConfig(e),P.log("配置解析完成");const t=await this.configResolver.resolveAmqpLink(this.config.amqpAutoLink,this.config.amqpLink);this.connectionManager=new M(this.config),this.messageProcessor=new w(this.config),this.autoReloader=new y(this.config),this.connectionManager.setAmqpLink(t);const s=await this.connectionManager.initialize();this._setupReconnectHandler(),await this.messageProcessor.startConsuming(s),P.log("消息处理器已启动"),this.autoReloader.start(s),this.config.finish(),P.log("AMQP初始化完成")}catch(e){throw P.error("AMQP初始化失败:",e.message),e}}_setupReconnectHandler(){const e=this.connectionManager.reconnect.bind(this.connectionManager);this.connectionManager.reconnect=async()=>{try{const t=await e();return this.messageProcessor.clearProcessingMessages(),await this.messageProcessor.startConsuming(t),P.log("重连后消息处理器已重新启动"),this.autoReloader.restart(t),P.log("重连后自动重载监控已重新启动"),t}catch(e){throw P.error("重连处理失败:",e.message),e}}}getStatus(){return{isConnected:!!this.connectionManager&&this.connectionManager.isConnected(),processingCount:this.messageProcessor?this.messageProcessor.getProcessingCount():0,autoReloaderActive:!!this.autoReloader&&this.autoReloader.isActive(),channelName:this.config?this.config.channelName:null}}async shutdown(){try{P.log("开始优雅关闭AMQP连接..."),this.autoReloader&&this.autoReloader.stop(),this.messageProcessor&&this.messageProcessor.clearProcessingMessages(),this.connectionManager&&await this.connectionManager.close(),P.log("AMQP连接已优雅关闭")}catch(e){P.error("关闭AMQP连接时出错:",e.message)}}}var R=i({async init(e){const t=new AMQPInitializer;return await t.init(e)},AMQPInitializer:AMQPInitializer});module.exports=R;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amqplib-init.cjs.js","sources":["../module/ConfigResolver.js","../module/ConnectionManager.js","../module/MessageProcessor.js","../module/AutoReloader.js","../index.js"],"sourcesContent":["const axios = require('axios');\nconst log = require('chalk-style');\n\n/**\n * 配置解析器模块\n * 负责处理配置参数和自动获取RabbitMQ连接信息\n */\nclass ConfigResolver {\n constructor() {\n this.defaultConfig = {\n channelName: 'node-test-channel',\n prefetch: 1,\n callback: () => {},\n finish: () => {},\n amqpLink: '',\n amqpAutoLink: '',\n heartbeat: 60, // 增加心跳间隔到60秒,避免长时间处理时连接断开\n timeout: 300000, // 增加连接超时到5分钟(300秒)\n delay: 0,\n autoReload: 0,\n queryHook: () => {},\n initHook: () => {},\n durable: true,\n // 新增配置项 - 支持15分钟长任务\n messageTimeout: 900000, // 消息处理超时15分钟(900秒)\n reconnectDelay: 5000, // 重连延迟5秒\n maxReconnectAttempts: 10 // 最大重连次数\n };\n }\n\n /**\n * 解析和合并配置参数\n * @param {Object} options - 用户传入的配置选项\n * @returns {Object} 合并后的完整配置\n */\n resolveConfig(options = {}) {\n return { ...this.defaultConfig, ...options };\n }\n\n /**\n * 自动获取RabbitMQ连接信息\n * @param {string} amqpAutoLink - 自动获取连接信息的HTTPS链接\n * @param {string} fallbackAmqpLink - 备用连接地址\n * @returns {Promise<string>} 最终使用的连接地址\n */\n async resolveAmqpLink(amqpAutoLink, fallbackAmqpLink) {\n if (!amqpAutoLink) {\n return fallbackAmqpLink;\n }\n\n try {\n log.log(`正在从 ${amqpAutoLink} 获取连接信息...`);\n const response = await axios.post(amqpAutoLink);\n const { info } = response.data;\n \n if (this._validateConnectionInfo(info)) {\n const finalAmqpLink = `amqp://${info.AMQPLIB_USER}:${info.AMQPLIB_PWD}@${info.AMQPLIB_PUB}:${info.AMQPLIB_PORT}`;\n log.log(`✅ 自动获取连接信息成功: ${finalAmqpLink}`);\n return finalAmqpLink;\n } else {\n log.error('❌ 获取的连接信息不完整,使用默认连接地址');\n return fallbackAmqpLink;\n }\n } catch (error) {\n log.error('❌ 获取连接信息失败:', error.message);\n log.log('使用默认连接地址继续...');\n return fallbackAmqpLink;\n }\n }\n\n /**\n * 验证连接信息的完整性\n * @param {Object} info - 连接信息对象\n * @returns {boolean} 是否包含所有必要字段\n * @private\n */\n _validateConnectionInfo(info) {\n return info && \n info.AMQPLIB_USER && \n info.AMQPLIB_PWD && \n info.AMQPLIB_PUB && \n info.AMQPLIB_PORT;\n }\n}\n\nmodule.exports = ConfigResolver; ","const amqp = require('amqplib');\nconst log = require('chalk-style');\nconst happy = require('happy-help');\n\n/**\n * 连接管理器模块\n * 负责RabbitMQ连接管理、重连逻辑、频道管理\n */\nclass ConnectionManager {\n constructor(config) {\n this.config = config;\n this.connection = null;\n this.channel = null;\n this.amqpLink = '';\n this.reconnectInProgress = false; // 防止重复重连\n this.reconnectAttempts = 0; // 重连计数器\n this.maxReconnectAttempts = config.maxReconnectAttempts || 10; // 最大重连次数\n }\n\n /**\n * 设置AMQP连接地址\n * @param {string} amqpLink - RabbitMQ连接地址\n */\n setAmqpLink(amqpLink) {\n this.amqpLink = amqpLink;\n }\n\n /**\n * 初始化连接和频道\n * @returns {Promise<Object>} 返回频道对象\n */\n async initialize() {\n const { channelName, durable, prefetch, heartbeat, timeout, initHook, reconnectDelay } = this.config;\n \n try {\n // 建立连接\n this.connection = await amqp.connect(this.amqpLink, { heartbeat, timeout });\n \n // 创建频道\n this.channel = await this.connection.createChannel();\n \n // 设置队列和预取\n await this.channel.assertQueue(channelName, { durable });\n await this.channel.prefetch(prefetch);\n \n // 执行初始化钩子\n await initHook({ channel: this.channel, connection: this.connection });\n \n log.log(`已连接到RabbitMQ,频道: ${channelName}`);\n \n // 设置连接事件监听\n this._setupConnectionEvents();\n \n return this.channel;\n } catch (error) {\n log.error('初始化RabbitMQ连接时出错:', error);\n throw error;\n }\n }\n\n /**\n * 重连逻辑\n * @returns {Promise<Object>} 返回新的频道对象\n */\n async reconnect() {\n if (this.reconnectInProgress) {\n log.log('重连已在进行中,跳过此次重连请求');\n return this.channel;\n }\n\n // 检查是否达到最大重连次数\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n log.error(`❌ 已达到最大重连次数 ${this.maxReconnectAttempts},停止重连`);\n log.error('请检查 RabbitMQ 服务状态或网络连接');\n return null;\n }\n\n this.reconnectInProgress = true;\n this.reconnectAttempts++;\n \n try {\n log.error(`🔄 连接丢失,正在尝试第 ${this.reconnectAttempts}/${this.maxReconnectAttempts} 次重连...`);\n \n // 清理旧的channel状态\n await this._cleanupOldChannel();\n \n // 等待重连间隔,使用配置的延迟时间\n const delaySeconds = (this.config.reconnectDelay || 5000) / 1000;\n await happy.sleep(delaySeconds);\n \n // 重新初始化连接\n await this.initialize();\n \n // 重连成功,重置计数器\n this.reconnectAttempts = 0;\n log.log(`✅ 已重新连接到RabbitMQ,频道: ${this.config.channelName}`);\n \n return this.channel;\n } catch (error) {\n log.error(`❌ 第 ${this.reconnectAttempts} 次重连失败:`, error.message);\n \n // 如果未达到最大次数,继续重试\n if (this.reconnectAttempts < this.maxReconnectAttempts) {\n const retryDelay = this.config.reconnectDelay || 5000;\n setTimeout(() => {\n this.reconnectInProgress = false;\n this.reconnect();\n }, retryDelay);\n } else {\n log.error('❌ 已达到最大重连次数,停止重连');\n }\n \n throw error;\n } finally {\n this.reconnectInProgress = false;\n }\n }\n\n /**\n * 获取当前频道\n * @returns {Object|null} 当前频道对象\n */\n getChannel() {\n return this.channel;\n }\n\n /**\n * 获取当前连接\n * @returns {Object|null} 当前连接对象\n */\n getConnection() {\n return this.connection;\n }\n\n /**\n * 检查连接是否正常\n * @returns {boolean} 连接状态\n */\n isConnected() {\n return this.connection && this.channel && !this.connection.connection.destroyed;\n }\n\n /**\n * 关闭连接\n * @returns {Promise<void>}\n */\n async close() {\n try {\n if (this.channel) {\n await this.channel.close();\n this.channel = null;\n }\n if (this.connection) {\n await this.connection.close();\n this.connection = null;\n }\n log.log('RabbitMQ连接已关闭');\n } catch (error) {\n log.error('关闭连接时出错:', error.message);\n }\n }\n\n /**\n * 设置连接事件监听\n * @private\n */\n _setupConnectionEvents() {\n // 连接错误处理\n this.connection.on('error', (err) => {\n log.error('连接错误:', err.message);\n this.reconnect().catch(error => {\n log.error('重连失败:', error.message);\n });\n });\n\n // 连接关闭处理\n this.connection.on('close', () => {\n log.error('与RabbitMQ的连接已关闭');\n this.reconnect().catch(error => {\n log.error('重连失败:', error.message);\n });\n });\n }\n\n /**\n * 清理旧的频道状态\n * @private\n */\n async _cleanupOldChannel() {\n if (this.channel) {\n try {\n await this.channel.close();\n } catch (e) {\n log.log('关闭旧channel时出错:', e.message);\n }\n this.channel = null;\n }\n }\n\n /**\n * 获取连接统计信息\n * @returns {Object} 连接统计\n */\n getStats() {\n return {\n isConnected: this.isConnected(),\n reconnectAttempts: this.reconnectAttempts,\n maxReconnectAttempts: this.maxReconnectAttempts,\n reconnectInProgress: this.reconnectInProgress\n };\n }\n}\n\nmodule.exports = ConnectionManager; ","const log = require('chalk-style');\nconst happy = require('happy-help');\n\n/**\n * 消息处理器模块\n * 负责消息处理、状态跟踪、ACK/REJECT逻辑\n */\nclass MessageProcessor {\n constructor(config) {\n this.config = config;\n this.processingMessages = new Set(); // 跟踪正在处理的消息\n }\n\n /**\n * 开始消费消息\n * @param {Object} channel - RabbitMQ频道\n * @returns {Promise<Function>} 返回清理函数\n */\n async startConsuming(channel) {\n const { channelName, callback, delay } = this.config;\n \n log.log(`开始消费: ${channelName}`);\n \n await channel.consume(channelName, async (msg) => {\n if (msg !== null) {\n await this._handleMessage(msg, channel, callback, delay);\n } else {\n // ✅ 修复关键bug:null消息不需要ACK操作\n log.log('收到null消息,队列可能为空或连接中断');\n // 移除错误的 channel.ack(msg) 调用\n }\n }, { noAck: false });\n \n // 返回清理函数,用于重连时清理状态\n return () => {\n this.processingMessages.clear();\n log.log('已清理消息处理状态');\n };\n }\n\n /**\n * 处理单条消息\n * @param {Object} msg - RabbitMQ消息对象\n * @param {Object} channel - RabbitMQ频道\n * @param {Function} callback - 消息处理回调函数\n * @param {number} delay - 延迟ACK时间\n * @private\n */\n async _handleMessage(msg, channel, callback, delay) {\n const deliveryTag = msg.fields.deliveryTag;\n \n // 检查消息是否已在处理中\n if (this.processingMessages.has(deliveryTag)) {\n log.log(`消息 ${deliveryTag} 已在处理中,跳过`);\n return;\n }\n \n this.processingMessages.add(deliveryTag);\n \n // 检查消息内容有效性,对无效消息直接确认\n if (!this._isValidMessageContent(msg)) {\n log.log(`⚠️ 收到无效消息 ${deliveryTag},内容为空或无法解析,自动确认以防止阻塞`);\n this._acknowledgeMessage(msg, channel, deliveryTag, 0); // 立即确认无效消息\n return;\n }\n \n try {\n const content = JSON.parse(msg.content.toString());\n log.log(`🪴 队列收到消息: ${JSON.stringify(content)}`);\n const startTime = Date.now();\n \n // 创建超时 Promise\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => {\n reject(new Error(`消息处理超时 (${this.config.messageTimeout}ms)`));\n }, this.config.messageTimeout);\n });\n \n // 使用 Promise.race 实现超时控制\n try {\n await Promise.race([\n callback(content),\n timeoutPromise\n ]);\n \n const endTime = Date.now() - startTime;\n log.log(`☘️ 消息处理完成,延迟: ${delay}ms,总时间: ${endTime}ms`);\n this._acknowledgeMessage(msg, channel, deliveryTag, delay);\n \n } catch (callbackError) {\n if (callbackError.message.includes('超时')) {\n log.error(`⏰ 消息 ${deliveryTag} 处理超时 (${this.config.messageTimeout}ms)`);\n } else {\n log.log('‼️ 处理消息返回错误:', callbackError.message);\n }\n await this._rejectMessage(msg, channel, deliveryTag);\n }\n \n } catch (e) {\n log.log('‼️ 处理消息时出错:', e.message);\n await this._rejectMessage(msg, channel, deliveryTag);\n }\n }\n\n /**\n * 检查消息内容是否有效\n * @param {Object} msg - RabbitMQ消息对象\n * @returns {boolean} 消息内容是否有效\n * @private\n */\n _isValidMessageContent(msg) {\n try {\n // 检查消息对象是否存在\n if (!msg || !msg.content) {\n return false;\n }\n \n // 获取消息内容字符串\n const contentStr = msg.content.toString();\n \n // 检查内容是否为空或只包含空白字符\n if (!contentStr || contentStr.trim() === '') {\n return false;\n }\n \n // 检查是否为null字符串\n if (contentStr.toLowerCase() === 'null' || contentStr.toLowerCase() === 'undefined') {\n return false;\n }\n \n // 尝试解析JSON,如果失败则认为无效\n JSON.parse(contentStr);\n return true;\n } catch (error) {\n // JSON解析失败,认为消息无效\n return false;\n }\n }\n\n /**\n * 确认消息\n * @param {Object} msg - RabbitMQ消息对象\n * @param {Object} channel - RabbitMQ频道\n * @param {string} deliveryTag - 消息标签\n * @param {number} delay - 延迟时间\n * @private\n */\n _acknowledgeMessage(msg, channel, deliveryTag, delay) {\n // 确保消息还在处理集合中再进行ACK\n if (this.processingMessages.has(deliveryTag)) {\n setTimeout(() => {\n try {\n channel.ack(msg);\n this.processingMessages.delete(deliveryTag);\n log.log(`✅ 消息 ${deliveryTag} 已确认`);\n } catch (ackError) {\n log.error(`ACK消息 ${deliveryTag} 时出错:`, ackError.message);\n this.processingMessages.delete(deliveryTag);\n }\n }, delay);\n }\n }\n\n /**\n * 拒绝消息并重新排队\n * @param {Object} msg - RabbitMQ消息对象\n * @param {Object} channel - RabbitMQ频道\n * @param {string} deliveryTag - 消息标签\n * @private\n */\n async _rejectMessage(msg, channel, deliveryTag) {\n await happy.sleep(5);\n \n if (this.processingMessages.has(deliveryTag)) {\n try {\n channel.reject(msg, true);\n this.processingMessages.delete(deliveryTag);\n log.log(`❌ 消息 ${deliveryTag} 已拒绝并重新排队`);\n } catch (rejectError) {\n log.error(`拒绝消息 ${deliveryTag} 时出错:`, rejectError.message);\n this.processingMessages.delete(deliveryTag);\n }\n }\n }\n\n /**\n * 清理所有处理中的消息状态\n */\n clearProcessingMessages() {\n this.processingMessages.clear();\n log.log('已清理所有消息处理状态');\n }\n\n /**\n * 获取当前处理中的消息数量\n * @returns {number} 处理中的消息数量\n */\n getProcessingCount() {\n return this.processingMessages.size;\n }\n}\n\nmodule.exports = MessageProcessor; ","const log = require('chalk-style');\n\n/**\n * 自动重载器模块\n * 负责监控队列状态(已移除 PM2 重启功能,改用 Supervisor 管理)\n */\nclass AutoReloader {\n constructor(config) {\n this.config = config;\n this.intervalId = null;\n this.isRunning = false;\n }\n\n /**\n * 启动自动重载监控\n * @param {Object} channel - RabbitMQ频道\n */\n start(channel) {\n const { autoReload, channelName, queryHook } = this.config;\n \n if (autoReload <= 0) {\n log.log('自动重载功能未启用');\n return;\n }\n\n if (this.isRunning) {\n log.log('自动重载监控已在运行中');\n return;\n }\n\n this.isRunning = true;\n log.log(`启动队列监控,间隔: ${autoReload}ms`);\n\n this.intervalId = setInterval(async () => {\n try {\n await this._checkQueueStatus(channel, channelName, queryHook);\n } catch (error) {\n log.error('队列状态检查时出错:', error.message);\n }\n }, autoReload);\n }\n\n /**\n * 停止自动重载监控\n */\n stop() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n this.isRunning = false;\n log.log('自动重载监控已停止');\n }\n }\n\n /**\n * 重启自动重载监控(用于重连后)\n * @param {Object} channel - 新的RabbitMQ频道\n */\n restart(channel) {\n this.stop();\n this.start(channel);\n }\n\n /**\n * 获取监控状态\n * @returns {boolean} 是否正在运行\n */\n isActive() {\n return this.isRunning;\n }\n\n /**\n * 检查队列状态(仅监控,不执行重启)\n * @param {Object} channel - RabbitMQ频道\n * @param {string} channelName - 频道名称\n * @param {Function} queryHook - 查询钩子函数\n * @private\n */\n async _checkQueueStatus(channel, channelName, queryHook) {\n try {\n // 检查队列中的消息数量\n const { messageCount } = await channel.checkQueue(channelName);\n \n // 执行查询钩子\n const hookResult = await queryHook();\n \n log.log(`队列 ${channelName} 中有 ${messageCount} 条消息,钩子状态: ${hookResult ? 1 : 0}`);\n \n // 注意: 已移除自动重启功能\n // 如需重启服务,请使用 Supervisor: supervisorctl restart <service-name>\n } catch (error) {\n log.error('检查队列状态时出错:', error.message);\n }\n }\n\n /**\n * 获取当前配置信息\n * @returns {Object} 配置信息\n */\n getConfig() {\n return {\n autoReload: this.config.autoReload,\n isRunning: this.isRunning,\n intervalId: this.intervalId !== null\n };\n }\n}\n\nmodule.exports = AutoReloader; ","const ConfigResolver = require('./module/ConfigResolver');\nconst ConnectionManager = require('./module/ConnectionManager');\nconst MessageProcessor = require('./module/MessageProcessor');\nconst AutoReloader = require('./module/AutoReloader');\nconst log = require('chalk-style');\n\n/**\n * AMQP初始化器主类\n * 协调各个模块完成RabbitMQ的初始化和消息处理\n */\nclass AMQPInitializer {\n constructor() {\n this.configResolver = new ConfigResolver();\n this.connectionManager = null;\n this.messageProcessor = null;\n this.autoReloader = null;\n this.config = null;\n }\n\n /**\n * 初始化AMQP连接和消息处理\n * @param {Object} options - 配置选项\n * @returns {Promise<void>}\n */\n async init(options = {}) {\n try {\n // 1. 解析配置\n this.config = this.configResolver.resolveConfig(options);\n log.log('配置解析完成');\n\n // 2. 解析连接地址\n const amqpLink = await this.configResolver.resolveAmqpLink(\n this.config.amqpAutoLink,\n this.config.amqpLink\n );\n\n // 3. 初始化各个模块\n this.connectionManager = new ConnectionManager(this.config);\n this.messageProcessor = new MessageProcessor(this.config);\n this.autoReloader = new AutoReloader(this.config);\n\n // 4. 设置连接地址并初始化连接\n this.connectionManager.setAmqpLink(amqpLink);\n const channel = await this.connectionManager.initialize();\n\n // 5. 重新定义重连逻辑,确保重连后重新启动消息处理和自动重载\n this._setupReconnectHandler();\n\n // 6. 启动消息处理\n await this.messageProcessor.startConsuming(channel);\n log.log('消息处理器已启动');\n\n // 7. 启动自动重载监控\n this.autoReloader.start(channel);\n\n // 8. 执行初始化完成回调\n this.config.finish();\n \n log.log('AMQP初始化完成');\n } catch (error) {\n log.error('AMQP初始化失败:', error.message);\n throw error;\n }\n }\n\n /**\n * 设置重连处理器\n * 确保重连后各个模块能够正确重新启动\n * @private\n */\n _setupReconnectHandler() {\n const originalReconnect = this.connectionManager.reconnect.bind(this.connectionManager);\n \n this.connectionManager.reconnect = async () => {\n try {\n // 执行原始重连逻辑\n const newChannel = await originalReconnect();\n \n // 重连后重新启动消息处理\n this.messageProcessor.clearProcessingMessages();\n await this.messageProcessor.startConsuming(newChannel);\n log.log('重连后消息处理器已重新启动');\n \n // 重连后重新启动自动重载监控\n this.autoReloader.restart(newChannel);\n log.log('重连后自动重载监控已重新启动');\n \n return newChannel;\n } catch (error) {\n log.error('重连处理失败:', error.message);\n throw error;\n }\n };\n }\n\n /**\n * 获取当前状态信息\n * @returns {Object} 状态信息\n */\n getStatus() {\n return {\n isConnected: this.connectionManager ? this.connectionManager.isConnected() : false,\n processingCount: this.messageProcessor ? this.messageProcessor.getProcessingCount() : 0,\n autoReloaderActive: this.autoReloader ? this.autoReloader.isActive() : false,\n channelName: this.config ? this.config.channelName : null\n };\n }\n\n /**\n * 优雅关闭\n * @returns {Promise<void>}\n */\n async shutdown() {\n try {\n log.log('开始优雅关闭AMQP连接...');\n \n // 停止自动重载监控\n if (this.autoReloader) {\n this.autoReloader.stop();\n }\n \n // 清理消息处理状态\n if (this.messageProcessor) {\n this.messageProcessor.clearProcessingMessages();\n }\n \n // 关闭连接\n if (this.connectionManager) {\n await this.connectionManager.close();\n }\n \n log.log('AMQP连接已优雅关闭');\n } catch (error) {\n log.error('关闭AMQP连接时出错:', error.message);\n }\n }\n}\n\n// 导出兼容的API\nmodule.exports = {\n /**\n * 初始化函数 - 保持向后兼容\n * @param {Object} options - 配置选项\n * @returns {Promise<void>}\n */\n async init(options) {\n const initializer = new AMQPInitializer();\n return await initializer.init(options);\n },\n\n // 导出类,供需要更多控制的用户使用\n AMQPInitializer\n};\n"],"names":["log","ConfigResolver","require$$0","happy","ConnectionManager","require$$1","MessageProcessor","AutoReloader","require$$2","require$$3","require$$4"],"mappings":";;;;;;;;;;;;;AAAA,MAAM,KAAK,GAAG,UAAgB;AAC9B,MAAMA,KAAG,GAAG,UAAsB;;AAElC;AACA;AACA;AACA;uBACA,MAAM,cAAc,CAAC;AACrB,EAAE,WAAW,GAAG;AAChB,IAAI,IAAI,CAAC,aAAa,GAAG;AACzB,MAAM,WAAW,EAAE,mBAAmB;AACtC,MAAM,QAAQ,EAAE,CAAC;AACjB,MAAM,QAAQ,EAAE,MAAM,CAAA,CAAE;AACxB,MAAM,MAAM,EAAE,MAAM,CAAA,CAAE;AACtB,MAAM,QAAQ,EAAE,EAAE;AAClB,MAAM,YAAY,EAAE,EAAE;AACtB,MAAM,SAAS,EAAE,EAAE;AACnB,MAAM,OAAO,EAAE,MAAM;AACrB,MAAM,KAAK,EAAE,CAAC;AACd,MAAM,UAAU,EAAE,CAAC;AACnB,MAAM,SAAS,EAAE,MAAM,CAAA,CAAE;AACzB,MAAM,QAAQ,EAAE,MAAM,CAAA,CAAE;AACxB,MAAM,OAAO,EAAE,IAAI;AACnB;AACA,MAAM,cAAc,EAAE,MAAM;AAC5B,MAAM,cAAc,EAAE,IAAI;AAC1B,MAAM,oBAAoB,EAAE,EAAE;AAC9B,KAAK;AACL,EAAA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAE,aAAa,CAAC,OAAO,GAAG,EAAE,EAAE;AAC9B,IAAI,OAAO,EAAE,GAAG,IAAI,CAAC,aAAa,EAAE,GAAG,OAAO,EAAE;AAChD,EAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,eAAe,CAAC,YAAY,EAAE,gBAAgB,EAAE;AACxD,IAAI,IAAI,CAAC,YAAY,EAAE;AACvB,MAAM,OAAO,gBAAgB;AAC7B,IAAA;;AAEA,IAAI,IAAI;AACR,MAAMA,KAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;AAC9C,MAAM,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC;AACrD,MAAM,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,IAAI;AACpC;AACA,MAAM,IAAI,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE;AAC9C,QAAQ,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;AACxH,QAAQA,KAAG,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC,CAAC;AACjD,QAAQ,OAAO,aAAa;AAC5B,MAAA,CAAO,MAAM;AACb,QAAQA,KAAG,CAAC,KAAK,CAAC,uBAAuB,CAAC;AAC1C,QAAQ,OAAO,gBAAgB;AAC/B,MAAA;AACA,IAAA,CAAK,CAAC,OAAO,KAAK,EAAE;AACpB,MAAMA,KAAG,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC;AAC7C,MAAMA,KAAG,CAAC,GAAG,CAAC,eAAe,CAAC;AAC9B,MAAM,OAAO,gBAAgB;AAC7B,IAAA;AACA,EAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,uBAAuB,CAAC,IAAI,EAAE;AAChC,IAAI,OAAO,IAAI;AACf,WAAW,IAAI,CAAC,YAAY;AAC5B,WAAW,IAAI,CAAC,WAAW;AAC3B,WAAW,IAAI,CAAC,WAAW;AAC3B,WAAW,IAAI,CAAC,YAAY;AAC5B,EAAA;AACA;;AAEA,IAAA,gBAAc,GAAGC,gBAAc;;ACrF/B,MAAM,IAAI,GAAGC,YAAkB;AAC/B,MAAMF,KAAG,GAAG,UAAsB;AAClC,MAAMG,OAAK,GAAG,UAAqB;;AAEnC;AACA;AACA;AACA;0BACA,MAAM,iBAAiB,CAAC;AACxB,EAAE,WAAW,CAAC,MAAM,EAAE;AACtB,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM;AACxB,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI;AAC1B,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI;AACvB,IAAI,IAAI,CAAC,QAAQ,GAAG,EAAE;AACtB,IAAI,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAC;AACrC,IAAI,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;AAC/B,IAAI,IAAI,CAAC,oBAAoB,GAAG,MAAM,CAAC,oBAAoB,IAAI,EAAE,CAAC;AAClE,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,WAAW,CAAC,QAAQ,EAAE;AACxB,IAAI,IAAI,CAAC,QAAQ,GAAG,QAAQ;AAC5B,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,MAAM,UAAU,GAAG;AACrB,IAAI,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,MAAM;AACxG;AACA,IAAI,IAAI;AACR;AACA,MAAM,IAAI,CAAC,UAAU,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AACjF;AACA;AACA,MAAM,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE;AAC1D;AACA;AACA,MAAM,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,CAAC;AAC9D,MAAM,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;AAC3C;AACA;AACA,MAAM,MAAM,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;AAC5E;AACA,MAAMH,KAAG,CAAC,GAAG,CAAC,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC,CAAC;AAChD;AACA;AACA,MAAM,IAAI,CAAC,sBAAsB,EAAE;AACnC;AACA,MAAM,OAAO,IAAI,CAAC,OAAO;AACzB,IAAA,CAAK,CAAC,OAAO,KAAK,EAAE;AACpB,MAAMA,KAAG,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC;AAC3C,MAAM,MAAM,KAAK;AACjB,IAAA;AACA,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,MAAM,SAAS,GAAG;AACpB,IAAI,IAAI,IAAI,CAAC,mBAAmB,EAAE;AAClC,MAAMA,KAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC;AACjC,MAAM,OAAO,IAAI,CAAC,OAAO;AACzB,IAAA;;AAEA;AACA,IAAI,IAAI,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,oBAAoB,EAAE;AAC7D,MAAMA,KAAG,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;AAChE,MAAMA,KAAG,CAAC,KAAK,CAAC,wBAAwB,CAAC;AACzC,MAAM,OAAO,IAAI;AACjB,IAAA;;AAEA,IAAI,IAAI,CAAC,mBAAmB,GAAG,IAAI;AACnC,IAAI,IAAI,CAAC,iBAAiB,EAAE;AAC5B;AACA,IAAI,IAAI;AACR,MAAMA,KAAG,CAAC,KAAK,CAAC,CAAC,cAAc,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9F;AACA;AACA,MAAM,MAAM,IAAI,CAAC,kBAAkB,EAAE;AACrC;AACA;AACA,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,IAAI,IAAI,IAAI;AACtE,MAAM,MAAMG,OAAK,CAAC,KAAK,CAAC,YAAY,CAAC;AACrC;AACA;AACA,MAAM,MAAM,IAAI,CAAC,UAAU,EAAE;AAC7B;AACA;AACA,MAAM,IAAI,CAAC,iBAAiB,GAAG,CAAC;AAChC,MAAMH,KAAG,CAAC,GAAG,CAAC,CAAC,qBAAqB,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;AAChE;AACA,MAAM,OAAO,IAAI,CAAC,OAAO;AACzB,IAAA,CAAK,CAAC,OAAO,KAAK,EAAE;AACpB,MAAMA,KAAG,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC;AACtE;AACA;AACA,MAAM,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,EAAE;AAC9D,QAAQ,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,IAAI;AAC7D,QAAQ,UAAU,CAAC,MAAM;AACzB,UAAU,IAAI,CAAC,mBAAmB,GAAG,KAAK;AAC1C,UAAU,IAAI,CAAC,SAAS,EAAE;AAC1B,QAAA,CAAS,EAAE,UAAU,CAAC;AACtB,MAAA,CAAO,MAAM;AACb,QAAQA,KAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC;AACrC,MAAA;AACA;AACA,MAAM,MAAM,KAAK;AACjB,IAAA,CAAK,SAAS;AACd,MAAM,IAAI,CAAC,mBAAmB,GAAG,KAAK;AACtC,IAAA;AACA,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,UAAU,GAAG;AACf,IAAI,OAAO,IAAI,CAAC,OAAO;AACvB,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,aAAa,GAAG;AAClB,IAAI,OAAO,IAAI,CAAC,UAAU;AAC1B,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,WAAW,GAAG;AAChB,IAAI,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS;AACnF,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,MAAM,KAAK,GAAG;AAChB,IAAI,IAAI;AACR,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE;AACxB,QAAQ,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AAClC,QAAQ,IAAI,CAAC,OAAO,GAAG,IAAI;AAC3B,MAAA;AACA,MAAM,IAAI,IAAI,CAAC,UAAU,EAAE;AAC3B,QAAQ,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE;AACrC,QAAQ,IAAI,CAAC,UAAU,GAAG,IAAI;AAC9B,MAAA;AACA,MAAMA,KAAG,CAAC,GAAG,CAAC,eAAe,CAAC;AAC9B,IAAA,CAAK,CAAC,OAAO,KAAK,EAAE;AACpB,MAAMA,KAAG,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC;AAC1C,IAAA;AACA,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,sBAAsB,GAAG;AAC3B;AACA,IAAI,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK;AACzC,MAAMA,KAAG,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC;AACrC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI;AACtC,QAAQA,KAAG,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;AACzC,MAAA,CAAO,CAAC;AACR,IAAA,CAAK,CAAC;;AAEN;AACA,IAAI,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM;AACtC,MAAMA,KAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC;AAClC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI;AACtC,QAAQA,KAAG,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;AACzC,MAAA,CAAO,CAAC;AACR,IAAA,CAAK,CAAC;AACN,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,MAAM,kBAAkB,GAAG;AAC7B,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE;AACtB,MAAM,IAAI;AACV,QAAQ,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AAClC,MAAA,CAAO,CAAC,OAAO,CAAC,EAAE;AAClB,QAAQA,KAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC;AAC5C,MAAA;AACA,MAAM,IAAI,CAAC,OAAO,GAAG,IAAI;AACzB,IAAA;AACA,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,QAAQ,GAAG;AACb,IAAI,OAAO;AACX,MAAM,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE;AACrC,MAAM,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;AAC/C,MAAM,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;AACrD,MAAM,mBAAmB,EAAE,IAAI,CAAC;AAChC,KAAK;AACL,EAAA;AACA;;AAEA,IAAA,mBAAc,GAAGI,mBAAiB;;ACrNlC,MAAMJ,KAAG,GAAGE,UAAsB;AAClC,MAAM,KAAK,GAAGG,UAAqB;;AAEnC;AACA;AACA;AACA;yBACA,MAAM,gBAAgB,CAAC;AACvB,EAAE,WAAW,CAAC,MAAM,EAAE;AACtB,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM;AACxB,IAAI,IAAI,CAAC,kBAAkB,GAAG,IAAI,GAAG,EAAE,CAAC;AACxC,EAAA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,cAAc,CAAC,OAAO,EAAE;AAChC,IAAI,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,MAAM;AACxD;AACA,IAAIL,KAAG,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;AACnC;AACA,IAAI,MAAM,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,GAAG,KAAK;AACtD,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;AACxB,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC;AAChE,MAAA,CAAO,MAAM;AACb;AACA,QAAQA,KAAG,CAAC,GAAG,CAAC,sBAAsB,CAAC;AACvC;AACA,MAAA;AACA,IAAA,CAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AACxB;AACA;AACA,IAAI,OAAO,MAAM;AACjB,MAAM,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE;AACrC,MAAMA,KAAG,CAAC,GAAG,CAAC,WAAW,CAAC;AAC1B,IAAA,CAAK;AACL,EAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE;AACtD,IAAI,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW;AAC9C;AACA;AACA,IAAI,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;AAClD,MAAMA,KAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;AAC3C,MAAM;AACN,IAAA;AACA;AACA,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC;AAC5C;AACA;AACA,IAAI,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,EAAE;AAC3C,MAAMA,KAAG,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,WAAW,CAAC,oBAAoB,CAAC,CAAC;AAC7D,MAAM,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;AAC7D,MAAM;AACN,IAAA;AACA;AACA,IAAI,IAAI;AACR,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;AACxD,MAAMA,KAAG,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACtD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE;AAClC;AACA;AACA,MAAM,MAAM,cAAc,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK;AACxD,QAAQ,UAAU,CAAC,MAAM;AACzB,UAAU,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;AACvE,QAAA,CAAS,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;AACtC,MAAA,CAAO,CAAC;AACR;AACA;AACA,MAAM,IAAI;AACV,QAAQ,MAAM,OAAO,CAAC,IAAI,CAAC;AAC3B,UAAU,QAAQ,CAAC,OAAO,CAAC;AAC3B,UAAU;AACV,SAAS,CAAC;AACV;AACA,QAAQ,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;AAC9C,QAAQA,KAAG,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;AAC7D,QAAQ,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC;AAClE;AACA,MAAA,CAAO,CAAC,OAAO,aAAa,EAAE;AAC9B,QAAQ,IAAI,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;AAClD,UAAUA,KAAG,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;AACjF,QAAA,CAAS,MAAM;AACf,UAAUA,KAAG,CAAC,GAAG,CAAC,cAAc,EAAE,aAAa,CAAC,OAAO,CAAC;AACxD,QAAA;AACA,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,CAAC;AAC5D,MAAA;AACA;AACA,IAAA,CAAK,CAAC,OAAO,CAAC,EAAE;AAChB,MAAMA,KAAG,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC;AACvC,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,CAAC;AAC1D,IAAA;AACA,EAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,sBAAsB,CAAC,GAAG,EAAE;AAC9B,IAAI,IAAI;AACR;AACA,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE;AAChC,QAAQ,OAAO,KAAK;AACpB,MAAA;AACA;AACA;AACA,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE;AAC/C;AACA;AACA,MAAM,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;AACnD,QAAQ,OAAO,KAAK;AACpB,MAAA;AACA;AACA;AACA,MAAM,IAAI,UAAU,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,UAAU,CAAC,WAAW,EAAE,KAAK,WAAW,EAAE;AAC3F,QAAQ,OAAO,KAAK;AACpB,MAAA;AACA;AACA;AACA,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;AAC5B,MAAM,OAAO,IAAI;AACjB,IAAA,CAAK,CAAC,OAAO,KAAK,EAAE;AACpB;AACA,MAAM,OAAO,KAAK;AAClB,IAAA;AACA,EAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE;AACxD;AACA,IAAI,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;AAClD,MAAM,UAAU,CAAC,MAAM;AACvB,QAAQ,IAAI;AACZ,UAAU,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;AAC1B,UAAU,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC;AACrD,UAAUA,KAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;AAC5C,QAAA,CAAS,CAAC,OAAO,QAAQ,EAAE;AAC3B,UAAUA,KAAG,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC;AAClE,UAAU,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC;AACrD,QAAA;AACA,MAAA,CAAO,EAAE,KAAK,CAAC;AACf,IAAA;AACA,EAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE;AAClD,IAAI,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AACxB;AACA,IAAI,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;AAClD,MAAM,IAAI;AACV,QAAQ,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC;AACjC,QAAQ,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC;AACnD,QAAQA,KAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;AAC/C,MAAA,CAAO,CAAC,OAAO,WAAW,EAAE;AAC5B,QAAQA,KAAG,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC;AAClE,QAAQ,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC;AACnD,MAAA;AACA,IAAA;AACA,EAAA;;AAEA;AACA;AACA;AACA,EAAE,uBAAuB,GAAG;AAC5B,IAAI,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE;AACnC,IAAIA,KAAG,CAAC,GAAG,CAAC,aAAa,CAAC;AAC1B,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,kBAAkB,GAAG;AACvB,IAAI,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI;AACvC,EAAA;AACA;;AAEA,IAAA,kBAAc,GAAGM,kBAAgB;;AC1MjC,MAAMN,KAAG,GAAGE,UAAsB;;AAElC;AACA;AACA;AACA;qBACA,MAAM,YAAY,CAAC;AACnB,EAAE,WAAW,CAAC,MAAM,EAAE;AACtB,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM;AACxB,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI;AAC1B,IAAI,IAAI,CAAC,SAAS,GAAG,KAAK;AAC1B,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,KAAK,CAAC,OAAO,EAAE;AACjB,IAAI,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,MAAM;AAC9D;AACA,IAAI,IAAI,UAAU,IAAI,CAAC,EAAE;AACzB,MAAMF,KAAG,CAAC,GAAG,CAAC,WAAW,CAAC;AAC1B,MAAM;AACN,IAAA;;AAEA,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;AACxB,MAAMA,KAAG,CAAC,GAAG,CAAC,aAAa,CAAC;AAC5B,MAAM;AACN,IAAA;;AAEA,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI;AACzB,IAAIA,KAAG,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC;;AAEzC,IAAI,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,YAAY;AAC9C,MAAM,IAAI;AACV,QAAQ,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,CAAC;AACrE,MAAA,CAAO,CAAC,OAAO,KAAK,EAAE;AACtB,QAAQA,KAAG,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC;AAC9C,MAAA;AACA,IAAA,CAAK,EAAE,UAAU,CAAC;AAClB,EAAA;;AAEA;AACA;AACA;AACA,EAAE,IAAI,GAAG;AACT,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;AACzB,MAAM,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC;AACpC,MAAM,IAAI,CAAC,UAAU,GAAG,IAAI;AAC5B,MAAM,IAAI,CAAC,SAAS,GAAG,KAAK;AAC5B,MAAMA,KAAG,CAAC,GAAG,CAAC,WAAW,CAAC;AAC1B,IAAA;AACA,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,OAAO,CAAC,OAAO,EAAE;AACnB,IAAI,IAAI,CAAC,IAAI,EAAE;AACf,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;AACvB,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,QAAQ,GAAG;AACb,IAAI,OAAO,IAAI,CAAC,SAAS;AACzB,EAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE;AAC3D,IAAI,IAAI;AACR;AACA,MAAM,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC;AACpE;AACA;AACA,MAAM,MAAM,UAAU,GAAG,MAAM,SAAS,EAAE;AAC1C;AACA,MAAMA,KAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,EAAE,YAAY,CAAC,WAAW,EAAE,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACrF;AACA;AACA;AACA,IAAA,CAAK,CAAC,OAAO,KAAK,EAAE;AACpB,MAAMA,KAAG,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC;AAC5C,IAAA;AACA,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,SAAS,GAAG;AACd,IAAI,OAAO;AACX,MAAM,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU;AACxC,MAAM,SAAS,EAAE,IAAI,CAAC,SAAS;AAC/B,MAAM,UAAU,EAAE,IAAI,CAAC,UAAU,KAAK;AACtC,KAAK;AACL,EAAA;AACA;;AAEA,IAAA,cAAc,GAAGO,cAAY;;AC5G7B,MAAM,cAAc,GAAGL,gBAAkC;AACzD,MAAM,iBAAiB,GAAGG,mBAAqC;AAC/D,MAAM,gBAAgB,GAAGG,kBAAoC;AAC7D,MAAM,YAAY,GAAGC,cAAgC;AACrD,MAAM,GAAG,GAAGC,UAAsB;;AAElC;AACA;AACA;AACA;AACA,MAAM,eAAe,CAAC;AACtB,EAAE,WAAW,GAAG;AAChB,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,EAAE;AAC9C,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI;AACjC,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI;AAChC,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI;AAC5B,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI;AACtB,EAAA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,IAAI,CAAC,OAAO,GAAG,EAAE,EAAE;AAC3B,IAAI,IAAI;AACR;AACA,MAAM,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,OAAO,CAAC;AAC9D,MAAM,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC;;AAEvB;AACA,MAAM,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,eAAe;AAChE,QAAQ,IAAI,CAAC,MAAM,CAAC,YAAY;AAChC,QAAQ,IAAI,CAAC,MAAM,CAAC;AACpB,OAAO;;AAEP;AACA,MAAM,IAAI,CAAC,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;AACjE,MAAM,IAAI,CAAC,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC;AAC/D,MAAM,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;;AAEvD;AACA,MAAM,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,QAAQ,CAAC;AAClD,MAAM,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,EAAE;;AAE/D;AACA,MAAM,IAAI,CAAC,sBAAsB,EAAE;;AAEnC;AACA,MAAM,MAAM,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,OAAO,CAAC;AACzD,MAAM,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC;;AAEzB;AACA,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC;;AAEtC;AACA,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;AAC1B;AACA,MAAM,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC;AAC1B,IAAA,CAAK,CAAC,OAAO,KAAK,EAAE;AACpB,MAAM,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC;AAC5C,MAAM,MAAM,KAAK;AACjB,IAAA;AACA,EAAA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAE,sBAAsB,GAAG;AAC3B,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC;AAC3F;AACA,IAAI,IAAI,CAAC,iBAAiB,CAAC,SAAS,GAAG,YAAY;AACnD,MAAM,IAAI;AACV;AACA,QAAQ,MAAM,UAAU,GAAG,MAAM,iBAAiB,EAAE;AACpD;AACA;AACA,QAAQ,IAAI,CAAC,gBAAgB,CAAC,uBAAuB,EAAE;AACvD,QAAQ,MAAM,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,UAAU,CAAC;AAC9D,QAAQ,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC;AAChC;AACA;AACA,QAAQ,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC;AAC7C,QAAQ,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC;AACjC;AACA,QAAQ,OAAO,UAAU;AACzB,MAAA,CAAO,CAAC,OAAO,KAAK,EAAE;AACtB,QAAQ,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC;AAC3C,QAAQ,MAAM,KAAK;AACnB,MAAA;AACA,IAAA,CAAK;AACL,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,SAAS,GAAG;AACd,IAAI,OAAO;AACX,MAAM,WAAW,EAAE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE,GAAG,KAAK;AACxF,MAAM,eAAe,EAAE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,GAAG,CAAC;AAC7F,MAAM,kBAAkB,EAAE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,GAAG,KAAK;AAClF,MAAM,WAAW,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG;AAC3D,KAAK;AACL,EAAA;;AAEA;AACA;AACA;AACA;AACA,EAAE,MAAM,QAAQ,GAAG;AACnB,IAAI,IAAI;AACR,MAAM,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAC;AAChC;AACA;AACA,MAAM,IAAI,IAAI,CAAC,YAAY,EAAE;AAC7B,QAAQ,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;AAChC,MAAA;AACA;AACA;AACA,MAAM,IAAI,IAAI,CAAC,gBAAgB,EAAE;AACjC,QAAQ,IAAI,CAAC,gBAAgB,CAAC,uBAAuB,EAAE;AACvD,MAAA;AACA;AACA;AACA,MAAM,IAAI,IAAI,CAAC,iBAAiB,EAAE;AAClC,QAAQ,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE;AAC5C,MAAA;AACA;AACA,MAAM,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC;AAC5B,IAAA,CAAK,CAAC,OAAO,KAAK,EAAE;AACpB,MAAM,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC;AAC9C,IAAA;AACA,EAAA;AACA;;AAEA;AACA,IAAA,WAAc,GAAG;AACjB;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,IAAI,CAAC,OAAO,EAAE;AACtB,IAAI,MAAM,WAAW,GAAG,IAAI,eAAe,EAAE;AAC7C,IAAI,OAAO,MAAM,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC;AAC1C,EAAA,CAAG;;AAEH;AACA,EAAE;AACF,CAAC;;;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from"axios";import t from"chalk-style";import s from"amqplib";import n from"happy-help";function i(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}const o=e,a=t;var c=class{constructor(){this.defaultConfig={channelName:"node-test-channel",prefetch:1,callback:()=>{},finish:()=>{},amqpLink:"",amqpAutoLink:"",heartbeat:60,timeout:3e5,delay:0,autoReload:0,queryHook:()=>{},initHook:()=>{},durable:!0,messageTimeout:9e5,reconnectDelay:5e3,maxReconnectAttempts:10}}resolveConfig(e={}){return{...this.defaultConfig,...e}}async resolveAmqpLink(e,t){if(!e)return t;try{a.log(`正在从 ${e} 获取连接信息...`);const s=await o.post(e),{info:n}=s.data;if(this._validateConnectionInfo(n)){const e=`amqp://${n.AMQPLIB_USER}:${n.AMQPLIB_PWD}@${n.AMQPLIB_PUB}:${n.AMQPLIB_PORT}`;return a.log(`✅ 自动获取连接信息成功: ${e}`),e}return a.error("❌ 获取的连接信息不完整,使用默认连接地址"),t}catch(e){return a.error("❌ 获取连接信息失败:",e.message),a.log("使用默认连接地址继续..."),t}}_validateConnectionInfo(e){return e&&e.AMQPLIB_USER&&e.AMQPLIB_PWD&&e.AMQPLIB_PUB&&e.AMQPLIB_PORT}};const r=s,h=t,l=n;var g=class{constructor(e){this.config=e,this.connection=null,this.channel=null,this.amqpLink="",this.reconnectInProgress=!1,this.reconnectAttempts=0,this.maxReconnectAttempts=e.maxReconnectAttempts||10}setAmqpLink(e){this.amqpLink=e}async initialize(){const{channelName:e,durable:t,prefetch:s,heartbeat:n,timeout:i,initHook:o,reconnectDelay:a}=this.config;try{return this.connection=await r.connect(this.amqpLink,{heartbeat:n,timeout:i}),this.channel=await this.connection.createChannel(),await this.channel.assertQueue(e,{durable:t}),await this.channel.prefetch(s),await o({channel:this.channel,connection:this.connection}),h.log(`已连接到RabbitMQ,频道: ${e}`),this._setupConnectionEvents(),this.channel}catch(e){throw h.error("初始化RabbitMQ连接时出错:",e),e}}async reconnect(){if(this.reconnectInProgress)return h.log("重连已在进行中,跳过此次重连请求"),this.channel;if(this.reconnectAttempts>=this.maxReconnectAttempts)return h.error(`❌ 已达到最大重连次数 ${this.maxReconnectAttempts},停止重连`),h.error("请检查 RabbitMQ 服务状态或网络连接"),null;this.reconnectInProgress=!0,this.reconnectAttempts++;try{h.error(`🔄 连接丢失,正在尝试第 ${this.reconnectAttempts}/${this.maxReconnectAttempts} 次重连...`),await this._cleanupOldChannel();const e=(this.config.reconnectDelay||5e3)/1e3;return await l.sleep(e),await this.initialize(),this.reconnectAttempts=0,h.log(`✅ 已重新连接到RabbitMQ,频道: ${this.config.channelName}`),this.channel}catch(e){if(h.error(`❌ 第 ${this.reconnectAttempts} 次重连失败:`,e.message),this.reconnectAttempts<this.maxReconnectAttempts){const e=this.config.reconnectDelay||5e3;setTimeout(()=>{this.reconnectInProgress=!1,this.reconnect()},e)}else h.error("❌ 已达到最大重连次数,停止重连");throw e}finally{this.reconnectInProgress=!1}}getChannel(){return this.channel}getConnection(){return this.connection}isConnected(){return this.connection&&this.channel&&!this.connection.connection.destroyed}async close(){try{this.channel&&(await this.channel.close(),this.channel=null),this.connection&&(await this.connection.close(),this.connection=null),h.log("RabbitMQ连接已关闭")}catch(e){h.error("关闭连接时出错:",e.message)}}_setupConnectionEvents(){this.connection.on("error",e=>{h.error("连接错误:",e.message),this.reconnect().catch(e=>{h.error("重连失败:",e.message)})}),this.connection.on("close",()=>{h.error("与RabbitMQ的连接已关闭"),this.reconnect().catch(e=>{h.error("重连失败:",e.message)})})}async _cleanupOldChannel(){if(this.channel){try{await this.channel.close()}catch(e){h.log("关闭旧channel时出错:",e.message)}this.channel=null}}getStats(){return{isConnected:this.isConnected(),reconnectAttempts:this.reconnectAttempts,maxReconnectAttempts:this.maxReconnectAttempts,reconnectInProgress:this.reconnectInProgress}}};const u=t,m=n;var p=class{constructor(e){this.config=e,this.processingMessages=new Set}async startConsuming(e){const{channelName:t,callback:s,delay:n}=this.config;return u.log(`开始消费: ${t}`),await e.consume(t,async t=>{null!==t?await this._handleMessage(t,e,s,n):u.log("收到null消息,队列可能为空或连接中断")},{noAck:!1}),()=>{this.processingMessages.clear(),u.log("已清理消息处理状态")}}async _handleMessage(e,t,s,n){const i=e.fields.deliveryTag;if(this.processingMessages.has(i))u.log(`消息 ${i} 已在处理中,跳过`);else{if(this.processingMessages.add(i),!this._isValidMessageContent(e))return u.log(`⚠️ 收到无效消息 ${i},内容为空或无法解析,自动确认以防止阻塞`),void this._acknowledgeMessage(e,t,i,0);try{const o=JSON.parse(e.content.toString());u.log(`🪴 队列收到消息: ${JSON.stringify(o)}`);const a=Date.now(),c=new Promise((e,t)=>{setTimeout(()=>{t(new Error(`消息处理超时 (${this.config.messageTimeout}ms)`))},this.config.messageTimeout)});try{await Promise.race([s(o),c]);const r=Date.now()-a;u.log(`☘️ 消息处理完成,延迟: ${n}ms,总时间: ${r}ms`),this._acknowledgeMessage(e,t,i,n)}catch(s){s.message.includes("超时")?u.error(`⏰ 消息 ${i} 处理超时 (${this.config.messageTimeout}ms)`):u.log("‼️ 处理消息返回错误:",s.message),await this._rejectMessage(e,t,i)}}catch(s){u.log("‼️ 处理消息时出错:",s.message),await this._rejectMessage(e,t,i)}}}_isValidMessageContent(e){try{if(!e||!e.content)return!1;const t=e.content.toString();return!(!t||""===t.trim())&&("null"!==t.toLowerCase()&&"undefined"!==t.toLowerCase()&&(JSON.parse(t),!0))}catch(e){return!1}}_acknowledgeMessage(e,t,s,n){this.processingMessages.has(s)&&setTimeout(()=>{try{t.ack(e),this.processingMessages.delete(s),u.log(`✅ 消息 ${s} 已确认`)}catch(e){u.error(`ACK消息 ${s} 时出错:`,e.message),this.processingMessages.delete(s)}},n)}async _rejectMessage(e,t,s){if(await m.sleep(5),this.processingMessages.has(s))try{t.reject(e,!0),this.processingMessages.delete(s),u.log(`❌ 消息 ${s} 已拒绝并重新排队`)}catch(e){u.error(`拒绝消息 ${s} 时出错:`,e.message),this.processingMessages.delete(s)}}clearProcessingMessages(){this.processingMessages.clear(),u.log("已清理所有消息处理状态")}getProcessingCount(){return this.processingMessages.size}};const d=t;const f=c,M=g,w=p,y=class{constructor(e){this.config=e,this.intervalId=null,this.isRunning=!1}start(e){const{autoReload:t,channelName:s,queryHook:n}=this.config;t<=0?d.log("自动重载功能未启用"):this.isRunning?d.log("自动重载监控已在运行中"):(this.isRunning=!0,d.log(`启动队列监控,间隔: ${t}ms`),this.intervalId=setInterval(async()=>{try{await this._checkQueueStatus(e,s,n)}catch(e){d.error("队列状态检查时出错:",e.message)}},t))}stop(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=null,this.isRunning=!1,d.log("自动重载监控已停止"))}restart(e){this.stop(),this.start(e)}isActive(){return this.isRunning}async _checkQueueStatus(e,t,s){try{const{messageCount:n}=await e.checkQueue(t),i=await s();d.log(`队列 ${t} 中有 ${n} 条消息,钩子状态: ${i?1:0}`)}catch(e){d.error("检查队列状态时出错:",e.message)}}getConfig(){return{autoReload:this.config.autoReload,isRunning:this.isRunning,intervalId:null!==this.intervalId}}},P=t;class AMQPInitializer{constructor(){this.configResolver=new f,this.connectionManager=null,this.messageProcessor=null,this.autoReloader=null,this.config=null}async init(e={}){try{this.config=this.configResolver.resolveConfig(e),P.log("配置解析完成");const t=await this.configResolver.resolveAmqpLink(this.config.amqpAutoLink,this.config.amqpLink);this.connectionManager=new M(this.config),this.messageProcessor=new w(this.config),this.autoReloader=new y(this.config),this.connectionManager.setAmqpLink(t);const s=await this.connectionManager.initialize();this._setupReconnectHandler(),await this.messageProcessor.startConsuming(s),P.log("消息处理器已启动"),this.autoReloader.start(s),this.config.finish(),P.log("AMQP初始化完成")}catch(e){throw P.error("AMQP初始化失败:",e.message),e}}_setupReconnectHandler(){const e=this.connectionManager.reconnect.bind(this.connectionManager);this.connectionManager.reconnect=async()=>{try{const t=await e();return this.messageProcessor.clearProcessingMessages(),await this.messageProcessor.startConsuming(t),P.log("重连后消息处理器已重新启动"),this.autoReloader.restart(t),P.log("重连后自动重载监控已重新启动"),t}catch(e){throw P.error("重连处理失败:",e.message),e}}}getStatus(){return{isConnected:!!this.connectionManager&&this.connectionManager.isConnected(),processingCount:this.messageProcessor?this.messageProcessor.getProcessingCount():0,autoReloaderActive:!!this.autoReloader&&this.autoReloader.isActive(),channelName:this.config?this.config.channelName:null}}async shutdown(){try{P.log("开始优雅关闭AMQP连接..."),this.autoReloader&&this.autoReloader.stop(),this.messageProcessor&&this.messageProcessor.clearProcessingMessages(),this.connectionManager&&await this.connectionManager.close(),P.log("AMQP连接已优雅关闭")}catch(e){P.error("关闭AMQP连接时出错:",e.message)}}}var R=i({async init(e){const t=new AMQPInitializer;return await t.init(e)},AMQPInitializer:AMQPInitializer});export{R as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amqplib-init.esm.js","sources":["../module/ConfigResolver.js","../module/ConnectionManager.js","../module/MessageProcessor.js","../module/AutoReloader.js","../index.js"],"sourcesContent":["const axios = require('axios');\nconst log = require('chalk-style');\n\n/**\n * 配置解析器模块\n * 负责处理配置参数和自动获取RabbitMQ连接信息\n */\nclass ConfigResolver {\n constructor() {\n this.defaultConfig = {\n channelName: 'node-test-channel',\n prefetch: 1,\n callback: () => {},\n finish: () => {},\n amqpLink: '',\n amqpAutoLink: '',\n heartbeat: 60, // 增加心跳间隔到60秒,避免长时间处理时连接断开\n timeout: 300000, // 增加连接超时到5分钟(300秒)\n delay: 0,\n autoReload: 0,\n queryHook: () => {},\n initHook: () => {},\n durable: true,\n // 新增配置项 - 支持15分钟长任务\n messageTimeout: 900000, // 消息处理超时15分钟(900秒)\n reconnectDelay: 5000, // 重连延迟5秒\n maxReconnectAttempts: 10 // 最大重连次数\n };\n }\n\n /**\n * 解析和合并配置参数\n * @param {Object} options - 用户传入的配置选项\n * @returns {Object} 合并后的完整配置\n */\n resolveConfig(options = {}) {\n return { ...this.defaultConfig, ...options };\n }\n\n /**\n * 自动获取RabbitMQ连接信息\n * @param {string} amqpAutoLink - 自动获取连接信息的HTTPS链接\n * @param {string} fallbackAmqpLink - 备用连接地址\n * @returns {Promise<string>} 最终使用的连接地址\n */\n async resolveAmqpLink(amqpAutoLink, fallbackAmqpLink) {\n if (!amqpAutoLink) {\n return fallbackAmqpLink;\n }\n\n try {\n log.log(`正在从 ${amqpAutoLink} 获取连接信息...`);\n const response = await axios.post(amqpAutoLink);\n const { info } = response.data;\n \n if (this._validateConnectionInfo(info)) {\n const finalAmqpLink = `amqp://${info.AMQPLIB_USER}:${info.AMQPLIB_PWD}@${info.AMQPLIB_PUB}:${info.AMQPLIB_PORT}`;\n log.log(`✅ 自动获取连接信息成功: ${finalAmqpLink}`);\n return finalAmqpLink;\n } else {\n log.error('❌ 获取的连接信息不完整,使用默认连接地址');\n return fallbackAmqpLink;\n }\n } catch (error) {\n log.error('❌ 获取连接信息失败:', error.message);\n log.log('使用默认连接地址继续...');\n return fallbackAmqpLink;\n }\n }\n\n /**\n * 验证连接信息的完整性\n * @param {Object} info - 连接信息对象\n * @returns {boolean} 是否包含所有必要字段\n * @private\n */\n _validateConnectionInfo(info) {\n return info && \n info.AMQPLIB_USER && \n info.AMQPLIB_PWD && \n info.AMQPLIB_PUB && \n info.AMQPLIB_PORT;\n }\n}\n\nmodule.exports = ConfigResolver; ","const amqp = require('amqplib');\nconst log = require('chalk-style');\nconst happy = require('happy-help');\n\n/**\n * 连接管理器模块\n * 负责RabbitMQ连接管理、重连逻辑、频道管理\n */\nclass ConnectionManager {\n constructor(config) {\n this.config = config;\n this.connection = null;\n this.channel = null;\n this.amqpLink = '';\n this.reconnectInProgress = false; // 防止重复重连\n this.reconnectAttempts = 0; // 重连计数器\n this.maxReconnectAttempts = config.maxReconnectAttempts || 10; // 最大重连次数\n }\n\n /**\n * 设置AMQP连接地址\n * @param {string} amqpLink - RabbitMQ连接地址\n */\n setAmqpLink(amqpLink) {\n this.amqpLink = amqpLink;\n }\n\n /**\n * 初始化连接和频道\n * @returns {Promise<Object>} 返回频道对象\n */\n async initialize() {\n const { channelName, durable, prefetch, heartbeat, timeout, initHook, reconnectDelay } = this.config;\n \n try {\n // 建立连接\n this.connection = await amqp.connect(this.amqpLink, { heartbeat, timeout });\n \n // 创建频道\n this.channel = await this.connection.createChannel();\n \n // 设置队列和预取\n await this.channel.assertQueue(channelName, { durable });\n await this.channel.prefetch(prefetch);\n \n // 执行初始化钩子\n await initHook({ channel: this.channel, connection: this.connection });\n \n log.log(`已连接到RabbitMQ,频道: ${channelName}`);\n \n // 设置连接事件监听\n this._setupConnectionEvents();\n \n return this.channel;\n } catch (error) {\n log.error('初始化RabbitMQ连接时出错:', error);\n throw error;\n }\n }\n\n /**\n * 重连逻辑\n * @returns {Promise<Object>} 返回新的频道对象\n */\n async reconnect() {\n if (this.reconnectInProgress) {\n log.log('重连已在进行中,跳过此次重连请求');\n return this.channel;\n }\n\n // 检查是否达到最大重连次数\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n log.error(`❌ 已达到最大重连次数 ${this.maxReconnectAttempts},停止重连`);\n log.error('请检查 RabbitMQ 服务状态或网络连接');\n return null;\n }\n\n this.reconnectInProgress = true;\n this.reconnectAttempts++;\n \n try {\n log.error(`🔄 连接丢失,正在尝试第 ${this.reconnectAttempts}/${this.maxReconnectAttempts} 次重连...`);\n \n // 清理旧的channel状态\n await this._cleanupOldChannel();\n \n // 等待重连间隔,使用配置的延迟时间\n const delaySeconds = (this.config.reconnectDelay || 5000) / 1000;\n await happy.sleep(delaySeconds);\n \n // 重新初始化连接\n await this.initialize();\n \n // 重连成功,重置计数器\n this.reconnectAttempts = 0;\n log.log(`✅ 已重新连接到RabbitMQ,频道: ${this.config.channelName}`);\n \n return this.channel;\n } catch (error) {\n log.error(`❌ 第 ${this.reconnectAttempts} 次重连失败:`, error.message);\n \n // 如果未达到最大次数,继续重试\n if (this.reconnectAttempts < this.maxReconnectAttempts) {\n const retryDelay = this.config.reconnectDelay || 5000;\n setTimeout(() => {\n this.reconnectInProgress = false;\n this.reconnect();\n }, retryDelay);\n } else {\n log.error('❌ 已达到最大重连次数,停止重连');\n }\n \n throw error;\n } finally {\n this.reconnectInProgress = false;\n }\n }\n\n /**\n * 获取当前频道\n * @returns {Object|null} 当前频道对象\n */\n getChannel() {\n return this.channel;\n }\n\n /**\n * 获取当前连接\n * @returns {Object|null} 当前连接对象\n */\n getConnection() {\n return this.connection;\n }\n\n /**\n * 检查连接是否正常\n * @returns {boolean} 连接状态\n */\n isConnected() {\n return this.connection && this.channel && !this.connection.connection.destroyed;\n }\n\n /**\n * 关闭连接\n * @returns {Promise<void>}\n */\n async close() {\n try {\n if (this.channel) {\n await this.channel.close();\n this.channel = null;\n }\n if (this.connection) {\n await this.connection.close();\n this.connection = null;\n }\n log.log('RabbitMQ连接已关闭');\n } catch (error) {\n log.error('关闭连接时出错:', error.message);\n }\n }\n\n /**\n * 设置连接事件监听\n * @private\n */\n _setupConnectionEvents() {\n // 连接错误处理\n this.connection.on('error', (err) => {\n log.error('连接错误:', err.message);\n this.reconnect().catch(error => {\n log.error('重连失败:', error.message);\n });\n });\n\n // 连接关闭处理\n this.connection.on('close', () => {\n log.error('与RabbitMQ的连接已关闭');\n this.reconnect().catch(error => {\n log.error('重连失败:', error.message);\n });\n });\n }\n\n /**\n * 清理旧的频道状态\n * @private\n */\n async _cleanupOldChannel() {\n if (this.channel) {\n try {\n await this.channel.close();\n } catch (e) {\n log.log('关闭旧channel时出错:', e.message);\n }\n this.channel = null;\n }\n }\n\n /**\n * 获取连接统计信息\n * @returns {Object} 连接统计\n */\n getStats() {\n return {\n isConnected: this.isConnected(),\n reconnectAttempts: this.reconnectAttempts,\n maxReconnectAttempts: this.maxReconnectAttempts,\n reconnectInProgress: this.reconnectInProgress\n };\n }\n}\n\nmodule.exports = ConnectionManager; ","const log = require('chalk-style');\nconst happy = require('happy-help');\n\n/**\n * 消息处理器模块\n * 负责消息处理、状态跟踪、ACK/REJECT逻辑\n */\nclass MessageProcessor {\n constructor(config) {\n this.config = config;\n this.processingMessages = new Set(); // 跟踪正在处理的消息\n }\n\n /**\n * 开始消费消息\n * @param {Object} channel - RabbitMQ频道\n * @returns {Promise<Function>} 返回清理函数\n */\n async startConsuming(channel) {\n const { channelName, callback, delay } = this.config;\n \n log.log(`开始消费: ${channelName}`);\n \n await channel.consume(channelName, async (msg) => {\n if (msg !== null) {\n await this._handleMessage(msg, channel, callback, delay);\n } else {\n // ✅ 修复关键bug:null消息不需要ACK操作\n log.log('收到null消息,队列可能为空或连接中断');\n // 移除错误的 channel.ack(msg) 调用\n }\n }, { noAck: false });\n \n // 返回清理函数,用于重连时清理状态\n return () => {\n this.processingMessages.clear();\n log.log('已清理消息处理状态');\n };\n }\n\n /**\n * 处理单条消息\n * @param {Object} msg - RabbitMQ消息对象\n * @param {Object} channel - RabbitMQ频道\n * @param {Function} callback - 消息处理回调函数\n * @param {number} delay - 延迟ACK时间\n * @private\n */\n async _handleMessage(msg, channel, callback, delay) {\n const deliveryTag = msg.fields.deliveryTag;\n \n // 检查消息是否已在处理中\n if (this.processingMessages.has(deliveryTag)) {\n log.log(`消息 ${deliveryTag} 已在处理中,跳过`);\n return;\n }\n \n this.processingMessages.add(deliveryTag);\n \n // 检查消息内容有效性,对无效消息直接确认\n if (!this._isValidMessageContent(msg)) {\n log.log(`⚠️ 收到无效消息 ${deliveryTag},内容为空或无法解析,自动确认以防止阻塞`);\n this._acknowledgeMessage(msg, channel, deliveryTag, 0); // 立即确认无效消息\n return;\n }\n \n try {\n const content = JSON.parse(msg.content.toString());\n log.log(`🪴 队列收到消息: ${JSON.stringify(content)}`);\n const startTime = Date.now();\n \n // 创建超时 Promise\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => {\n reject(new Error(`消息处理超时 (${this.config.messageTimeout}ms)`));\n }, this.config.messageTimeout);\n });\n \n // 使用 Promise.race 实现超时控制\n try {\n await Promise.race([\n callback(content),\n timeoutPromise\n ]);\n \n const endTime = Date.now() - startTime;\n log.log(`☘️ 消息处理完成,延迟: ${delay}ms,总时间: ${endTime}ms`);\n this._acknowledgeMessage(msg, channel, deliveryTag, delay);\n \n } catch (callbackError) {\n if (callbackError.message.includes('超时')) {\n log.error(`⏰ 消息 ${deliveryTag} 处理超时 (${this.config.messageTimeout}ms)`);\n } else {\n log.log('‼️ 处理消息返回错误:', callbackError.message);\n }\n await this._rejectMessage(msg, channel, deliveryTag);\n }\n \n } catch (e) {\n log.log('‼️ 处理消息时出错:', e.message);\n await this._rejectMessage(msg, channel, deliveryTag);\n }\n }\n\n /**\n * 检查消息内容是否有效\n * @param {Object} msg - RabbitMQ消息对象\n * @returns {boolean} 消息内容是否有效\n * @private\n */\n _isValidMessageContent(msg) {\n try {\n // 检查消息对象是否存在\n if (!msg || !msg.content) {\n return false;\n }\n \n // 获取消息内容字符串\n const contentStr = msg.content.toString();\n \n // 检查内容是否为空或只包含空白字符\n if (!contentStr || contentStr.trim() === '') {\n return false;\n }\n \n // 检查是否为null字符串\n if (contentStr.toLowerCase() === 'null' || contentStr.toLowerCase() === 'undefined') {\n return false;\n }\n \n // 尝试解析JSON,如果失败则认为无效\n JSON.parse(contentStr);\n return true;\n } catch (error) {\n // JSON解析失败,认为消息无效\n return false;\n }\n }\n\n /**\n * 确认消息\n * @param {Object} msg - RabbitMQ消息对象\n * @param {Object} channel - RabbitMQ频道\n * @param {string} deliveryTag - 消息标签\n * @param {number} delay - 延迟时间\n * @private\n */\n _acknowledgeMessage(msg, channel, deliveryTag, delay) {\n // 确保消息还在处理集合中再进行ACK\n if (this.processingMessages.has(deliveryTag)) {\n setTimeout(() => {\n try {\n channel.ack(msg);\n this.processingMessages.delete(deliveryTag);\n log.log(`✅ 消息 ${deliveryTag} 已确认`);\n } catch (ackError) {\n log.error(`ACK消息 ${deliveryTag} 时出错:`, ackError.message);\n this.processingMessages.delete(deliveryTag);\n }\n }, delay);\n }\n }\n\n /**\n * 拒绝消息并重新排队\n * @param {Object} msg - RabbitMQ消息对象\n * @param {Object} channel - RabbitMQ频道\n * @param {string} deliveryTag - 消息标签\n * @private\n */\n async _rejectMessage(msg, channel, deliveryTag) {\n await happy.sleep(5);\n \n if (this.processingMessages.has(deliveryTag)) {\n try {\n channel.reject(msg, true);\n this.processingMessages.delete(deliveryTag);\n log.log(`❌ 消息 ${deliveryTag} 已拒绝并重新排队`);\n } catch (rejectError) {\n log.error(`拒绝消息 ${deliveryTag} 时出错:`, rejectError.message);\n this.processingMessages.delete(deliveryTag);\n }\n }\n }\n\n /**\n * 清理所有处理中的消息状态\n */\n clearProcessingMessages() {\n this.processingMessages.clear();\n log.log('已清理所有消息处理状态');\n }\n\n /**\n * 获取当前处理中的消息数量\n * @returns {number} 处理中的消息数量\n */\n getProcessingCount() {\n return this.processingMessages.size;\n }\n}\n\nmodule.exports = MessageProcessor; ","const log = require('chalk-style');\n\n/**\n * 自动重载器模块\n * 负责监控队列状态(已移除 PM2 重启功能,改用 Supervisor 管理)\n */\nclass AutoReloader {\n constructor(config) {\n this.config = config;\n this.intervalId = null;\n this.isRunning = false;\n }\n\n /**\n * 启动自动重载监控\n * @param {Object} channel - RabbitMQ频道\n */\n start(channel) {\n const { autoReload, channelName, queryHook } = this.config;\n \n if (autoReload <= 0) {\n log.log('自动重载功能未启用');\n return;\n }\n\n if (this.isRunning) {\n log.log('自动重载监控已在运行中');\n return;\n }\n\n this.isRunning = true;\n log.log(`启动队列监控,间隔: ${autoReload}ms`);\n\n this.intervalId = setInterval(async () => {\n try {\n await this._checkQueueStatus(channel, channelName, queryHook);\n } catch (error) {\n log.error('队列状态检查时出错:', error.message);\n }\n }, autoReload);\n }\n\n /**\n * 停止自动重载监控\n */\n stop() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n this.isRunning = false;\n log.log('自动重载监控已停止');\n }\n }\n\n /**\n * 重启自动重载监控(用于重连后)\n * @param {Object} channel - 新的RabbitMQ频道\n */\n restart(channel) {\n this.stop();\n this.start(channel);\n }\n\n /**\n * 获取监控状态\n * @returns {boolean} 是否正在运行\n */\n isActive() {\n return this.isRunning;\n }\n\n /**\n * 检查队列状态(仅监控,不执行重启)\n * @param {Object} channel - RabbitMQ频道\n * @param {string} channelName - 频道名称\n * @param {Function} queryHook - 查询钩子函数\n * @private\n */\n async _checkQueueStatus(channel, channelName, queryHook) {\n try {\n // 检查队列中的消息数量\n const { messageCount } = await channel.checkQueue(channelName);\n \n // 执行查询钩子\n const hookResult = await queryHook();\n \n log.log(`队列 ${channelName} 中有 ${messageCount} 条消息,钩子状态: ${hookResult ? 1 : 0}`);\n \n // 注意: 已移除自动重启功能\n // 如需重启服务,请使用 Supervisor: supervisorctl restart <service-name>\n } catch (error) {\n log.error('检查队列状态时出错:', error.message);\n }\n }\n\n /**\n * 获取当前配置信息\n * @returns {Object} 配置信息\n */\n getConfig() {\n return {\n autoReload: this.config.autoReload,\n isRunning: this.isRunning,\n intervalId: this.intervalId !== null\n };\n }\n}\n\nmodule.exports = AutoReloader; ","const ConfigResolver = require('./module/ConfigResolver');\nconst ConnectionManager = require('./module/ConnectionManager');\nconst MessageProcessor = require('./module/MessageProcessor');\nconst AutoReloader = require('./module/AutoReloader');\nconst log = require('chalk-style');\n\n/**\n * AMQP初始化器主类\n * 协调各个模块完成RabbitMQ的初始化和消息处理\n */\nclass AMQPInitializer {\n constructor() {\n this.configResolver = new ConfigResolver();\n this.connectionManager = null;\n this.messageProcessor = null;\n this.autoReloader = null;\n this.config = null;\n }\n\n /**\n * 初始化AMQP连接和消息处理\n * @param {Object} options - 配置选项\n * @returns {Promise<void>}\n */\n async init(options = {}) {\n try {\n // 1. 解析配置\n this.config = this.configResolver.resolveConfig(options);\n log.log('配置解析完成');\n\n // 2. 解析连接地址\n const amqpLink = await this.configResolver.resolveAmqpLink(\n this.config.amqpAutoLink,\n this.config.amqpLink\n );\n\n // 3. 初始化各个模块\n this.connectionManager = new ConnectionManager(this.config);\n this.messageProcessor = new MessageProcessor(this.config);\n this.autoReloader = new AutoReloader(this.config);\n\n // 4. 设置连接地址并初始化连接\n this.connectionManager.setAmqpLink(amqpLink);\n const channel = await this.connectionManager.initialize();\n\n // 5. 重新定义重连逻辑,确保重连后重新启动消息处理和自动重载\n this._setupReconnectHandler();\n\n // 6. 启动消息处理\n await this.messageProcessor.startConsuming(channel);\n log.log('消息处理器已启动');\n\n // 7. 启动自动重载监控\n this.autoReloader.start(channel);\n\n // 8. 执行初始化完成回调\n this.config.finish();\n \n log.log('AMQP初始化完成');\n } catch (error) {\n log.error('AMQP初始化失败:', error.message);\n throw error;\n }\n }\n\n /**\n * 设置重连处理器\n * 确保重连后各个模块能够正确重新启动\n * @private\n */\n _setupReconnectHandler() {\n const originalReconnect = this.connectionManager.reconnect.bind(this.connectionManager);\n \n this.connectionManager.reconnect = async () => {\n try {\n // 执行原始重连逻辑\n const newChannel = await originalReconnect();\n \n // 重连后重新启动消息处理\n this.messageProcessor.clearProcessingMessages();\n await this.messageProcessor.startConsuming(newChannel);\n log.log('重连后消息处理器已重新启动');\n \n // 重连后重新启动自动重载监控\n this.autoReloader.restart(newChannel);\n log.log('重连后自动重载监控已重新启动');\n \n return newChannel;\n } catch (error) {\n log.error('重连处理失败:', error.message);\n throw error;\n }\n };\n }\n\n /**\n * 获取当前状态信息\n * @returns {Object} 状态信息\n */\n getStatus() {\n return {\n isConnected: this.connectionManager ? this.connectionManager.isConnected() : false,\n processingCount: this.messageProcessor ? this.messageProcessor.getProcessingCount() : 0,\n autoReloaderActive: this.autoReloader ? this.autoReloader.isActive() : false,\n channelName: this.config ? this.config.channelName : null\n };\n }\n\n /**\n * 优雅关闭\n * @returns {Promise<void>}\n */\n async shutdown() {\n try {\n log.log('开始优雅关闭AMQP连接...');\n \n // 停止自动重载监控\n if (this.autoReloader) {\n this.autoReloader.stop();\n }\n \n // 清理消息处理状态\n if (this.messageProcessor) {\n this.messageProcessor.clearProcessingMessages();\n }\n \n // 关闭连接\n if (this.connectionManager) {\n await this.connectionManager.close();\n }\n \n log.log('AMQP连接已优雅关闭');\n } catch (error) {\n log.error('关闭AMQP连接时出错:', error.message);\n }\n }\n}\n\n// 导出兼容的API\nmodule.exports = {\n /**\n * 初始化函数 - 保持向后兼容\n * @param {Object} options - 配置选项\n * @returns {Promise<void>}\n */\n async init(options) {\n const initializer = new AMQPInitializer();\n return await initializer.init(options);\n },\n\n // 导出类,供需要更多控制的用户使用\n AMQPInitializer\n};\n"],"names":["log","ConfigResolver","require$$0","happy","ConnectionManager","require$$1","MessageProcessor","AutoReloader","require$$2","require$$3","require$$4"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("axios"),require("chalk-style"),require("amqplib"),require("happy-help")):"function"==typeof define&&define.amd?define(["axios","chalk-style","amqplib","happy-help"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).AmqplibInit=t(e.require$$0,e.require$$1,e.require$$0$1,e.require$$2)}(this,function(e,t,s,n){"use strict";function i(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}const o=e,a=t;var c=class{constructor(){this.defaultConfig={channelName:"node-test-channel",prefetch:1,callback:()=>{},finish:()=>{},amqpLink:"",amqpAutoLink:"",heartbeat:60,timeout:3e5,delay:0,autoReload:0,queryHook:()=>{},initHook:()=>{},durable:!0,messageTimeout:9e5,reconnectDelay:5e3,maxReconnectAttempts:10}}resolveConfig(e={}){return{...this.defaultConfig,...e}}async resolveAmqpLink(e,t){if(!e)return t;try{a.log(`正在从 ${e} 获取连接信息...`);const s=await o.post(e),{info:n}=s.data;if(this._validateConnectionInfo(n)){const e=`amqp://${n.AMQPLIB_USER}:${n.AMQPLIB_PWD}@${n.AMQPLIB_PUB}:${n.AMQPLIB_PORT}`;return a.log(`✅ 自动获取连接信息成功: ${e}`),e}return a.error("❌ 获取的连接信息不完整,使用默认连接地址"),t}catch(e){return a.error("❌ 获取连接信息失败:",e.message),a.log("使用默认连接地址继续..."),t}}_validateConnectionInfo(e){return e&&e.AMQPLIB_USER&&e.AMQPLIB_PWD&&e.AMQPLIB_PUB&&e.AMQPLIB_PORT}};const r=s,h=t,l=n;var g=class{constructor(e){this.config=e,this.connection=null,this.channel=null,this.amqpLink="",this.reconnectInProgress=!1,this.reconnectAttempts=0,this.maxReconnectAttempts=e.maxReconnectAttempts||10}setAmqpLink(e){this.amqpLink=e}async initialize(){const{channelName:e,durable:t,prefetch:s,heartbeat:n,timeout:i,initHook:o,reconnectDelay:a}=this.config;try{return this.connection=await r.connect(this.amqpLink,{heartbeat:n,timeout:i}),this.channel=await this.connection.createChannel(),await this.channel.assertQueue(e,{durable:t}),await this.channel.prefetch(s),await o({channel:this.channel,connection:this.connection}),h.log(`已连接到RabbitMQ,频道: ${e}`),this._setupConnectionEvents(),this.channel}catch(e){throw h.error("初始化RabbitMQ连接时出错:",e),e}}async reconnect(){if(this.reconnectInProgress)return h.log("重连已在进行中,跳过此次重连请求"),this.channel;if(this.reconnectAttempts>=this.maxReconnectAttempts)return h.error(`❌ 已达到最大重连次数 ${this.maxReconnectAttempts},停止重连`),h.error("请检查 RabbitMQ 服务状态或网络连接"),null;this.reconnectInProgress=!0,this.reconnectAttempts++;try{h.error(`🔄 连接丢失,正在尝试第 ${this.reconnectAttempts}/${this.maxReconnectAttempts} 次重连...`),await this._cleanupOldChannel();const e=(this.config.reconnectDelay||5e3)/1e3;return await l.sleep(e),await this.initialize(),this.reconnectAttempts=0,h.log(`✅ 已重新连接到RabbitMQ,频道: ${this.config.channelName}`),this.channel}catch(e){if(h.error(`❌ 第 ${this.reconnectAttempts} 次重连失败:`,e.message),this.reconnectAttempts<this.maxReconnectAttempts){const e=this.config.reconnectDelay||5e3;setTimeout(()=>{this.reconnectInProgress=!1,this.reconnect()},e)}else h.error("❌ 已达到最大重连次数,停止重连");throw e}finally{this.reconnectInProgress=!1}}getChannel(){return this.channel}getConnection(){return this.connection}isConnected(){return this.connection&&this.channel&&!this.connection.connection.destroyed}async close(){try{this.channel&&(await this.channel.close(),this.channel=null),this.connection&&(await this.connection.close(),this.connection=null),h.log("RabbitMQ连接已关闭")}catch(e){h.error("关闭连接时出错:",e.message)}}_setupConnectionEvents(){this.connection.on("error",e=>{h.error("连接错误:",e.message),this.reconnect().catch(e=>{h.error("重连失败:",e.message)})}),this.connection.on("close",()=>{h.error("与RabbitMQ的连接已关闭"),this.reconnect().catch(e=>{h.error("重连失败:",e.message)})})}async _cleanupOldChannel(){if(this.channel){try{await this.channel.close()}catch(e){h.log("关闭旧channel时出错:",e.message)}this.channel=null}}getStats(){return{isConnected:this.isConnected(),reconnectAttempts:this.reconnectAttempts,maxReconnectAttempts:this.maxReconnectAttempts,reconnectInProgress:this.reconnectInProgress}}};const u=t,m=n;var p=class{constructor(e){this.config=e,this.processingMessages=new Set}async startConsuming(e){const{channelName:t,callback:s,delay:n}=this.config;return u.log(`开始消费: ${t}`),await e.consume(t,async t=>{null!==t?await this._handleMessage(t,e,s,n):u.log("收到null消息,队列可能为空或连接中断")},{noAck:!1}),()=>{this.processingMessages.clear(),u.log("已清理消息处理状态")}}async _handleMessage(e,t,s,n){const i=e.fields.deliveryTag;if(this.processingMessages.has(i))u.log(`消息 ${i} 已在处理中,跳过`);else{if(this.processingMessages.add(i),!this._isValidMessageContent(e))return u.log(`⚠️ 收到无效消息 ${i},内容为空或无法解析,自动确认以防止阻塞`),void this._acknowledgeMessage(e,t,i,0);try{const o=JSON.parse(e.content.toString());u.log(`🪴 队列收到消息: ${JSON.stringify(o)}`);const a=Date.now(),c=new Promise((e,t)=>{setTimeout(()=>{t(new Error(`消息处理超时 (${this.config.messageTimeout}ms)`))},this.config.messageTimeout)});try{await Promise.race([s(o),c]);const r=Date.now()-a;u.log(`☘️ 消息处理完成,延迟: ${n}ms,总时间: ${r}ms`),this._acknowledgeMessage(e,t,i,n)}catch(s){s.message.includes("超时")?u.error(`⏰ 消息 ${i} 处理超时 (${this.config.messageTimeout}ms)`):u.log("‼️ 处理消息返回错误:",s.message),await this._rejectMessage(e,t,i)}}catch(s){u.log("‼️ 处理消息时出错:",s.message),await this._rejectMessage(e,t,i)}}}_isValidMessageContent(e){try{if(!e||!e.content)return!1;const t=e.content.toString();return!(!t||""===t.trim())&&("null"!==t.toLowerCase()&&"undefined"!==t.toLowerCase()&&(JSON.parse(t),!0))}catch(e){return!1}}_acknowledgeMessage(e,t,s,n){this.processingMessages.has(s)&&setTimeout(()=>{try{t.ack(e),this.processingMessages.delete(s),u.log(`✅ 消息 ${s} 已确认`)}catch(e){u.error(`ACK消息 ${s} 时出错:`,e.message),this.processingMessages.delete(s)}},n)}async _rejectMessage(e,t,s){if(await m.sleep(5),this.processingMessages.has(s))try{t.reject(e,!0),this.processingMessages.delete(s),u.log(`❌ 消息 ${s} 已拒绝并重新排队`)}catch(e){u.error(`拒绝消息 ${s} 时出错:`,e.message),this.processingMessages.delete(s)}}clearProcessingMessages(){this.processingMessages.clear(),u.log("已清理所有消息处理状态")}getProcessingCount(){return this.processingMessages.size}};const d=t;const f=c,M=g,y=p,w=class{constructor(e){this.config=e,this.intervalId=null,this.isRunning=!1}start(e){const{autoReload:t,channelName:s,queryHook:n}=this.config;t<=0?d.log("自动重载功能未启用"):this.isRunning?d.log("自动重载监控已在运行中"):(this.isRunning=!0,d.log(`启动队列监控,间隔: ${t}ms`),this.intervalId=setInterval(async()=>{try{await this._checkQueueStatus(e,s,n)}catch(e){d.error("队列状态检查时出错:",e.message)}},t))}stop(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=null,this.isRunning=!1,d.log("自动重载监控已停止"))}restart(e){this.stop(),this.start(e)}isActive(){return this.isRunning}async _checkQueueStatus(e,t,s){try{const{messageCount:n}=await e.checkQueue(t),i=await s();d.log(`队列 ${t} 中有 ${n} 条消息,钩子状态: ${i?1:0}`)}catch(e){d.error("检查队列状态时出错:",e.message)}}getConfig(){return{autoReload:this.config.autoReload,isRunning:this.isRunning,intervalId:null!==this.intervalId}}},A=t;class AMQPInitializer{constructor(){this.configResolver=new f,this.connectionManager=null,this.messageProcessor=null,this.autoReloader=null,this.config=null}async init(e={}){try{this.config=this.configResolver.resolveConfig(e),A.log("配置解析完成");const t=await this.configResolver.resolveAmqpLink(this.config.amqpAutoLink,this.config.amqpLink);this.connectionManager=new M(this.config),this.messageProcessor=new y(this.config),this.autoReloader=new w(this.config),this.connectionManager.setAmqpLink(t);const s=await this.connectionManager.initialize();this._setupReconnectHandler(),await this.messageProcessor.startConsuming(s),A.log("消息处理器已启动"),this.autoReloader.start(s),this.config.finish(),A.log("AMQP初始化完成")}catch(e){throw A.error("AMQP初始化失败:",e.message),e}}_setupReconnectHandler(){const e=this.connectionManager.reconnect.bind(this.connectionManager);this.connectionManager.reconnect=async()=>{try{const t=await e();return this.messageProcessor.clearProcessingMessages(),await this.messageProcessor.startConsuming(t),A.log("重连后消息处理器已重新启动"),this.autoReloader.restart(t),A.log("重连后自动重载监控已重新启动"),t}catch(e){throw A.error("重连处理失败:",e.message),e}}}getStatus(){return{isConnected:!!this.connectionManager&&this.connectionManager.isConnected(),processingCount:this.messageProcessor?this.messageProcessor.getProcessingCount():0,autoReloaderActive:!!this.autoReloader&&this.autoReloader.isActive(),channelName:this.config?this.config.channelName:null}}async shutdown(){try{A.log("开始优雅关闭AMQP连接..."),this.autoReloader&&this.autoReloader.stop(),this.messageProcessor&&this.messageProcessor.clearProcessingMessages(),this.connectionManager&&await this.connectionManager.close(),A.log("AMQP连接已优雅关闭")}catch(e){A.error("关闭AMQP连接时出错:",e.message)}}}return i({async init(e){const t=new AMQPInitializer;return await t.init(e)},AMQPInitializer:AMQPInitializer})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amqplib-init.umd.js","sources":["../module/ConfigResolver.js","../module/ConnectionManager.js","../module/MessageProcessor.js","../module/AutoReloader.js","../index.js"],"sourcesContent":["const axios = require('axios');\nconst log = require('chalk-style');\n\n/**\n * 配置解析器模块\n * 负责处理配置参数和自动获取RabbitMQ连接信息\n */\nclass ConfigResolver {\n constructor() {\n this.defaultConfig = {\n channelName: 'node-test-channel',\n prefetch: 1,\n callback: () => {},\n finish: () => {},\n amqpLink: '',\n amqpAutoLink: '',\n heartbeat: 60, // 增加心跳间隔到60秒,避免长时间处理时连接断开\n timeout: 300000, // 增加连接超时到5分钟(300秒)\n delay: 0,\n autoReload: 0,\n queryHook: () => {},\n initHook: () => {},\n durable: true,\n // 新增配置项 - 支持15分钟长任务\n messageTimeout: 900000, // 消息处理超时15分钟(900秒)\n reconnectDelay: 5000, // 重连延迟5秒\n maxReconnectAttempts: 10 // 最大重连次数\n };\n }\n\n /**\n * 解析和合并配置参数\n * @param {Object} options - 用户传入的配置选项\n * @returns {Object} 合并后的完整配置\n */\n resolveConfig(options = {}) {\n return { ...this.defaultConfig, ...options };\n }\n\n /**\n * 自动获取RabbitMQ连接信息\n * @param {string} amqpAutoLink - 自动获取连接信息的HTTPS链接\n * @param {string} fallbackAmqpLink - 备用连接地址\n * @returns {Promise<string>} 最终使用的连接地址\n */\n async resolveAmqpLink(amqpAutoLink, fallbackAmqpLink) {\n if (!amqpAutoLink) {\n return fallbackAmqpLink;\n }\n\n try {\n log.log(`正在从 ${amqpAutoLink} 获取连接信息...`);\n const response = await axios.post(amqpAutoLink);\n const { info } = response.data;\n \n if (this._validateConnectionInfo(info)) {\n const finalAmqpLink = `amqp://${info.AMQPLIB_USER}:${info.AMQPLIB_PWD}@${info.AMQPLIB_PUB}:${info.AMQPLIB_PORT}`;\n log.log(`✅ 自动获取连接信息成功: ${finalAmqpLink}`);\n return finalAmqpLink;\n } else {\n log.error('❌ 获取的连接信息不完整,使用默认连接地址');\n return fallbackAmqpLink;\n }\n } catch (error) {\n log.error('❌ 获取连接信息失败:', error.message);\n log.log('使用默认连接地址继续...');\n return fallbackAmqpLink;\n }\n }\n\n /**\n * 验证连接信息的完整性\n * @param {Object} info - 连接信息对象\n * @returns {boolean} 是否包含所有必要字段\n * @private\n */\n _validateConnectionInfo(info) {\n return info && \n info.AMQPLIB_USER && \n info.AMQPLIB_PWD && \n info.AMQPLIB_PUB && \n info.AMQPLIB_PORT;\n }\n}\n\nmodule.exports = ConfigResolver; ","const amqp = require('amqplib');\nconst log = require('chalk-style');\nconst happy = require('happy-help');\n\n/**\n * 连接管理器模块\n * 负责RabbitMQ连接管理、重连逻辑、频道管理\n */\nclass ConnectionManager {\n constructor(config) {\n this.config = config;\n this.connection = null;\n this.channel = null;\n this.amqpLink = '';\n this.reconnectInProgress = false; // 防止重复重连\n this.reconnectAttempts = 0; // 重连计数器\n this.maxReconnectAttempts = config.maxReconnectAttempts || 10; // 最大重连次数\n }\n\n /**\n * 设置AMQP连接地址\n * @param {string} amqpLink - RabbitMQ连接地址\n */\n setAmqpLink(amqpLink) {\n this.amqpLink = amqpLink;\n }\n\n /**\n * 初始化连接和频道\n * @returns {Promise<Object>} 返回频道对象\n */\n async initialize() {\n const { channelName, durable, prefetch, heartbeat, timeout, initHook, reconnectDelay } = this.config;\n \n try {\n // 建立连接\n this.connection = await amqp.connect(this.amqpLink, { heartbeat, timeout });\n \n // 创建频道\n this.channel = await this.connection.createChannel();\n \n // 设置队列和预取\n await this.channel.assertQueue(channelName, { durable });\n await this.channel.prefetch(prefetch);\n \n // 执行初始化钩子\n await initHook({ channel: this.channel, connection: this.connection });\n \n log.log(`已连接到RabbitMQ,频道: ${channelName}`);\n \n // 设置连接事件监听\n this._setupConnectionEvents();\n \n return this.channel;\n } catch (error) {\n log.error('初始化RabbitMQ连接时出错:', error);\n throw error;\n }\n }\n\n /**\n * 重连逻辑\n * @returns {Promise<Object>} 返回新的频道对象\n */\n async reconnect() {\n if (this.reconnectInProgress) {\n log.log('重连已在进行中,跳过此次重连请求');\n return this.channel;\n }\n\n // 检查是否达到最大重连次数\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n log.error(`❌ 已达到最大重连次数 ${this.maxReconnectAttempts},停止重连`);\n log.error('请检查 RabbitMQ 服务状态或网络连接');\n return null;\n }\n\n this.reconnectInProgress = true;\n this.reconnectAttempts++;\n \n try {\n log.error(`🔄 连接丢失,正在尝试第 ${this.reconnectAttempts}/${this.maxReconnectAttempts} 次重连...`);\n \n // 清理旧的channel状态\n await this._cleanupOldChannel();\n \n // 等待重连间隔,使用配置的延迟时间\n const delaySeconds = (this.config.reconnectDelay || 5000) / 1000;\n await happy.sleep(delaySeconds);\n \n // 重新初始化连接\n await this.initialize();\n \n // 重连成功,重置计数器\n this.reconnectAttempts = 0;\n log.log(`✅ 已重新连接到RabbitMQ,频道: ${this.config.channelName}`);\n \n return this.channel;\n } catch (error) {\n log.error(`❌ 第 ${this.reconnectAttempts} 次重连失败:`, error.message);\n \n // 如果未达到最大次数,继续重试\n if (this.reconnectAttempts < this.maxReconnectAttempts) {\n const retryDelay = this.config.reconnectDelay || 5000;\n setTimeout(() => {\n this.reconnectInProgress = false;\n this.reconnect();\n }, retryDelay);\n } else {\n log.error('❌ 已达到最大重连次数,停止重连');\n }\n \n throw error;\n } finally {\n this.reconnectInProgress = false;\n }\n }\n\n /**\n * 获取当前频道\n * @returns {Object|null} 当前频道对象\n */\n getChannel() {\n return this.channel;\n }\n\n /**\n * 获取当前连接\n * @returns {Object|null} 当前连接对象\n */\n getConnection() {\n return this.connection;\n }\n\n /**\n * 检查连接是否正常\n * @returns {boolean} 连接状态\n */\n isConnected() {\n return this.connection && this.channel && !this.connection.connection.destroyed;\n }\n\n /**\n * 关闭连接\n * @returns {Promise<void>}\n */\n async close() {\n try {\n if (this.channel) {\n await this.channel.close();\n this.channel = null;\n }\n if (this.connection) {\n await this.connection.close();\n this.connection = null;\n }\n log.log('RabbitMQ连接已关闭');\n } catch (error) {\n log.error('关闭连接时出错:', error.message);\n }\n }\n\n /**\n * 设置连接事件监听\n * @private\n */\n _setupConnectionEvents() {\n // 连接错误处理\n this.connection.on('error', (err) => {\n log.error('连接错误:', err.message);\n this.reconnect().catch(error => {\n log.error('重连失败:', error.message);\n });\n });\n\n // 连接关闭处理\n this.connection.on('close', () => {\n log.error('与RabbitMQ的连接已关闭');\n this.reconnect().catch(error => {\n log.error('重连失败:', error.message);\n });\n });\n }\n\n /**\n * 清理旧的频道状态\n * @private\n */\n async _cleanupOldChannel() {\n if (this.channel) {\n try {\n await this.channel.close();\n } catch (e) {\n log.log('关闭旧channel时出错:', e.message);\n }\n this.channel = null;\n }\n }\n\n /**\n * 获取连接统计信息\n * @returns {Object} 连接统计\n */\n getStats() {\n return {\n isConnected: this.isConnected(),\n reconnectAttempts: this.reconnectAttempts,\n maxReconnectAttempts: this.maxReconnectAttempts,\n reconnectInProgress: this.reconnectInProgress\n };\n }\n}\n\nmodule.exports = ConnectionManager; ","const log = require('chalk-style');\nconst happy = require('happy-help');\n\n/**\n * 消息处理器模块\n * 负责消息处理、状态跟踪、ACK/REJECT逻辑\n */\nclass MessageProcessor {\n constructor(config) {\n this.config = config;\n this.processingMessages = new Set(); // 跟踪正在处理的消息\n }\n\n /**\n * 开始消费消息\n * @param {Object} channel - RabbitMQ频道\n * @returns {Promise<Function>} 返回清理函数\n */\n async startConsuming(channel) {\n const { channelName, callback, delay } = this.config;\n \n log.log(`开始消费: ${channelName}`);\n \n await channel.consume(channelName, async (msg) => {\n if (msg !== null) {\n await this._handleMessage(msg, channel, callback, delay);\n } else {\n // ✅ 修复关键bug:null消息不需要ACK操作\n log.log('收到null消息,队列可能为空或连接中断');\n // 移除错误的 channel.ack(msg) 调用\n }\n }, { noAck: false });\n \n // 返回清理函数,用于重连时清理状态\n return () => {\n this.processingMessages.clear();\n log.log('已清理消息处理状态');\n };\n }\n\n /**\n * 处理单条消息\n * @param {Object} msg - RabbitMQ消息对象\n * @param {Object} channel - RabbitMQ频道\n * @param {Function} callback - 消息处理回调函数\n * @param {number} delay - 延迟ACK时间\n * @private\n */\n async _handleMessage(msg, channel, callback, delay) {\n const deliveryTag = msg.fields.deliveryTag;\n \n // 检查消息是否已在处理中\n if (this.processingMessages.has(deliveryTag)) {\n log.log(`消息 ${deliveryTag} 已在处理中,跳过`);\n return;\n }\n \n this.processingMessages.add(deliveryTag);\n \n // 检查消息内容有效性,对无效消息直接确认\n if (!this._isValidMessageContent(msg)) {\n log.log(`⚠️ 收到无效消息 ${deliveryTag},内容为空或无法解析,自动确认以防止阻塞`);\n this._acknowledgeMessage(msg, channel, deliveryTag, 0); // 立即确认无效消息\n return;\n }\n \n try {\n const content = JSON.parse(msg.content.toString());\n log.log(`🪴 队列收到消息: ${JSON.stringify(content)}`);\n const startTime = Date.now();\n \n // 创建超时 Promise\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => {\n reject(new Error(`消息处理超时 (${this.config.messageTimeout}ms)`));\n }, this.config.messageTimeout);\n });\n \n // 使用 Promise.race 实现超时控制\n try {\n await Promise.race([\n callback(content),\n timeoutPromise\n ]);\n \n const endTime = Date.now() - startTime;\n log.log(`☘️ 消息处理完成,延迟: ${delay}ms,总时间: ${endTime}ms`);\n this._acknowledgeMessage(msg, channel, deliveryTag, delay);\n \n } catch (callbackError) {\n if (callbackError.message.includes('超时')) {\n log.error(`⏰ 消息 ${deliveryTag} 处理超时 (${this.config.messageTimeout}ms)`);\n } else {\n log.log('‼️ 处理消息返回错误:', callbackError.message);\n }\n await this._rejectMessage(msg, channel, deliveryTag);\n }\n \n } catch (e) {\n log.log('‼️ 处理消息时出错:', e.message);\n await this._rejectMessage(msg, channel, deliveryTag);\n }\n }\n\n /**\n * 检查消息内容是否有效\n * @param {Object} msg - RabbitMQ消息对象\n * @returns {boolean} 消息内容是否有效\n * @private\n */\n _isValidMessageContent(msg) {\n try {\n // 检查消息对象是否存在\n if (!msg || !msg.content) {\n return false;\n }\n \n // 获取消息内容字符串\n const contentStr = msg.content.toString();\n \n // 检查内容是否为空或只包含空白字符\n if (!contentStr || contentStr.trim() === '') {\n return false;\n }\n \n // 检查是否为null字符串\n if (contentStr.toLowerCase() === 'null' || contentStr.toLowerCase() === 'undefined') {\n return false;\n }\n \n // 尝试解析JSON,如果失败则认为无效\n JSON.parse(contentStr);\n return true;\n } catch (error) {\n // JSON解析失败,认为消息无效\n return false;\n }\n }\n\n /**\n * 确认消息\n * @param {Object} msg - RabbitMQ消息对象\n * @param {Object} channel - RabbitMQ频道\n * @param {string} deliveryTag - 消息标签\n * @param {number} delay - 延迟时间\n * @private\n */\n _acknowledgeMessage(msg, channel, deliveryTag, delay) {\n // 确保消息还在处理集合中再进行ACK\n if (this.processingMessages.has(deliveryTag)) {\n setTimeout(() => {\n try {\n channel.ack(msg);\n this.processingMessages.delete(deliveryTag);\n log.log(`✅ 消息 ${deliveryTag} 已确认`);\n } catch (ackError) {\n log.error(`ACK消息 ${deliveryTag} 时出错:`, ackError.message);\n this.processingMessages.delete(deliveryTag);\n }\n }, delay);\n }\n }\n\n /**\n * 拒绝消息并重新排队\n * @param {Object} msg - RabbitMQ消息对象\n * @param {Object} channel - RabbitMQ频道\n * @param {string} deliveryTag - 消息标签\n * @private\n */\n async _rejectMessage(msg, channel, deliveryTag) {\n await happy.sleep(5);\n \n if (this.processingMessages.has(deliveryTag)) {\n try {\n channel.reject(msg, true);\n this.processingMessages.delete(deliveryTag);\n log.log(`❌ 消息 ${deliveryTag} 已拒绝并重新排队`);\n } catch (rejectError) {\n log.error(`拒绝消息 ${deliveryTag} 时出错:`, rejectError.message);\n this.processingMessages.delete(deliveryTag);\n }\n }\n }\n\n /**\n * 清理所有处理中的消息状态\n */\n clearProcessingMessages() {\n this.processingMessages.clear();\n log.log('已清理所有消息处理状态');\n }\n\n /**\n * 获取当前处理中的消息数量\n * @returns {number} 处理中的消息数量\n */\n getProcessingCount() {\n return this.processingMessages.size;\n }\n}\n\nmodule.exports = MessageProcessor; ","const log = require('chalk-style');\n\n/**\n * 自动重载器模块\n * 负责监控队列状态(已移除 PM2 重启功能,改用 Supervisor 管理)\n */\nclass AutoReloader {\n constructor(config) {\n this.config = config;\n this.intervalId = null;\n this.isRunning = false;\n }\n\n /**\n * 启动自动重载监控\n * @param {Object} channel - RabbitMQ频道\n */\n start(channel) {\n const { autoReload, channelName, queryHook } = this.config;\n \n if (autoReload <= 0) {\n log.log('自动重载功能未启用');\n return;\n }\n\n if (this.isRunning) {\n log.log('自动重载监控已在运行中');\n return;\n }\n\n this.isRunning = true;\n log.log(`启动队列监控,间隔: ${autoReload}ms`);\n\n this.intervalId = setInterval(async () => {\n try {\n await this._checkQueueStatus(channel, channelName, queryHook);\n } catch (error) {\n log.error('队列状态检查时出错:', error.message);\n }\n }, autoReload);\n }\n\n /**\n * 停止自动重载监控\n */\n stop() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n this.isRunning = false;\n log.log('自动重载监控已停止');\n }\n }\n\n /**\n * 重启自动重载监控(用于重连后)\n * @param {Object} channel - 新的RabbitMQ频道\n */\n restart(channel) {\n this.stop();\n this.start(channel);\n }\n\n /**\n * 获取监控状态\n * @returns {boolean} 是否正在运行\n */\n isActive() {\n return this.isRunning;\n }\n\n /**\n * 检查队列状态(仅监控,不执行重启)\n * @param {Object} channel - RabbitMQ频道\n * @param {string} channelName - 频道名称\n * @param {Function} queryHook - 查询钩子函数\n * @private\n */\n async _checkQueueStatus(channel, channelName, queryHook) {\n try {\n // 检查队列中的消息数量\n const { messageCount } = await channel.checkQueue(channelName);\n \n // 执行查询钩子\n const hookResult = await queryHook();\n \n log.log(`队列 ${channelName} 中有 ${messageCount} 条消息,钩子状态: ${hookResult ? 1 : 0}`);\n \n // 注意: 已移除自动重启功能\n // 如需重启服务,请使用 Supervisor: supervisorctl restart <service-name>\n } catch (error) {\n log.error('检查队列状态时出错:', error.message);\n }\n }\n\n /**\n * 获取当前配置信息\n * @returns {Object} 配置信息\n */\n getConfig() {\n return {\n autoReload: this.config.autoReload,\n isRunning: this.isRunning,\n intervalId: this.intervalId !== null\n };\n }\n}\n\nmodule.exports = AutoReloader; ","const ConfigResolver = require('./module/ConfigResolver');\nconst ConnectionManager = require('./module/ConnectionManager');\nconst MessageProcessor = require('./module/MessageProcessor');\nconst AutoReloader = require('./module/AutoReloader');\nconst log = require('chalk-style');\n\n/**\n * AMQP初始化器主类\n * 协调各个模块完成RabbitMQ的初始化和消息处理\n */\nclass AMQPInitializer {\n constructor() {\n this.configResolver = new ConfigResolver();\n this.connectionManager = null;\n this.messageProcessor = null;\n this.autoReloader = null;\n this.config = null;\n }\n\n /**\n * 初始化AMQP连接和消息处理\n * @param {Object} options - 配置选项\n * @returns {Promise<void>}\n */\n async init(options = {}) {\n try {\n // 1. 解析配置\n this.config = this.configResolver.resolveConfig(options);\n log.log('配置解析完成');\n\n // 2. 解析连接地址\n const amqpLink = await this.configResolver.resolveAmqpLink(\n this.config.amqpAutoLink,\n this.config.amqpLink\n );\n\n // 3. 初始化各个模块\n this.connectionManager = new ConnectionManager(this.config);\n this.messageProcessor = new MessageProcessor(this.config);\n this.autoReloader = new AutoReloader(this.config);\n\n // 4. 设置连接地址并初始化连接\n this.connectionManager.setAmqpLink(amqpLink);\n const channel = await this.connectionManager.initialize();\n\n // 5. 重新定义重连逻辑,确保重连后重新启动消息处理和自动重载\n this._setupReconnectHandler();\n\n // 6. 启动消息处理\n await this.messageProcessor.startConsuming(channel);\n log.log('消息处理器已启动');\n\n // 7. 启动自动重载监控\n this.autoReloader.start(channel);\n\n // 8. 执行初始化完成回调\n this.config.finish();\n \n log.log('AMQP初始化完成');\n } catch (error) {\n log.error('AMQP初始化失败:', error.message);\n throw error;\n }\n }\n\n /**\n * 设置重连处理器\n * 确保重连后各个模块能够正确重新启动\n * @private\n */\n _setupReconnectHandler() {\n const originalReconnect = this.connectionManager.reconnect.bind(this.connectionManager);\n \n this.connectionManager.reconnect = async () => {\n try {\n // 执行原始重连逻辑\n const newChannel = await originalReconnect();\n \n // 重连后重新启动消息处理\n this.messageProcessor.clearProcessingMessages();\n await this.messageProcessor.startConsuming(newChannel);\n log.log('重连后消息处理器已重新启动');\n \n // 重连后重新启动自动重载监控\n this.autoReloader.restart(newChannel);\n log.log('重连后自动重载监控已重新启动');\n \n return newChannel;\n } catch (error) {\n log.error('重连处理失败:', error.message);\n throw error;\n }\n };\n }\n\n /**\n * 获取当前状态信息\n * @returns {Object} 状态信息\n */\n getStatus() {\n return {\n isConnected: this.connectionManager ? this.connectionManager.isConnected() : false,\n processingCount: this.messageProcessor ? this.messageProcessor.getProcessingCount() : 0,\n autoReloaderActive: this.autoReloader ? this.autoReloader.isActive() : false,\n channelName: this.config ? this.config.channelName : null\n };\n }\n\n /**\n * 优雅关闭\n * @returns {Promise<void>}\n */\n async shutdown() {\n try {\n log.log('开始优雅关闭AMQP连接...');\n \n // 停止自动重载监控\n if (this.autoReloader) {\n this.autoReloader.stop();\n }\n \n // 清理消息处理状态\n if (this.messageProcessor) {\n this.messageProcessor.clearProcessingMessages();\n }\n \n // 关闭连接\n if (this.connectionManager) {\n await this.connectionManager.close();\n }\n \n log.log('AMQP连接已优雅关闭');\n } catch (error) {\n log.error('关闭AMQP连接时出错:', error.message);\n }\n }\n}\n\n// 导出兼容的API\nmodule.exports = {\n /**\n * 初始化函数 - 保持向后兼容\n * @param {Object} options - 配置选项\n * @returns {Promise<void>}\n */\n async init(options) {\n const initializer = new AMQPInitializer();\n return await initializer.init(options);\n },\n\n // 导出类,供需要更多控制的用户使用\n AMQPInitializer\n};\n"],"names":["log","ConfigResolver","require$$0","happy","ConnectionManager","require$$1","MessageProcessor","AutoReloader","require$$2","require$$3","require$$4"],"mappings":";;;;;;;;;;CAAA,MAAM,KAAK,GAAG,UAAgB;CAC9B,MAAMA,KAAG,GAAG,UAAsB;;CAElC;CACA;CACA;CACA;wBACA,MAAM,cAAc,CAAC;CACrB,EAAE,WAAW,GAAG;CAChB,IAAI,IAAI,CAAC,aAAa,GAAG;CACzB,MAAM,WAAW,EAAE,mBAAmB;CACtC,MAAM,QAAQ,EAAE,CAAC;CACjB,MAAM,QAAQ,EAAE,MAAM,CAAA,CAAE;CACxB,MAAM,MAAM,EAAE,MAAM,CAAA,CAAE;CACtB,MAAM,QAAQ,EAAE,EAAE;CAClB,MAAM,YAAY,EAAE,EAAE;CACtB,MAAM,SAAS,EAAE,EAAE;CACnB,MAAM,OAAO,EAAE,MAAM;CACrB,MAAM,KAAK,EAAE,CAAC;CACd,MAAM,UAAU,EAAE,CAAC;CACnB,MAAM,SAAS,EAAE,MAAM,CAAA,CAAE;CACzB,MAAM,QAAQ,EAAE,MAAM,CAAA,CAAE;CACxB,MAAM,OAAO,EAAE,IAAI;CACnB;CACA,MAAM,cAAc,EAAE,MAAM;CAC5B,MAAM,cAAc,EAAE,IAAI;CAC1B,MAAM,oBAAoB,EAAE,EAAE;CAC9B,KAAK;CACL,EAAA;;CAEA;CACA;CACA;CACA;CACA;CACA,EAAE,aAAa,CAAC,OAAO,GAAG,EAAE,EAAE;CAC9B,IAAI,OAAO,EAAE,GAAG,IAAI,CAAC,aAAa,EAAE,GAAG,OAAO,EAAE;CAChD,EAAA;;CAEA;CACA;CACA;CACA;CACA;CACA;CACA,EAAE,MAAM,eAAe,CAAC,YAAY,EAAE,gBAAgB,EAAE;CACxD,IAAI,IAAI,CAAC,YAAY,EAAE;CACvB,MAAM,OAAO,gBAAgB;CAC7B,IAAA;;CAEA,IAAI,IAAI;CACR,MAAMA,KAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;CAC9C,MAAM,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC;CACrD,MAAM,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,IAAI;CACpC;CACA,MAAM,IAAI,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE;CAC9C,QAAQ,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;CACxH,QAAQA,KAAG,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC,CAAC;CACjD,QAAQ,OAAO,aAAa;CAC5B,MAAA,CAAO,MAAM;CACb,QAAQA,KAAG,CAAC,KAAK,CAAC,uBAAuB,CAAC;CAC1C,QAAQ,OAAO,gBAAgB;CAC/B,MAAA;CACA,IAAA,CAAK,CAAC,OAAO,KAAK,EAAE;CACpB,MAAMA,KAAG,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC;CAC7C,MAAMA,KAAG,CAAC,GAAG,CAAC,eAAe,CAAC;CAC9B,MAAM,OAAO,gBAAgB;CAC7B,IAAA;CACA,EAAA;;CAEA;CACA;CACA;CACA;CACA;CACA;CACA,EAAE,uBAAuB,CAAC,IAAI,EAAE;CAChC,IAAI,OAAO,IAAI;CACf,WAAW,IAAI,CAAC,YAAY;CAC5B,WAAW,IAAI,CAAC,WAAW;CAC3B,WAAW,IAAI,CAAC,WAAW;CAC3B,WAAW,IAAI,CAAC,YAAY;CAC5B,EAAA;CACA;;CAEA,IAAA,gBAAc,GAAGC,gBAAc;;CCrF/B,MAAM,IAAI,GAAGC,YAAkB;CAC/B,MAAMF,KAAG,GAAG,UAAsB;CAClC,MAAMG,OAAK,GAAG,UAAqB;;CAEnC;CACA;CACA;CACA;2BACA,MAAM,iBAAiB,CAAC;CACxB,EAAE,WAAW,CAAC,MAAM,EAAE;CACtB,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM;CACxB,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI;CAC1B,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI;CACvB,IAAI,IAAI,CAAC,QAAQ,GAAG,EAAE;CACtB,IAAI,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAC;CACrC,IAAI,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;CAC/B,IAAI,IAAI,CAAC,oBAAoB,GAAG,MAAM,CAAC,oBAAoB,IAAI,EAAE,CAAC;CAClE,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,WAAW,CAAC,QAAQ,EAAE;CACxB,IAAI,IAAI,CAAC,QAAQ,GAAG,QAAQ;CAC5B,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,MAAM,UAAU,GAAG;CACrB,IAAI,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,MAAM;CACxG;CACA,IAAI,IAAI;CACR;CACA,MAAM,IAAI,CAAC,UAAU,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;CACjF;CACA;CACA,MAAM,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE;CAC1D;CACA;CACA,MAAM,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,CAAC;CAC9D,MAAM,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;CAC3C;CACA;CACA,MAAM,MAAM,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;CAC5E;CACA,MAAMH,KAAG,CAAC,GAAG,CAAC,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC,CAAC;CAChD;CACA;CACA,MAAM,IAAI,CAAC,sBAAsB,EAAE;CACnC;CACA,MAAM,OAAO,IAAI,CAAC,OAAO;CACzB,IAAA,CAAK,CAAC,OAAO,KAAK,EAAE;CACpB,MAAMA,KAAG,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC;CAC3C,MAAM,MAAM,KAAK;CACjB,IAAA;CACA,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,MAAM,SAAS,GAAG;CACpB,IAAI,IAAI,IAAI,CAAC,mBAAmB,EAAE;CAClC,MAAMA,KAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC;CACjC,MAAM,OAAO,IAAI,CAAC,OAAO;CACzB,IAAA;;CAEA;CACA,IAAI,IAAI,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,oBAAoB,EAAE;CAC7D,MAAMA,KAAG,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;CAChE,MAAMA,KAAG,CAAC,KAAK,CAAC,wBAAwB,CAAC;CACzC,MAAM,OAAO,IAAI;CACjB,IAAA;;CAEA,IAAI,IAAI,CAAC,mBAAmB,GAAG,IAAI;CACnC,IAAI,IAAI,CAAC,iBAAiB,EAAE;CAC5B;CACA,IAAI,IAAI;CACR,MAAMA,KAAG,CAAC,KAAK,CAAC,CAAC,cAAc,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;CAC9F;CACA;CACA,MAAM,MAAM,IAAI,CAAC,kBAAkB,EAAE;CACrC;CACA;CACA,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,IAAI,IAAI,IAAI;CACtE,MAAM,MAAMG,OAAK,CAAC,KAAK,CAAC,YAAY,CAAC;CACrC;CACA;CACA,MAAM,MAAM,IAAI,CAAC,UAAU,EAAE;CAC7B;CACA;CACA,MAAM,IAAI,CAAC,iBAAiB,GAAG,CAAC;CAChC,MAAMH,KAAG,CAAC,GAAG,CAAC,CAAC,qBAAqB,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;CAChE;CACA,MAAM,OAAO,IAAI,CAAC,OAAO;CACzB,IAAA,CAAK,CAAC,OAAO,KAAK,EAAE;CACpB,MAAMA,KAAG,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC;CACtE;CACA;CACA,MAAM,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,EAAE;CAC9D,QAAQ,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,IAAI;CAC7D,QAAQ,UAAU,CAAC,MAAM;CACzB,UAAU,IAAI,CAAC,mBAAmB,GAAG,KAAK;CAC1C,UAAU,IAAI,CAAC,SAAS,EAAE;CAC1B,QAAA,CAAS,EAAE,UAAU,CAAC;CACtB,MAAA,CAAO,MAAM;CACb,QAAQA,KAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC;CACrC,MAAA;CACA;CACA,MAAM,MAAM,KAAK;CACjB,IAAA,CAAK,SAAS;CACd,MAAM,IAAI,CAAC,mBAAmB,GAAG,KAAK;CACtC,IAAA;CACA,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,UAAU,GAAG;CACf,IAAI,OAAO,IAAI,CAAC,OAAO;CACvB,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,aAAa,GAAG;CAClB,IAAI,OAAO,IAAI,CAAC,UAAU;CAC1B,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,WAAW,GAAG;CAChB,IAAI,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS;CACnF,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,MAAM,KAAK,GAAG;CAChB,IAAI,IAAI;CACR,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE;CACxB,QAAQ,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;CAClC,QAAQ,IAAI,CAAC,OAAO,GAAG,IAAI;CAC3B,MAAA;CACA,MAAM,IAAI,IAAI,CAAC,UAAU,EAAE;CAC3B,QAAQ,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE;CACrC,QAAQ,IAAI,CAAC,UAAU,GAAG,IAAI;CAC9B,MAAA;CACA,MAAMA,KAAG,CAAC,GAAG,CAAC,eAAe,CAAC;CAC9B,IAAA,CAAK,CAAC,OAAO,KAAK,EAAE;CACpB,MAAMA,KAAG,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC;CAC1C,IAAA;CACA,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,sBAAsB,GAAG;CAC3B;CACA,IAAI,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK;CACzC,MAAMA,KAAG,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC;CACrC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI;CACtC,QAAQA,KAAG,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;CACzC,MAAA,CAAO,CAAC;CACR,IAAA,CAAK,CAAC;;CAEN;CACA,IAAI,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM;CACtC,MAAMA,KAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC;CAClC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI;CACtC,QAAQA,KAAG,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;CACzC,MAAA,CAAO,CAAC;CACR,IAAA,CAAK,CAAC;CACN,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,MAAM,kBAAkB,GAAG;CAC7B,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE;CACtB,MAAM,IAAI;CACV,QAAQ,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;CAClC,MAAA,CAAO,CAAC,OAAO,CAAC,EAAE;CAClB,QAAQA,KAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC;CAC5C,MAAA;CACA,MAAM,IAAI,CAAC,OAAO,GAAG,IAAI;CACzB,IAAA;CACA,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,QAAQ,GAAG;CACb,IAAI,OAAO;CACX,MAAM,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE;CACrC,MAAM,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;CAC/C,MAAM,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;CACrD,MAAM,mBAAmB,EAAE,IAAI,CAAC;CAChC,KAAK;CACL,EAAA;CACA;;CAEA,IAAA,mBAAc,GAAGI,mBAAiB;;CCrNlC,MAAMJ,KAAG,GAAGE,UAAsB;CAClC,MAAM,KAAK,GAAGG,UAAqB;;CAEnC;CACA;CACA;CACA;0BACA,MAAM,gBAAgB,CAAC;CACvB,EAAE,WAAW,CAAC,MAAM,EAAE;CACtB,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM;CACxB,IAAI,IAAI,CAAC,kBAAkB,GAAG,IAAI,GAAG,EAAE,CAAC;CACxC,EAAA;;CAEA;CACA;CACA;CACA;CACA;CACA,EAAE,MAAM,cAAc,CAAC,OAAO,EAAE;CAChC,IAAI,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,MAAM;CACxD;CACA,IAAIL,KAAG,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;CACnC;CACA,IAAI,MAAM,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,GAAG,KAAK;CACtD,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;CACxB,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC;CAChE,MAAA,CAAO,MAAM;CACb;CACA,QAAQA,KAAG,CAAC,GAAG,CAAC,sBAAsB,CAAC;CACvC;CACA,MAAA;CACA,IAAA,CAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;CACxB;CACA;CACA,IAAI,OAAO,MAAM;CACjB,MAAM,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE;CACrC,MAAMA,KAAG,CAAC,GAAG,CAAC,WAAW,CAAC;CAC1B,IAAA,CAAK;CACL,EAAA;;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,EAAE,MAAM,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE;CACtD,IAAI,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW;CAC9C;CACA;CACA,IAAI,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;CAClD,MAAMA,KAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;CAC3C,MAAM;CACN,IAAA;CACA;CACA,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC;CAC5C;CACA;CACA,IAAI,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,EAAE;CAC3C,MAAMA,KAAG,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,WAAW,CAAC,oBAAoB,CAAC,CAAC;CAC7D,MAAM,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;CAC7D,MAAM;CACN,IAAA;CACA;CACA,IAAI,IAAI;CACR,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;CACxD,MAAMA,KAAG,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;CACtD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE;CAClC;CACA;CACA,MAAM,MAAM,cAAc,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK;CACxD,QAAQ,UAAU,CAAC,MAAM;CACzB,UAAU,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;CACvE,QAAA,CAAS,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;CACtC,MAAA,CAAO,CAAC;CACR;CACA;CACA,MAAM,IAAI;CACV,QAAQ,MAAM,OAAO,CAAC,IAAI,CAAC;CAC3B,UAAU,QAAQ,CAAC,OAAO,CAAC;CAC3B,UAAU;CACV,SAAS,CAAC;CACV;CACA,QAAQ,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;CAC9C,QAAQA,KAAG,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;CAC7D,QAAQ,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC;CAClE;CACA,MAAA,CAAO,CAAC,OAAO,aAAa,EAAE;CAC9B,QAAQ,IAAI,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;CAClD,UAAUA,KAAG,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;CACjF,QAAA,CAAS,MAAM;CACf,UAAUA,KAAG,CAAC,GAAG,CAAC,cAAc,EAAE,aAAa,CAAC,OAAO,CAAC;CACxD,QAAA;CACA,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,CAAC;CAC5D,MAAA;CACA;CACA,IAAA,CAAK,CAAC,OAAO,CAAC,EAAE;CAChB,MAAMA,KAAG,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC;CACvC,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,CAAC;CAC1D,IAAA;CACA,EAAA;;CAEA;CACA;CACA;CACA;CACA;CACA;CACA,EAAE,sBAAsB,CAAC,GAAG,EAAE;CAC9B,IAAI,IAAI;CACR;CACA,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE;CAChC,QAAQ,OAAO,KAAK;CACpB,MAAA;CACA;CACA;CACA,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE;CAC/C;CACA;CACA,MAAM,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;CACnD,QAAQ,OAAO,KAAK;CACpB,MAAA;CACA;CACA;CACA,MAAM,IAAI,UAAU,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,UAAU,CAAC,WAAW,EAAE,KAAK,WAAW,EAAE;CAC3F,QAAQ,OAAO,KAAK;CACpB,MAAA;CACA;CACA;CACA,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;CAC5B,MAAM,OAAO,IAAI;CACjB,IAAA,CAAK,CAAC,OAAO,KAAK,EAAE;CACpB;CACA,MAAM,OAAO,KAAK;CAClB,IAAA;CACA,EAAA;;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,EAAE,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE;CACxD;CACA,IAAI,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;CAClD,MAAM,UAAU,CAAC,MAAM;CACvB,QAAQ,IAAI;CACZ,UAAU,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;CAC1B,UAAU,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC;CACrD,UAAUA,KAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;CAC5C,QAAA,CAAS,CAAC,OAAO,QAAQ,EAAE;CAC3B,UAAUA,KAAG,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC;CAClE,UAAU,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC;CACrD,QAAA;CACA,MAAA,CAAO,EAAE,KAAK,CAAC;CACf,IAAA;CACA,EAAA;;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,EAAE,MAAM,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE;CAClD,IAAI,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;CACxB;CACA,IAAI,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;CAClD,MAAM,IAAI;CACV,QAAQ,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC;CACjC,QAAQ,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC;CACnD,QAAQA,KAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;CAC/C,MAAA,CAAO,CAAC,OAAO,WAAW,EAAE;CAC5B,QAAQA,KAAG,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC;CAClE,QAAQ,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC;CACnD,MAAA;CACA,IAAA;CACA,EAAA;;CAEA;CACA;CACA;CACA,EAAE,uBAAuB,GAAG;CAC5B,IAAI,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE;CACnC,IAAIA,KAAG,CAAC,GAAG,CAAC,aAAa,CAAC;CAC1B,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,kBAAkB,GAAG;CACvB,IAAI,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI;CACvC,EAAA;CACA;;CAEA,IAAA,kBAAc,GAAGM,kBAAgB;;CC1MjC,MAAMN,KAAG,GAAGE,UAAsB;;CAElC;CACA;CACA;CACA;sBACA,MAAM,YAAY,CAAC;CACnB,EAAE,WAAW,CAAC,MAAM,EAAE;CACtB,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM;CACxB,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI;CAC1B,IAAI,IAAI,CAAC,SAAS,GAAG,KAAK;CAC1B,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,KAAK,CAAC,OAAO,EAAE;CACjB,IAAI,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,MAAM;CAC9D;CACA,IAAI,IAAI,UAAU,IAAI,CAAC,EAAE;CACzB,MAAMF,KAAG,CAAC,GAAG,CAAC,WAAW,CAAC;CAC1B,MAAM;CACN,IAAA;;CAEA,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;CACxB,MAAMA,KAAG,CAAC,GAAG,CAAC,aAAa,CAAC;CAC5B,MAAM;CACN,IAAA;;CAEA,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI;CACzB,IAAIA,KAAG,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC;;CAEzC,IAAI,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,YAAY;CAC9C,MAAM,IAAI;CACV,QAAQ,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,CAAC;CACrE,MAAA,CAAO,CAAC,OAAO,KAAK,EAAE;CACtB,QAAQA,KAAG,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC;CAC9C,MAAA;CACA,IAAA,CAAK,EAAE,UAAU,CAAC;CAClB,EAAA;;CAEA;CACA;CACA;CACA,EAAE,IAAI,GAAG;CACT,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;CACzB,MAAM,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC;CACpC,MAAM,IAAI,CAAC,UAAU,GAAG,IAAI;CAC5B,MAAM,IAAI,CAAC,SAAS,GAAG,KAAK;CAC5B,MAAMA,KAAG,CAAC,GAAG,CAAC,WAAW,CAAC;CAC1B,IAAA;CACA,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,OAAO,CAAC,OAAO,EAAE;CACnB,IAAI,IAAI,CAAC,IAAI,EAAE;CACf,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;CACvB,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,QAAQ,GAAG;CACb,IAAI,OAAO,IAAI,CAAC,SAAS;CACzB,EAAA;;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,EAAE,MAAM,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE;CAC3D,IAAI,IAAI;CACR;CACA,MAAM,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC;CACpE;CACA;CACA,MAAM,MAAM,UAAU,GAAG,MAAM,SAAS,EAAE;CAC1C;CACA,MAAMA,KAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,EAAE,YAAY,CAAC,WAAW,EAAE,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACrF;CACA;CACA;CACA,IAAA,CAAK,CAAC,OAAO,KAAK,EAAE;CACpB,MAAMA,KAAG,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC;CAC5C,IAAA;CACA,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,SAAS,GAAG;CACd,IAAI,OAAO;CACX,MAAM,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU;CACxC,MAAM,SAAS,EAAE,IAAI,CAAC,SAAS;CAC/B,MAAM,UAAU,EAAE,IAAI,CAAC,UAAU,KAAK;CACtC,KAAK;CACL,EAAA;CACA;;CAEA,IAAA,cAAc,GAAGO,cAAY;;CC5G7B,MAAM,cAAc,GAAGL,gBAAkC;CACzD,MAAM,iBAAiB,GAAGG,mBAAqC;CAC/D,MAAM,gBAAgB,GAAGG,kBAAoC;CAC7D,MAAM,YAAY,GAAGC,cAAgC;CACrD,MAAM,GAAG,GAAGC,UAAsB;;CAElC;CACA;CACA;CACA;CACA,MAAM,eAAe,CAAC;CACtB,EAAE,WAAW,GAAG;CAChB,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,EAAE;CAC9C,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI;CACjC,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI;CAChC,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI;CAC5B,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI;CACtB,EAAA;;CAEA;CACA;CACA;CACA;CACA;CACA,EAAE,MAAM,IAAI,CAAC,OAAO,GAAG,EAAE,EAAE;CAC3B,IAAI,IAAI;CACR;CACA,MAAM,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,OAAO,CAAC;CAC9D,MAAM,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC;;CAEvB;CACA,MAAM,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,eAAe;CAChE,QAAQ,IAAI,CAAC,MAAM,CAAC,YAAY;CAChC,QAAQ,IAAI,CAAC,MAAM,CAAC;CACpB,OAAO;;CAEP;CACA,MAAM,IAAI,CAAC,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;CACjE,MAAM,IAAI,CAAC,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC;CAC/D,MAAM,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;;CAEvD;CACA,MAAM,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,QAAQ,CAAC;CAClD,MAAM,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,EAAE;;CAE/D;CACA,MAAM,IAAI,CAAC,sBAAsB,EAAE;;CAEnC;CACA,MAAM,MAAM,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,OAAO,CAAC;CACzD,MAAM,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC;;CAEzB;CACA,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC;;CAEtC;CACA,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;CAC1B;CACA,MAAM,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC;CAC1B,IAAA,CAAK,CAAC,OAAO,KAAK,EAAE;CACpB,MAAM,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC;CAC5C,MAAM,MAAM,KAAK;CACjB,IAAA;CACA,EAAA;;CAEA;CACA;CACA;CACA;CACA;CACA,EAAE,sBAAsB,GAAG;CAC3B,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC;CAC3F;CACA,IAAI,IAAI,CAAC,iBAAiB,CAAC,SAAS,GAAG,YAAY;CACnD,MAAM,IAAI;CACV;CACA,QAAQ,MAAM,UAAU,GAAG,MAAM,iBAAiB,EAAE;CACpD;CACA;CACA,QAAQ,IAAI,CAAC,gBAAgB,CAAC,uBAAuB,EAAE;CACvD,QAAQ,MAAM,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,UAAU,CAAC;CAC9D,QAAQ,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC;CAChC;CACA;CACA,QAAQ,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC;CAC7C,QAAQ,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC;CACjC;CACA,QAAQ,OAAO,UAAU;CACzB,MAAA,CAAO,CAAC,OAAO,KAAK,EAAE;CACtB,QAAQ,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC;CAC3C,QAAQ,MAAM,KAAK;CACnB,MAAA;CACA,IAAA,CAAK;CACL,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,SAAS,GAAG;CACd,IAAI,OAAO;CACX,MAAM,WAAW,EAAE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE,GAAG,KAAK;CACxF,MAAM,eAAe,EAAE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,GAAG,CAAC;CAC7F,MAAM,kBAAkB,EAAE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,GAAG,KAAK;CAClF,MAAM,WAAW,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG;CAC3D,KAAK;CACL,EAAA;;CAEA;CACA;CACA;CACA;CACA,EAAE,MAAM,QAAQ,GAAG;CACnB,IAAI,IAAI;CACR,MAAM,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAC;CAChC;CACA;CACA,MAAM,IAAI,IAAI,CAAC,YAAY,EAAE;CAC7B,QAAQ,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;CAChC,MAAA;CACA;CACA;CACA,MAAM,IAAI,IAAI,CAAC,gBAAgB,EAAE;CACjC,QAAQ,IAAI,CAAC,gBAAgB,CAAC,uBAAuB,EAAE;CACvD,MAAA;CACA;CACA;CACA,MAAM,IAAI,IAAI,CAAC,iBAAiB,EAAE;CAClC,QAAQ,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE;CAC5C,MAAA;CACA;CACA,MAAM,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC;CAC5B,IAAA,CAAK,CAAC,OAAO,KAAK,EAAE;CACpB,MAAM,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC;CAC9C,IAAA;CACA,EAAA;CACA;;CAEA;CACA,IAAA,WAAc,GAAG;CACjB;CACA;CACA;CACA;CACA;CACA,EAAE,MAAM,IAAI,CAAC,OAAO,EAAE;CACtB,IAAI,MAAM,WAAW,GAAG,IAAI,eAAe,EAAE;CAC7C,IAAI,OAAO,MAAM,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC;CAC1C,EAAA,CAAG;;CAEH;CACA,EAAE;CACF,CAAC;;;;;;;;;;;;"}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
declare module 'amqplib-init' {
|
|
2
|
+
/**
|
|
3
|
+
* 配置选项
|
|
4
|
+
*/
|
|
5
|
+
export interface AmqplibInitOptions {
|
|
6
|
+
/** 队列名称 */
|
|
7
|
+
channelName?: string;
|
|
8
|
+
/** RabbitMQ 连接地址 */
|
|
9
|
+
amqpLink?: string;
|
|
10
|
+
/** 自动获取连接地址的API */
|
|
11
|
+
amqpAutoLink?: string;
|
|
12
|
+
/** 预取消息数量 */
|
|
13
|
+
prefetch?: number;
|
|
14
|
+
/** 队列持久化 */
|
|
15
|
+
durable?: boolean;
|
|
16
|
+
/** 消息确认延迟时间(ms) */
|
|
17
|
+
delay?: number;
|
|
18
|
+
/** 心跳间隔(秒) */
|
|
19
|
+
heartbeat?: number;
|
|
20
|
+
/** 连接超时时间(ms) */
|
|
21
|
+
timeout?: number;
|
|
22
|
+
/** 消息处理超时时间(ms) */
|
|
23
|
+
messageTimeout?: number;
|
|
24
|
+
/** 重连延迟时间(ms) */
|
|
25
|
+
reconnectDelay?: number;
|
|
26
|
+
/** 最大重连次数 */
|
|
27
|
+
maxReconnectAttempts?: number;
|
|
28
|
+
/** 自动重载间隔(ms) */
|
|
29
|
+
autoReload?: number;
|
|
30
|
+
/** 消息处理回调 */
|
|
31
|
+
callback?: (message: any) => Promise<any> | any;
|
|
32
|
+
/** 初始化完成回调 */
|
|
33
|
+
finish?: () => void;
|
|
34
|
+
/** 初始化钩子 */
|
|
35
|
+
initHook?: (context: { channel: any; connection: any }) => Promise<void> | void;
|
|
36
|
+
/** 查询钩子 */
|
|
37
|
+
queryHook?: () => Promise<boolean> | boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 状态信息
|
|
42
|
+
*/
|
|
43
|
+
export interface AmqplibStatus {
|
|
44
|
+
/** 是否已连接 */
|
|
45
|
+
isConnected: boolean;
|
|
46
|
+
/** 处理中的消息数量 */
|
|
47
|
+
processingCount: number;
|
|
48
|
+
/** 自动重载器是否激活 */
|
|
49
|
+
autoReloaderActive: boolean;
|
|
50
|
+
/** 当前队列名 */
|
|
51
|
+
channelName: string | null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* AMQP 初始化器类
|
|
56
|
+
*/
|
|
57
|
+
export class AMQPInitializer {
|
|
58
|
+
/**
|
|
59
|
+
* 初始化 AMQP 连接和消息处理
|
|
60
|
+
* @param options 配置选项
|
|
61
|
+
*/
|
|
62
|
+
init(options?: AmqplibInitOptions): Promise<void>;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 获取当前状态信息
|
|
66
|
+
*/
|
|
67
|
+
getStatus(): AmqplibStatus;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 优雅关闭
|
|
71
|
+
*/
|
|
72
|
+
shutdown(): Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 初始化函数 - 保持向后兼容
|
|
77
|
+
* @param options 配置选项
|
|
78
|
+
*/
|
|
79
|
+
export function init(options?: AmqplibInitOptions): Promise<void>;
|
|
80
|
+
|
|
81
|
+
// 默认导出
|
|
82
|
+
const amqplibInit: {
|
|
83
|
+
init: typeof init;
|
|
84
|
+
AMQPInitializer: typeof AMQPInitializer;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export default amqplibInit;
|
|
88
|
+
}
|
package/module/AutoReloader.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
const shelljs = require('shelljs');
|
|
2
1
|
const log = require('chalk-style');
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* 自动重载器模块
|
|
6
|
-
*
|
|
5
|
+
* 负责监控队列状态(已移除 PM2 重启功能,改用 Supervisor 管理)
|
|
7
6
|
*/
|
|
8
7
|
class AutoReloader {
|
|
9
8
|
constructor(config) {
|
|
@@ -17,7 +16,7 @@ class AutoReloader {
|
|
|
17
16
|
* @param {Object} channel - RabbitMQ频道
|
|
18
17
|
*/
|
|
19
18
|
start(channel) {
|
|
20
|
-
const { autoReload, channelName,
|
|
19
|
+
const { autoReload, channelName, queryHook } = this.config;
|
|
21
20
|
|
|
22
21
|
if (autoReload <= 0) {
|
|
23
22
|
log.log('自动重载功能未启用');
|
|
@@ -30,13 +29,13 @@ class AutoReloader {
|
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
this.isRunning = true;
|
|
33
|
-
log.log(
|
|
32
|
+
log.log(`启动队列监控,间隔: ${autoReload}ms`);
|
|
34
33
|
|
|
35
34
|
this.intervalId = setInterval(async () => {
|
|
36
35
|
try {
|
|
37
|
-
await this.
|
|
36
|
+
await this._checkQueueStatus(channel, channelName, queryHook);
|
|
38
37
|
} catch (error) {
|
|
39
|
-
log.error('
|
|
38
|
+
log.error('队列状态检查时出错:', error.message);
|
|
40
39
|
}
|
|
41
40
|
}, autoReload);
|
|
42
41
|
}
|
|
@@ -71,54 +70,26 @@ class AutoReloader {
|
|
|
71
70
|
}
|
|
72
71
|
|
|
73
72
|
/**
|
|
74
|
-
*
|
|
73
|
+
* 检查队列状态(仅监控,不执行重启)
|
|
75
74
|
* @param {Object} channel - RabbitMQ频道
|
|
76
75
|
* @param {string} channelName - 频道名称
|
|
77
|
-
* @param {number} pmId - PM2进程ID
|
|
78
76
|
* @param {Function} queryHook - 查询钩子函数
|
|
79
77
|
* @private
|
|
80
78
|
*/
|
|
81
|
-
async
|
|
79
|
+
async _checkQueueStatus(channel, channelName, queryHook) {
|
|
82
80
|
try {
|
|
83
81
|
// 检查队列中的消息数量
|
|
84
82
|
const { messageCount } = await channel.checkQueue(channelName);
|
|
85
83
|
|
|
86
|
-
//
|
|
84
|
+
// 执行查询钩子
|
|
87
85
|
const hookResult = await queryHook();
|
|
88
86
|
|
|
89
|
-
log.log(
|
|
87
|
+
log.log(`队列 ${channelName} 中有 ${messageCount} 条消息,钩子状态: ${hookResult ? 1 : 0}`);
|
|
90
88
|
|
|
91
|
-
//
|
|
92
|
-
|
|
93
|
-
await this._executeReload(pmId);
|
|
94
|
-
}
|
|
95
|
-
} catch (error) {
|
|
96
|
-
log.error('检查队列长度时出错:', error.message);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* 执行服务重载
|
|
102
|
-
* @param {number} pmId - PM2进程ID
|
|
103
|
-
* @private
|
|
104
|
-
*/
|
|
105
|
-
async _executeReload(pmId) {
|
|
106
|
-
try {
|
|
107
|
-
log.log('队列中没有消息,正在重载服务...');
|
|
108
|
-
|
|
109
|
-
if (shelljs && typeof shelljs.exec === 'function') {
|
|
110
|
-
const result = shelljs.exec(`pm2 reload ${pmId}`);
|
|
111
|
-
|
|
112
|
-
if (result.code === 0) {
|
|
113
|
-
log.log(`服务重载成功,PM2进程ID: ${pmId}`);
|
|
114
|
-
} else {
|
|
115
|
-
log.error(`服务重载失败,错误码: ${result.code}, 输出: ${result.stderr}`);
|
|
116
|
-
}
|
|
117
|
-
} else {
|
|
118
|
-
log.error('shelljs不可用,无法执行服务重载');
|
|
119
|
-
}
|
|
89
|
+
// 注意: 已移除自动重启功能
|
|
90
|
+
// 如需重启服务,请使用 Supervisor: supervisorctl restart <service-name>
|
|
120
91
|
} catch (error) {
|
|
121
|
-
log.error('
|
|
92
|
+
log.error('检查队列状态时出错:', error.message);
|
|
122
93
|
}
|
|
123
94
|
}
|
|
124
95
|
|
|
@@ -129,7 +100,6 @@ class AutoReloader {
|
|
|
129
100
|
getConfig() {
|
|
130
101
|
return {
|
|
131
102
|
autoReload: this.config.autoReload,
|
|
132
|
-
pmId: this.config.pmId,
|
|
133
103
|
isRunning: this.isRunning,
|
|
134
104
|
intervalId: this.intervalId !== null
|
|
135
105
|
};
|
package/module/ConfigResolver.js
CHANGED
|
@@ -13,6 +13,8 @@ class ConnectionManager {
|
|
|
13
13
|
this.channel = null;
|
|
14
14
|
this.amqpLink = '';
|
|
15
15
|
this.reconnectInProgress = false; // 防止重复重连
|
|
16
|
+
this.reconnectAttempts = 0; // 重连计数器
|
|
17
|
+
this.maxReconnectAttempts = config.maxReconnectAttempts || 10; // 最大重连次数
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
/**
|
|
@@ -66,10 +68,18 @@ class ConnectionManager {
|
|
|
66
68
|
return this.channel;
|
|
67
69
|
}
|
|
68
70
|
|
|
71
|
+
// 检查是否达到最大重连次数
|
|
72
|
+
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
73
|
+
log.error(`❌ 已达到最大重连次数 ${this.maxReconnectAttempts},停止重连`);
|
|
74
|
+
log.error('请检查 RabbitMQ 服务状态或网络连接');
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
69
78
|
this.reconnectInProgress = true;
|
|
79
|
+
this.reconnectAttempts++;
|
|
70
80
|
|
|
71
81
|
try {
|
|
72
|
-
log.error(
|
|
82
|
+
log.error(`🔄 连接丢失,正在尝试第 ${this.reconnectAttempts}/${this.maxReconnectAttempts} 次重连...`);
|
|
73
83
|
|
|
74
84
|
// 清理旧的channel状态
|
|
75
85
|
await this._cleanupOldChannel();
|
|
@@ -81,17 +91,25 @@ class ConnectionManager {
|
|
|
81
91
|
// 重新初始化连接
|
|
82
92
|
await this.initialize();
|
|
83
93
|
|
|
84
|
-
|
|
94
|
+
// 重连成功,重置计数器
|
|
95
|
+
this.reconnectAttempts = 0;
|
|
96
|
+
log.log(`✅ 已重新连接到RabbitMQ,频道: ${this.config.channelName}`);
|
|
85
97
|
|
|
86
98
|
return this.channel;
|
|
87
99
|
} catch (error) {
|
|
88
|
-
log.error(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
this.
|
|
93
|
-
|
|
94
|
-
|
|
100
|
+
log.error(`❌ 第 ${this.reconnectAttempts} 次重连失败:`, error.message);
|
|
101
|
+
|
|
102
|
+
// 如果未达到最大次数,继续重试
|
|
103
|
+
if (this.reconnectAttempts < this.maxReconnectAttempts) {
|
|
104
|
+
const retryDelay = this.config.reconnectDelay || 5000;
|
|
105
|
+
setTimeout(() => {
|
|
106
|
+
this.reconnectInProgress = false;
|
|
107
|
+
this.reconnect();
|
|
108
|
+
}, retryDelay);
|
|
109
|
+
} else {
|
|
110
|
+
log.error('❌ 已达到最大重连次数,停止重连');
|
|
111
|
+
}
|
|
112
|
+
|
|
95
113
|
throw error;
|
|
96
114
|
} finally {
|
|
97
115
|
this.reconnectInProgress = false;
|
|
@@ -178,6 +196,19 @@ class ConnectionManager {
|
|
|
178
196
|
this.channel = null;
|
|
179
197
|
}
|
|
180
198
|
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* 获取连接统计信息
|
|
202
|
+
* @returns {Object} 连接统计
|
|
203
|
+
*/
|
|
204
|
+
getStats() {
|
|
205
|
+
return {
|
|
206
|
+
isConnected: this.isConnected(),
|
|
207
|
+
reconnectAttempts: this.reconnectAttempts,
|
|
208
|
+
maxReconnectAttempts: this.maxReconnectAttempts,
|
|
209
|
+
reconnectInProgress: this.reconnectInProgress
|
|
210
|
+
};
|
|
211
|
+
}
|
|
181
212
|
}
|
|
182
213
|
|
|
183
214
|
module.exports = ConnectionManager;
|
|
@@ -69,17 +69,33 @@ class MessageProcessor {
|
|
|
69
69
|
log.log(`🪴 队列收到消息: ${JSON.stringify(content)}`);
|
|
70
70
|
const startTime = Date.now();
|
|
71
71
|
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
72
|
+
// 创建超时 Promise
|
|
73
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
74
|
+
setTimeout(() => {
|
|
75
|
+
reject(new Error(`消息处理超时 (${this.config.messageTimeout}ms)`));
|
|
76
|
+
}, this.config.messageTimeout);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// 使用 Promise.race 实现超时控制
|
|
80
|
+
try {
|
|
81
|
+
await Promise.race([
|
|
82
|
+
callback(content),
|
|
83
|
+
timeoutPromise
|
|
84
|
+
]);
|
|
85
|
+
|
|
86
|
+
const endTime = Date.now() - startTime;
|
|
87
|
+
log.log(`☘️ 消息处理完成,延迟: ${delay}ms,总时间: ${endTime}ms`);
|
|
88
|
+
this._acknowledgeMessage(msg, channel, deliveryTag, delay);
|
|
89
|
+
|
|
90
|
+
} catch (callbackError) {
|
|
91
|
+
if (callbackError.message.includes('超时')) {
|
|
92
|
+
log.error(`⏰ 消息 ${deliveryTag} 处理超时 (${this.config.messageTimeout}ms)`);
|
|
93
|
+
} else {
|
|
94
|
+
log.log('‼️ 处理消息返回错误:', callbackError.message);
|
|
95
|
+
}
|
|
96
|
+
await this._rejectMessage(msg, channel, deliveryTag);
|
|
97
|
+
}
|
|
98
|
+
|
|
83
99
|
} catch (e) {
|
|
84
100
|
log.log('‼️ 处理消息时出错:', e.message);
|
|
85
101
|
await this._rejectMessage(msg, channel, deliveryTag);
|
package/package.json
CHANGED
|
@@ -1,11 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amqplib-init",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "消息队列初始化 -
|
|
5
|
-
"main": "
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "消息队列初始化 - 移除PM2依赖,改用Supervisor管理 (支持15分钟长任务)",
|
|
5
|
+
"main": "dist/amqplib-init.cjs.js",
|
|
6
|
+
"module": "dist/amqplib-init.esm.js",
|
|
7
|
+
"browser": "dist/amqplib-init.umd.js",
|
|
8
|
+
"types": "index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"require": "./dist/amqplib-init.cjs.js",
|
|
12
|
+
"import": "./dist/amqplib-init.esm.js",
|
|
13
|
+
"default": "./dist/amqplib-init.cjs.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"module",
|
|
19
|
+
"index.js",
|
|
20
|
+
"index.d.ts",
|
|
21
|
+
"README.md",
|
|
22
|
+
"CHANGELOG.md"
|
|
23
|
+
],
|
|
6
24
|
"scripts": {
|
|
25
|
+
"build": "rollup -c",
|
|
26
|
+
"prepublishOnly": "npm run build",
|
|
7
27
|
"start": "node index.js"
|
|
8
28
|
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"rabbitmq",
|
|
31
|
+
"amqp",
|
|
32
|
+
"message-queue",
|
|
33
|
+
"queue",
|
|
34
|
+
"amqplib",
|
|
35
|
+
"reconnect",
|
|
36
|
+
"supervisor"
|
|
37
|
+
],
|
|
9
38
|
"author": "",
|
|
10
39
|
"license": "ISC",
|
|
11
40
|
"dependencies": {
|
|
@@ -13,7 +42,13 @@
|
|
|
13
42
|
"axios": "^1.6.0",
|
|
14
43
|
"chalk-style": "^1.0.3",
|
|
15
44
|
"happy-help": "^1.0.1",
|
|
16
|
-
"js-base64": "^3.7.7"
|
|
17
|
-
|
|
45
|
+
"js-base64": "^3.7.7"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@rollup/plugin-commonjs": "^25.0.7",
|
|
49
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
50
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
51
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
52
|
+
"rollup": "^4.9.6"
|
|
18
53
|
}
|
|
19
54
|
}
|