服务总线队列、主题和订阅Service Bus queues, topics, and subscriptions

Azure 服务总线支持一组基于云的、面向消息的中间件技术,包括可靠的消息队列和持久发布/订阅消息。Azure Service Bus supports a set of cloud-based, message-oriented middleware technologies including reliable message queuing and durable publish/subscribe messaging. 这些中转消息传送功能可被视为分离式消息传送功能,支持使用服务总线消息传送工作负载的发布-订阅、临时分离和负载均衡方案。These brokered messaging capabilities can be thought of as decoupled messaging features that support publish-subscribe, temporal decoupling, and load-balancing scenarios using the Service Bus messaging workload. 分离式通信具有很多优点。Decoupled communication has many advantages. 例如,客户端和服务器可以根据需要进行连接并以异步方式执行其操作。For example, clients and servers can connect as needed and do their operations in an asynchronous fashion.

构成服务总线消息传送功能核心的消息传送实体包括队列、主题和订阅以及规则/操作 。The messaging entities that form the core of the messaging capabilities in Service Bus are queues, topics and subscriptions, and rules/actions.

队列Queues

队列为一个或多个竞争使用方提供 先入先出 (FIFO) 消息传递方式。Queues offer First In, First Out (FIFO) message delivery to one or more competing consumers. 也就是说,接收方通常会按照消息添加到队列中的顺序来接收并处理消息。That is, receivers typically receive and process messages in the order in which they were added to the queue. 并且每条消息仅由一个消息使用方接收并处理。And, only one message consumer receives and processes each message. 使用队列的主要优点是实现应用程序组件的临时分离。A key benefit of using queues is to achieve temporal decoupling of application components. 换句话说,创建方(发送方)和使用方(接收方)不必同时发送和接收消息。In other words, the producers (senders) and consumers (receivers) don't have to send and receive messages at the same time. 这是因为消息已持久存储在队列中。That's because messages are stored durably in the queue. 此外,创建方不必等待使用方的答复即可继续处理并发送更多消息。Furthermore, the producer doesn't have to wait for a reply from the consumer to continue to process and send messages.

相关的优点是“负载分级”,它允许创建方和使用方以不同速率发送和接收消息。A related benefit is load-leveling, which enables producers and consumers to send and receive messages at different rates. 在许多应用程序中,系统负载随时间而变化。In many applications, the system load varies over time. 但是,每个工作单元所需的处理时间通常为常量。However, the processing time required for each unit of work is typically constant. 使用队列在消息创建方与使用方之间中继意味着,消费应用程序只需能够处理平均负载而非峰值负载。Intermediating message producers and consumers with a queue means that the consuming application only has to be able to handle average load instead of peak load. 队列深度将随传入负载的变化而加大和减小。The depth of the queue grows and contracts as the incoming load varies. 此功能会直接根据为应用程序加载提供服务所需的基础结构的数目来节省成本。This capability directly saves money with regard to the amount of infrastructure required to service the application load. 随着负载增加,可添加更多的工作进程以从队列中读取。As the load increases, more worker processes can be added to read from the queue. 每条消息仅由一个辅助进程处理。Each message is processed by only one of the worker processes. 另外,可通过基于拉取的该负载均衡,以最合理的方式使用辅助计算机,即使具有处理能力的辅助计算机以其最大速率拉取消息也是如此。Furthermore, this pull-based load balancing allows for best use of the worker computers even if the worker computers with processing power pull messages at their own maximum rate. 此模式通常称为 使用者竞争 模式。This pattern is often termed the competing consumer pattern.

使用队列在消息创建方与使用方之间中继可在各组件之间提供固有的松散耦合。Using queues to intermediate between message producers and consumers provides an inherent loose coupling between the components. 由于创建方和使用方互不相识,因此,可升级使用方,而不会对创建方产生任何影响。Because producers and consumers aren't aware of each other, a consumer can be upgraded without having any effect on the producer.

创建队列Create queues

可以使用 Azure 门户PowerShellCLI资源管理器模板创建队列。You can create queues using the Azure portal, PowerShell, CLI, or Resource Manager templates. 然后,使用以 C#JavaPythonJavaScriptPHPRuby 编写的客户端发送和接收消息。Then, send and receive messages using clients written in C#, Java, Python, JavaScript, PHP, and Ruby.

接收模式Receive modes

