我对您围绕MessageSender类开发包装器的经验有疑问。我真的找不到真正的企业示例。我有一个仅用于将消息发送到队列的组件。我的吞吐量相当不错,每天约25,000。消息不是时间敏感的,因为它会在完成时触发后台过程完成。
我有兴趣在此方面进行一些对话。我觉得自己在为花生而烦恼,但由于我缺乏Azure经验,因此要确保我不会忽略任何事情。
我已将MessageSender对象实现为单例,无需重新创建。我确实不需要多个MessageSender对象,也没有理由每次需要时都要继续处理/初始化一个新对象。 (即使消息量不大,也会相当频繁地使用它)。出于对Lazy的Thread安全性的考虑,我将Lazy用作纯静态初始化程序。
我应该担心我的包装器类的多个实例引用同一个MessageSender对象吗?
/// <summary>
/// Lazy Loading MessageSender object used to send messages to the queue.
/// </summary>
private static Lazy<MessageSender> _MessageSender = new Lazy<MessageSender>(() =>
{
string _AzureServiceBusConnectionString = "redacted";
string _AzureServiceBusQueue ="redacted";
MessagingFactory factory = MessagingFactory.CreateFromConnectionString(_AzureServiceBusConnectionString);
factory.RetryPolicy = new RetryExponential(minBackoff: ServiceBusClient._MinBackOff,
maxBackoff: ServiceBusClient._MaxBackOff,
maxRetryCount: ServiceBusClient._MaxRetryCount);
return factory.CreateMessageSender(_AzureServiceBusQueue);
});
/// <summary>
/// Lazy loading QueueDescription object used to get queue availability.
/// </summary>
private static Lazy<QueueDescription> _QueueDescription = new Lazy<QueueDescription>(() =>
{
string _AzureServiceBusConnectionString = "redacted";
string _AzureServiceBusQueue ="redacted";
return NamespaceManager.CreateFromConnectionString(_AzureServiceBusConnectionString).GetQueue(_AzureServiceBusQueue);
});
/// <summary>
/// Gets the MessageSender, and instantiates it if not initialized.
/// </summary>
/// <value>
/// Azure Service Bus Queue MessageSender.
/// </value>
private MessageSender Sender
{
get
{
return ServiceBusClient._MessageSender.Value;
}
}
/// <summary>
/// Sends a single message to the Service Bus.
/// </summary>
/// <param name="searchMessageDTO">The search message dto.</param>
public void SendMessage(ISearchMessageDTO searchMessageDTO)
{
if (ServiceBusClient.IsServiceBusAvailable())
{
try
{
BrokeredMessage bm = this.ConvertDTOToBrokeredMessage(searchMessageDTO);
this.Sender.SendAsync(bm);
}
catch (Exception ex)
{
//Log Error Redacted
}
}
}
/// <summary>
/// Sends a batch of messages to the Service Bus.
/// </summary>
/// <param name="searchMessageDTOs">List of search messages to send.</param>
public void SendMessageBatch(List<ISearchMessageDTO> searchMessageDTOs)
{
if (ServiceBusClient.IsServiceBusAvailable())
{
try
{
List<BrokeredMessage> bms = new List<BrokeredMessage>();
foreach (ISearchMessageDTO dto in searchMessageDTOs)
{
bms.Add(this.ConvertDTOToBrokeredMessage(dto));
}
this.Sender.SendBatchAsync(bms);
}
catch (Exception ex)
{
//Log Error Redacted
}
}
}
/// <summary>
/// Converts the dto implementation to a brokered message.
/// </summary>
/// <param name="searchMessageDTO">The search message dto.</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException">searchMessageDTO</exception>
private BrokeredMessage ConvertDTOToBrokeredMessage(ISearchMessageDTO searchMessageDTO)
{
if (searchMessageDTO == null)
{
throw new ArgumentNullException("searchMessageDTO");
}
BrokeredMessage bm = new BrokeredMessage(JsonConvert.SerializeObject(searchMessageDTO));
return bm;
}
/// <summary>
/// Determines whether the Service Bus Queue is available by checking availability status of queue.
/// </summary>
/// <returns>
/// True if EntityAvailabilityStatus.Available otherwise False.
/// </returns>
public static bool IsServiceBusAvailable()
{
EntityAvailabilityStatus eas = ServiceBusClient._QueueDescription.Value.AvailabilityStatus;
if (eas == EntityAvailabilityStatus.Available)
{
return true;
}
else
{
return false;
}
}
}
谢谢!