Service Bus如何确保消息发送成功,发送端是否有Ack机制(是否有回调API告诉发送端,服务端已经收到消息)?根据对.NET发送Service Bus消息代码的分析,发送方法queueClient.SendAsync(message)并无返回值,因此没法知道发送消息是否成功。git
Azure 服务总线已针对持久性进行优化,会确保在服务确认请求成功以前,发送到服务总线的全部数据将提交到存储。一旦服务总线成功“ACK”(确认)请求,即表示服务总线已成功处理该请求。 若是服务总线返回“NACK”(失败),则表示服务总线没法处理该请求,客户端应用程序必须重试该请求。官方提供的SDK,在没有自定义RetryPolicy的状况下,都会采用默认的重试机制。github
Service Bus .Net SDK 默认的重试机制(RetryPolicy)为:c#
因此在调用Service Bus SDK发送消息时,若是代码正常执行且没有Exception,则表示消息成功发送。api
一句话总结为:无错即成功,失败看异常。服务器
另外也有以下两种发送俩查看消息:网络
- 用户代码错误(System.ArgumentException、System.InvalidOperationException、System.OperationCanceledException、System.Runtime.Serialization.SerializationException)。 常规操做:继续以前尝试修复代码。
- 设置/配置错误(Microsoft.ServiceBus.Messaging.MessagingEntityNotFoundException、System.UnauthorizedAccessException)。 常规操做:检查配置,必要时进行更改。
- 暂时性异常(Microsoft.ServiceBus.Messaging.MessagingException、Microsoft.ServiceBus.Messaging.ServerBusyException、Microsoft.ServiceBus.Messaging.MessagingCommunicationException)。 常规操做:重试操做或通知用户。 客户端 SDK 中的
RetryPolicy
类能够配置为自动处理重试。 有关详细信息,请参阅重试指南。- 其余异常(System.Transactions.TransactionException、System.TimeoutException、Microsoft.ServiceBus.Messaging.MessageLockLostException、Microsoft.ServiceBus.Messaging.SessionLockLostException)。 常规操做:特定于异常类型。
异常类型
下表列出了消息异常的类型及其缘由,并说明能够采起的建议性操做。session
异常类型 异常类型 说明/缘由/示例 建议的操做 自动/当即重试注意事项 TimeoutException 服务器在 OperationTimeout 控制的指定时间内未响应请求的操做。 服务器可能已完成请求的操做。 这多是因为网络或其余基础结构延迟形成的。 检查系统状态的一致性,并根据须要重试。 请参阅超时异常。 在某些状况下,重试可能会有帮助;在代码中添加剧试逻辑。 InvalidOperationException 不容许在服务器或服务中执行请求的用户操做。 有关详细信息,请查看异常消息。 例如,若是在 ReceiveAndDelete 模式下收到消息,则 Complete() 将生成此异常。 检查代码和文档。 确保请求的操做有效。 重试不起做用。 OperationCanceledException 尝试对已关闭、停止或释放的对象调用某个操做。 在极少数状况下,环境事务已释放。 检查代码并确保代码不会对已释放的对象调用操做。 重试不起做用。 UnauthorizedAccessException TokenProvider 对象没法获取令牌,该令牌无效,或者令牌不包含执行操做所需的声明。 确保使用正确的值建立令牌提供程序。 检查访问控制服务的配置。 在某些状况下,重试可能会有帮助;在代码中添加剧试逻辑。 ArgumentException
ArgumentNullException
ArgumentOutOfRangeException提供给该方法的一个或多个参数均无效。
提供给 NamespaceManager 或 Create 的 URI 包含路径段。
提供给 NamespaceManager 或 Create 的 URI 方案无效。
属性值大于 32 KB。检查调用代码并确保参数正确。 重试不起做用。 MessagingEntityNotFoundException 与操做关联的实体不存在或已被删除。 确保该实体存在。 重试不起做用。 MessageNotFoundException 尝试接收具备特定序列号的消息。 找不到此消息。 确保该消息还没有接收。 检查死信队列,以肯定该消息是否被视为死信。 重试不起做用。 MessagingCommunicationException 客户端没法与服务总线创建链接。 确保提供的主机名正确而且主机可访问。 若是你的代码在使用防火墙/代理的环境中运行,请确保到服务总线域/IP 地址和端口的流量未被阻止。app
若是存在间歇性的链接问题,重试可能会有帮助。 ServerBusyException 服务目前没法处理请求。 客户端能够等待一段时间,并重试操做。 客户端可在特定的时间间隔后重试操做。 若是重试致使其余异常,请检查该异常的重试行为。 MessagingException 在如下状况下,可能会引起通常消息异常: 尝试使用属于其余实体类型(例如主题)的名称或路径建立 QueueClient。async
尝试发送大于 256 KB 的消息。ide
服务器或服务在处理请求期间遇到错误。 有关详细信息,请查看异常消息。 这一般是暂时性异常。
因为实体正受到限制,所以已终止请求。 错误代码:5000一、5000二、50008。
检查代码,并确保只对消息正文使用可序列化对象(或使用自定义序列化程序)。 在文档中查看属性支持的值类型,并只使用支持的类型。
检查 IsTransient 属性。 若是为 true,能够重试操做。
若是异常是因为限制致使的,请等待几秒钟,而后重试该操做。 重试行为未定义,在其余场景中可能没有帮助。 MessagingEntityAlreadyExistsException 尝试使用已被该服务命名空间中另外一实体使用的名称建立实体。 删除现有的实体,或者选择不一样的名称来建立实体。 重试不起做用。 QuotaExceededException 消息实体已达到其容许的最大大小,或已超出到命名空间的最大链接数。 经过从实体或其子队列接收消息在该实体中建立空间。 请参阅QuotaExceededException。 若是同时已删除消息,则重试可能会有帮助。 RuleActionException 若是尝试建立无效的规则操做,服务总线将返回此异常。 若是在处理该消息的规则操做时出错,服务总线会将此异常附加到死信消息。 检查规则操做是否正确。 重试不起做用。 FilterException 若是尝试建立无效的筛选器,服务总线将返回此异常。 若是在处理该消息的筛选器时出错,服务总线会将此异常附加到死信消息。 检查筛选器是否正确。 重试不起做用。 SessionCannotBeLockedException 尝试接受具备特定会话 ID 的会话,但该会话当前已被另外一客户端锁定。 确保该会话未由其余客户端锁定。 若是在此期间会话已释放,则重试可能会有帮助。 TransactionSizeExceededException 事务包含过多的操做。 减小此事务中操做的数目。 重试不起做用。 MessagingEntityDisabledException 对已禁用的实体请求运行时操做。 激活实体。 若是在此期间该实体已激活,则重试可能会有帮助。 NoMatchingSubscriptionException 若是向已启用预筛选的主题发送消息而且全部筛选器都不匹配,则服务总线返回此异常。 确保至少有一个筛选器匹配。 重试不起做用。 MessageSizeExceededException 消息有效负载超出 256 KB 限制。 256-KB 限制是指总消息大小,可能包括系统属性和任何 .NET 开销。 减小消息负载的大小,并重试操做。 重试不起做用。 TransactionException 环境事务 (Transaction.Current) 无效。 该事务可能已完成或已停止。 内部异常可能提供了更多信息。 重试不起做用。 TransactionInDoubtException 已对未决事务尝试进行操做,或尝试提交该事务而且事务进入不肯定状态。 应用程序必须处理此异常(做为特例),由于此事务可能已提交。
Service Bus Explorer: https://github.com/paolosalvatori/ServiceBusExplorer/releases
Service Bus Retry Policy: https://docs.microsoft.com/en-us/azure/architecture/best-practices/retry-service-specific#service-bus