可以指定服务总线接收消息所用的两种不同模式:ReceiveAndDelete 或 PeekLock 。You can specify two different modes in which Service Bus receives messages: ReceiveAndDelete or PeekLock. ReceiveAndDelete 模式下,当服务总线收到来自使用者的请求时,它会将该消息标记为“正在使用”,并将其返回给使用者应用程序。In the ReceiveAndDelete mode, when Service Bus receives the request from the consumer, it marks the message as being consumed and returns it to the consumer application. 此模式是最简单的模型。This mode is the simplest model. 它最适合应用程序允许在出现故障时不处理消息的方案。It works best for scenarios in which the application can tolerate not processing a message if a failure occurs. 为了理解此方案,可以考虑这样一种情形:使用方发出接收请求,但在处理该请求前发生了崩溃。To understand this scenario, consider a scenario in which the consumer issues the receive request and then crashes before processing it. 由于服务总线会将消息标记为“正在使用”,应用程序会在重新启动后开始使用消息。As Service Bus marks the message as being consumed, the application begins consuming messages upon restart. 它会丢失在发生故障前使用的消息。It will miss the message that it consumed before the crash.

PeekLock 模式下,接收操作分成了两步,从而有可能支持无法容忍遗漏消息的应用程序。In the PeekLock mode, the receive operation becomes two-stage, which makes it possible to support applications that can't tolerate missing messages. 当服务总线收到请求时,它将执行以下操作:When Service Bus receives the request, it does the following operations:

  1. 查找要使用的下一条消息。Finds the next message to be consumed.
  2. 将其锁定以防止其他使用者接收该消息。Locks it to prevent other consumers from receiving it.
  3. 然后,将该消息返回到应用程序。Then, return the message to the application.

应用程序处理完消息或安全存储该消息以供将来处理后,会通过对消息调用 CompleteAsync 来完成接收过程的第二个阶段。After the application finishes processing the message or stores it reliably for future processing, it completes the second stage of the receive process by calling CompleteAsync on the message. 服务总线接收到 CompleteAsync 请求时会将消息标记为“正在使用”。When Service Bus receives the CompleteAsync request, it marks the message as being consumed.

如果应用程序因某种原因而无法处理消息,它可对消息调用 AbandonAsync 方法(而不是 CompleteAsync 方法)。If the application is unable to process the message for some reason, it can call the AbandonAsync method on the message (instead of CompleteAsync). 此方法可使服务总线解锁消息并使其能够重新被同一个使用方或其他竞争使用方接收。This method enables Service Bus to unlock the message and make it available to be received again, either by the same consumer or by another competing consumer. 其次,有一个与锁定关联的超时。Secondly, there's a timeout associated with the lock. 如果应用程序无法在锁定超时期满前处理消息,服务总线会解锁消息,使其再次可供接收。If the application fails to process the message before the lock timeout expires, Service Bus unlocks the message and makes it available to be received again.

如果应用程序在处理消息之后,但在调用 CompleteAsync 之前发生故障,服务总线会在应用程序重新启动时将该消息重新传送给应用程序。If the application crashes after it processes the message, but before it calls CompleteAsync, Service Bus redelivers the message to the application when it restarts. 此过程通常称为“至少一次”处理。This process is often called at-least once processing. 也就是说,每条消息至少处理一次。That is, each message is processed at least once. 但是,在某些情况下,同一消息可能会被重新传送。However, in certain situations the same message may be redelivered. 如果方案不容许重复处理,请在应用程序中添加其他逻辑来检测重复项。If your scenario can't tolerate duplicate processing, add additional logic in your application to detect duplicates. 可以通过使用消息的 MessageId 属性来实现,该属性在多次传送尝试中保持不变。You can achieve it by using the MessageId property of the message, which remains constant across delivery attempts. 此功能称为“仅一次”处理。This feature is known as exactly once processing.

主题和订阅Topics and subscriptions

队列允许单个使用方处理消息。A queue allows processing of a message by a single consumer. 与队列不同,主题和订阅以“发布和订阅”模式提供一对多的通信形式。In contrast to queues, topics and subscriptions provide a one-to-many form of communication in a publish and subscribe pattern. 这对于扩展到大量接收方而言十分有用。It's useful for scaling to large numbers of recipients. 每个发布的消息均可用于向该主题注册的每个订阅。Each published message is made available to each subscription registered with the topic. 发布方将消息发送到主题,一个或多个订阅服务器将接收该消息的副本,具体取决于对这些订阅设置的筛选规则。Publisher sends a message to a topic and one or more subscribers receive a copy of the message, depending on filter rules set on these subscriptions. 此订阅可以使用其他筛选器来限制其想要接收的消息。The subscriptions can use additional filters to restrict the messages that they want to receive. 发布方将消息发送到主题的方式与将消息发送到队列的方式相同。Publishers send messages to a topic in the same way that they send messages to a queue. 但使用方不会直接从主题接收消息。But, consumers don't receive messages directly from the topic. 相反,使用方从该主题的订阅接收消息。Instead, consumers receive messages from subscriptions of the topic. 主题订阅类似于接收发送至该主题的消息副本的虚拟队列。A topic subscription resembles a virtual queue that receives copies of the messages that are sent to the topic. 使用方从订阅接收消息的方式与从队列接收消息的方式相同。Consumers receive messages from a subscription identically to the way they receive messages from a queue.

