amqplib-init 1.2.4 → 1.3.1
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 +109 -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/package.json +38 -5
- package/demo.js +0 -5
- package/index.js +0 -153
- package/module/AutoReloader.js +0 -139
- package/module/ConfigResolver.js +0 -87
- package/module/ConnectionManager.js +0 -183
- package/module/MessageProcessor.js +0 -187
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
const log = require('chalk-style');
|
|
2
|
-
const happy = require('happy-help');
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 消息处理器模块
|
|
6
|
-
* 负责消息处理、状态跟踪、ACK/REJECT逻辑
|
|
7
|
-
*/
|
|
8
|
-
class MessageProcessor {
|
|
9
|
-
constructor(config) {
|
|
10
|
-
this.config = config;
|
|
11
|
-
this.processingMessages = new Set(); // 跟踪正在处理的消息
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* 开始消费消息
|
|
16
|
-
* @param {Object} channel - RabbitMQ频道
|
|
17
|
-
* @returns {Promise<Function>} 返回清理函数
|
|
18
|
-
*/
|
|
19
|
-
async startConsuming(channel) {
|
|
20
|
-
const { channelName, callback, delay } = this.config;
|
|
21
|
-
|
|
22
|
-
log.log(`开始消费: ${channelName}`);
|
|
23
|
-
|
|
24
|
-
await channel.consume(channelName, async (msg) => {
|
|
25
|
-
if (msg !== null) {
|
|
26
|
-
await this._handleMessage(msg, channel, callback, delay);
|
|
27
|
-
} else {
|
|
28
|
-
// ✅ 修复关键bug:null消息不需要ACK操作
|
|
29
|
-
log.log('收到null消息,队列可能为空或连接中断');
|
|
30
|
-
// 移除错误的 channel.ack(msg) 调用
|
|
31
|
-
}
|
|
32
|
-
}, { noAck: false });
|
|
33
|
-
|
|
34
|
-
// 返回清理函数,用于重连时清理状态
|
|
35
|
-
return () => {
|
|
36
|
-
this.processingMessages.clear();
|
|
37
|
-
log.log('已清理消息处理状态');
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* 处理单条消息
|
|
43
|
-
* @param {Object} msg - RabbitMQ消息对象
|
|
44
|
-
* @param {Object} channel - RabbitMQ频道
|
|
45
|
-
* @param {Function} callback - 消息处理回调函数
|
|
46
|
-
* @param {number} delay - 延迟ACK时间
|
|
47
|
-
* @private
|
|
48
|
-
*/
|
|
49
|
-
async _handleMessage(msg, channel, callback, delay) {
|
|
50
|
-
const deliveryTag = msg.fields.deliveryTag;
|
|
51
|
-
|
|
52
|
-
// 检查消息是否已在处理中
|
|
53
|
-
if (this.processingMessages.has(deliveryTag)) {
|
|
54
|
-
log.log(`消息 ${deliveryTag} 已在处理中,跳过`);
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
this.processingMessages.add(deliveryTag);
|
|
59
|
-
|
|
60
|
-
// 检查消息内容有效性,对无效消息直接确认
|
|
61
|
-
if (!this._isValidMessageContent(msg)) {
|
|
62
|
-
log.log(`⚠️ 收到无效消息 ${deliveryTag},内容为空或无法解析,自动确认以防止阻塞`);
|
|
63
|
-
this._acknowledgeMessage(msg, channel, deliveryTag, 0); // 立即确认无效消息
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
try {
|
|
68
|
-
const content = JSON.parse(msg.content.toString());
|
|
69
|
-
log.log(`🪴 队列收到消息: ${JSON.stringify(content)}`);
|
|
70
|
-
const startTime = Date.now();
|
|
71
|
-
|
|
72
|
-
// 执行消息处理回调
|
|
73
|
-
callback(content)
|
|
74
|
-
.then(() => {
|
|
75
|
-
const endTime = Date.now() - startTime;
|
|
76
|
-
log.log(`☘️ 消息处理完成,延迟: ${delay}ms,总时间: ${endTime}ms`);
|
|
77
|
-
this._acknowledgeMessage(msg, channel, deliveryTag, delay);
|
|
78
|
-
})
|
|
79
|
-
.catch(async (e) => {
|
|
80
|
-
log.log('‼️ 处理消息返回错误:', e);
|
|
81
|
-
await this._rejectMessage(msg, channel, deliveryTag);
|
|
82
|
-
});
|
|
83
|
-
} catch (e) {
|
|
84
|
-
log.log('‼️ 处理消息时出错:', e.message);
|
|
85
|
-
await this._rejectMessage(msg, channel, deliveryTag);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* 检查消息内容是否有效
|
|
91
|
-
* @param {Object} msg - RabbitMQ消息对象
|
|
92
|
-
* @returns {boolean} 消息内容是否有效
|
|
93
|
-
* @private
|
|
94
|
-
*/
|
|
95
|
-
_isValidMessageContent(msg) {
|
|
96
|
-
try {
|
|
97
|
-
// 检查消息对象是否存在
|
|
98
|
-
if (!msg || !msg.content) {
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// 获取消息内容字符串
|
|
103
|
-
const contentStr = msg.content.toString();
|
|
104
|
-
|
|
105
|
-
// 检查内容是否为空或只包含空白字符
|
|
106
|
-
if (!contentStr || contentStr.trim() === '') {
|
|
107
|
-
return false;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// 检查是否为null字符串
|
|
111
|
-
if (contentStr.toLowerCase() === 'null' || contentStr.toLowerCase() === 'undefined') {
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// 尝试解析JSON,如果失败则认为无效
|
|
116
|
-
JSON.parse(contentStr);
|
|
117
|
-
return true;
|
|
118
|
-
} catch (error) {
|
|
119
|
-
// JSON解析失败,认为消息无效
|
|
120
|
-
return false;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* 确认消息
|
|
126
|
-
* @param {Object} msg - RabbitMQ消息对象
|
|
127
|
-
* @param {Object} channel - RabbitMQ频道
|
|
128
|
-
* @param {string} deliveryTag - 消息标签
|
|
129
|
-
* @param {number} delay - 延迟时间
|
|
130
|
-
* @private
|
|
131
|
-
*/
|
|
132
|
-
_acknowledgeMessage(msg, channel, deliveryTag, delay) {
|
|
133
|
-
// 确保消息还在处理集合中再进行ACK
|
|
134
|
-
if (this.processingMessages.has(deliveryTag)) {
|
|
135
|
-
setTimeout(() => {
|
|
136
|
-
try {
|
|
137
|
-
channel.ack(msg);
|
|
138
|
-
this.processingMessages.delete(deliveryTag);
|
|
139
|
-
log.log(`✅ 消息 ${deliveryTag} 已确认`);
|
|
140
|
-
} catch (ackError) {
|
|
141
|
-
log.error(`ACK消息 ${deliveryTag} 时出错:`, ackError.message);
|
|
142
|
-
this.processingMessages.delete(deliveryTag);
|
|
143
|
-
}
|
|
144
|
-
}, delay);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* 拒绝消息并重新排队
|
|
150
|
-
* @param {Object} msg - RabbitMQ消息对象
|
|
151
|
-
* @param {Object} channel - RabbitMQ频道
|
|
152
|
-
* @param {string} deliveryTag - 消息标签
|
|
153
|
-
* @private
|
|
154
|
-
*/
|
|
155
|
-
async _rejectMessage(msg, channel, deliveryTag) {
|
|
156
|
-
await happy.sleep(5);
|
|
157
|
-
|
|
158
|
-
if (this.processingMessages.has(deliveryTag)) {
|
|
159
|
-
try {
|
|
160
|
-
channel.reject(msg, true);
|
|
161
|
-
this.processingMessages.delete(deliveryTag);
|
|
162
|
-
log.log(`❌ 消息 ${deliveryTag} 已拒绝并重新排队`);
|
|
163
|
-
} catch (rejectError) {
|
|
164
|
-
log.error(`拒绝消息 ${deliveryTag} 时出错:`, rejectError.message);
|
|
165
|
-
this.processingMessages.delete(deliveryTag);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* 清理所有处理中的消息状态
|
|
172
|
-
*/
|
|
173
|
-
clearProcessingMessages() {
|
|
174
|
-
this.processingMessages.clear();
|
|
175
|
-
log.log('已清理所有消息处理状态');
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* 获取当前处理中的消息数量
|
|
180
|
-
* @returns {number} 处理中的消息数量
|
|
181
|
-
*/
|
|
182
|
-
getProcessingCount() {
|
|
183
|
-
return this.processingMessages.size;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
module.exports = MessageProcessor;
|