/// <summary> /// 监控消费(只消费一次) /// </summary> /// <param name="listener">消费事件</param> /// <param name="autoAck">是否自动确认,默认false</param> public void StartSignle(IListenerMessageSingle listener, bool autoAck = false) { Connect(); // 只获取一次 var resp = _channel.BasicGet(_queueName, autoAck); var result = false; var message = Encoding.UTF8.GetString(resp.Body.ToArray()); try { result = listener.Consumer(message, resp); if (!result) { result = listener.FailureHandling(message, resp); } } catch (Exception e) { IocCollection.GetService <ILoggerFactory>().CreateLogger(listener.GetType()).LogError(e, e.Message); // 消费失败后处理 try { result = listener.FailureHandling(message, resp); } catch (Exception exception) { IocCollection.GetService <ILoggerFactory>() .CreateLogger(listener.GetType()) .LogError(exception, "失败处理出现异常:" + listener.GetType().FullName); result = false; } } finally { if (!autoAck) { if (result) { _channel.BasicAck(resp.DeliveryTag, false); } else { _channel.BasicReject(resp.DeliveryTag, true); } } Close(); } }
/// <summary> /// 定时检查连接状态 /// </summary> private void CheckStatsAndConnect() { // 大于0,才开起自动重连 if (this._lastAckTimeoutRestart < 1) { return; } // 检查连接状态 _cts = new CancellationTokenSource(); Task.Factory.StartNew(token => { var cancellationToken = (CancellationToken)token; try { while (true) { cancellationToken.ThrowIfCancellationRequested(); // 未打开、关闭状态、上一次ACK超时,则重启 if (_channel == null || _channel.IsClosed) { IocCollection.GetService <ILoggerFactory>().CreateLogger(this.GetType()).LogWarning($"发现Rabbit未连接,或已关闭,开始重新连接"); ReStart(); } else if ((DateTime.Now - _lastAckAt).TotalSeconds >= _lastAckTimeoutRestart) { IocCollection.GetService <ILoggerFactory>().CreateLogger(this.GetType()).LogWarning($"rabbit距上一次消费过去了{(DateTime.Now - _lastAckAt).TotalSeconds}秒后没有新的消息,尝试重新连接Rabbit。"); ReStart(); } Thread.Sleep(3000); } } catch (Exception e) { IocCollection.GetService <ILoggerFactory>().CreateLogger(this.GetType()).LogWarning(e.Message); } }, _cts.Token); }
/// <summary> /// 持续消费,并检查连接状态并自动恢复 /// </summary> private void Connect(IListenerMessage listener, bool autoAck = false) { Connect(); _channel.BasicQos(0, (ushort)_consumeThreadNums, false); var consumer = new EventingBasicConsumer(_channel); consumer.Received += (model, ea) => { bool result = true; string?message = Encoding.UTF8.GetString(ea.Body.ToArray()); try { listener.Consumer(message, model, ea); _lastAckAt = DateTime.Now; } catch (AlreadyClosedException e) // rabbit被关闭了,重新打开链接 { ReStart(); //IocCollection.GetService<ILoggerFactory>() // .CreateLogger(listener.GetType()) // .LogError(e, e.ToString()); } catch (Exception e) { // 全局异常处理 IocCollection.GetService <IGlobalException>()?.Handle(e, message); // 消费失败后处理 //IocCollection.GetService<ILoggerFactory>() // .CreateLogger(listener.GetType()) // .LogError(e, e.ToString()); try { result = listener.FailureHandling(message, model, ea); } catch (Exception exception) { //IocCollection.GetService<ILoggerFactory>() // .CreateLogger(listener.GetType()) // .LogError(exception, "失败处理出现异常:" + listener.GetType().FullName); result = false; } } finally { if (!autoAck) { if (result) { _channel.BasicAck(ea.DeliveryTag, false); } else { _channel.BasicReject(ea.DeliveryTag, true); } } } }; // 消费者开启监听 _channel.BasicConsume(queue: _queueName, autoAck: autoAck, consumer: consumer); }