队列的消息发送功能直接映射到主题,而其消息接收功能映射到订阅。The message-sending functionality of a queue maps directly to a topic and its message-receiving functionality maps to a subscription. 此外,此功能意味着订阅支持本部分中前面有关队列所述的相同模式:竞争使用者、临时分离、负荷量和负载均衡。Among other things, this feature means that subscriptions support the same patterns described earlier in this section with regard to queues: competing consumer, temporal decoupling, load leveling, and load balancing.

创建主题和订阅Create topics and subscriptions

创建主题与创建队列类似,如前一部分中所述。Creating a topic is similar to creating a queue, as described in the previous section. 可以使用 Azure 门户PowerShellCLI资源管理器模板创建主题和订阅。You can create topics and subscriptions using the Azure portal, PowerShell, CLI, or Resource Manager templates. 然后,使用以 C#JavaPythonJavaScriptPHPRuby 编写的客户端将消息发送到主题并从订阅接收消息。Then, send messages to a topic and receive messages from subscriptions using clients written in C#, Java, Python, JavaScript, PHP, and Ruby.

规则和操作Rules and actions

在许多情况下,必须以不同方式处理具有特定特征的消息。In many scenarios, messages that have specific characteristics must be processed in different ways. 若要启用此处理,可配置订阅以找到具有所需属性的消息,并对这些属性执行某些修改。To enable this processing, you can configure subscriptions to find messages that have desired properties and then perform certain modifications to those properties. 虽然服务总线订阅可以看到发送到主题的所有消息,但你仅可以将这些消息的一个子集复制到虚拟订阅队列。While Service Bus subscriptions see all messages sent to the topic, you can only copy a subset of those messages to the virtual subscription queue. 可使用订阅筛选器完成此筛选。This filtering is accomplished using subscription filters. 此类修改称为筛选器操作 。Such modifications are called filter actions. 创建订阅后,你可以提供对消息属性进行操作的筛选表达式。When a subscription is created, you can supply a filter expression that operates on the properties of the message. 这些属性可以是系统属性(例如“标签”),也可以是自定义应用程序属性(例如“StoreName” 。)SQL 筛选器表达式在此示例中为可选。The properties can be both the system properties (for example, Label) and custom application properties (for example, StoreName.) The SQL filter expression is optional in this case. 如果没有 SQL 筛选器表达式,会对该订阅的所有消息执行在订阅上定义的任何筛选器操作。Without a SQL filter expression, any filter action defined on a subscription will be done on all the messages for that subscription.

有关完整的工作示例,请参阅GitHub上的 TopicSubscriptionWithRuleOperationsSample 示例For a full working example, see the TopicSubscriptionWithRuleOperationsSample sample on GitHub.

有关可能的筛选器值的详细信息,请参阅文档 SqlFilterSqlRuleAction 类。For more information about possible filter values, see the documentation for the SqlFilter and SqlRuleAction classes.

Java 消息实体 (JMS) 2.0 实体(预览版)Java message service (JMS) 2.0 entities (Preview)

以下实体可通过 Java 消息服务 (JMS) 2.0 API 进行访问。The following entities are accessible through the Java message service (JMS) 2.0 API.

  • 临时队列Temporary queues
  • 临时主题Temporary topics
  • 共享持久订阅Shared durable subscriptions
  • 非共享持久订阅Unshared durable subscriptions
  • 共享非持久订阅Shared non-durable subscriptions
  • 非共享非持久订阅Unshared non-durable subscriptions

详细了解 JMS 2.0 实体和如何使用它们Learn more about the JMS 2.0 entities and about how to use them.

后续步骤Next steps

有关使用服务总线消息传送的详细信息和示例,请参阅以下高级主题:For more information and examples of using Service Bus messaging, see the following advanced topics: