移除自建消费者与队列拓扑,统一由事件总线发布/消费,并优化下游转发查询与配置。 Co-authored-by: Cursor <cursoragent@cursor.com>
92 lines
3.0 KiB
C#
92 lines
3.0 KiB
C#
using Fake;
|
||
using Fake.EventBus.RabbitMQ;
|
||
using Fake.RabbitMQ;
|
||
using Microsoft.Extensions.Logging;
|
||
using Microsoft.Extensions.Options;
|
||
using Oms.Application.Dtos.Orders;
|
||
using RabbitMQ.Client;
|
||
|
||
namespace Oms.Application.Messaging;
|
||
|
||
public interface IOrderBatchQueueInspector
|
||
{
|
||
bool IsEnabled { get; }
|
||
|
||
Task<OrderBatchDlxStatsOutput> GetStatsAsync(CancellationToken cancellationToken = default);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 巡检 Fake.EventBus.RabbitMQ 的工作队列与死信队列。
|
||
/// </summary>
|
||
public sealed class OrderBatchQueueInspector(
|
||
IRabbitMqConnectionPool connectionPool,
|
||
IOptions<OrderBatchRabbitMqOptions> options,
|
||
IOptions<RabbitMqEventBusOptions> eventBusOptions,
|
||
IApplicationInfo applicationInfo,
|
||
ILogger<OrderBatchQueueInspector> logger) : IOrderBatchQueueInspector
|
||
{
|
||
/// <summary>
|
||
/// DLX 堆积告警默认阈值。
|
||
/// </summary>
|
||
public const uint DefaultDlxAlertThreshold = 100;
|
||
|
||
public bool IsEnabled => options.Value.Enabled;
|
||
|
||
public Task<OrderBatchDlxStatsOutput> GetStatsAsync(CancellationToken cancellationToken = default)
|
||
{
|
||
if (!options.Value.Enabled)
|
||
{
|
||
return Task.FromResult(new OrderBatchDlxStatsOutput
|
||
{
|
||
Enabled = false,
|
||
DlxAlertThreshold = DefaultDlxAlertThreshold,
|
||
});
|
||
}
|
||
|
||
var busOptions = eventBusOptions.Value;
|
||
// 与 RabbitMqEventBus 一致:QueueName 为空时用 ApplicationName
|
||
var queueName = (busOptions.QueueName ?? applicationInfo.ApplicationName).TrimEnd('.') + ".Queue";
|
||
var dlxQueueName = "DLX." + queueName;
|
||
|
||
// Connection 由 Fake 连接池托管,禁止 Dispose
|
||
var connection = connectionPool.Get(busOptions.ConnectionName);
|
||
using var channel = connection.CreateModel();
|
||
|
||
var queues = new List<OrderBatchQueueStatOutput>
|
||
{
|
||
InspectQueue(channel, queueName),
|
||
InspectQueue(channel, dlxQueueName),
|
||
};
|
||
|
||
var dlxCount = queues.First(x => x.QueueName == dlxQueueName).MessageCount;
|
||
logger.LogDebug("Order batch Fake EventBus queue stats, dlxMessages={DeadLetterCount}", dlxCount);
|
||
|
||
return Task.FromResult(new OrderBatchDlxStatsOutput
|
||
{
|
||
Enabled = true,
|
||
DeadLetterMessageCount = dlxCount,
|
||
DlxAlertThreshold = DefaultDlxAlertThreshold,
|
||
Alert = dlxCount >= DefaultDlxAlertThreshold,
|
||
Queues = queues,
|
||
});
|
||
}
|
||
|
||
private static OrderBatchQueueStatOutput InspectQueue(IModel channel, string queueName)
|
||
{
|
||
try
|
||
{
|
||
var declare = channel.QueueDeclarePassive(queueName);
|
||
return new OrderBatchQueueStatOutput
|
||
{
|
||
QueueName = queueName,
|
||
MessageCount = declare.MessageCount,
|
||
ConsumerCount = declare.ConsumerCount,
|
||
};
|
||
}
|
||
catch (Exception)
|
||
{
|
||
return new OrderBatchQueueStatOutput { QueueName = queueName };
|
||
}
|
||
}
|
||
}
|