快速入门:如何通过 Ruby 使用服务总线主题和订阅Quickstart: How to use Service Bus topics and subscriptions with Ruby

本文介绍如何从 Ruby 应用程序使用服务总线主题和订阅。This article describes how to use Service Bus topics and subscriptions from Ruby applications. 涉及的方案包括:The scenarios covered include:

  • 创建主题和订阅Creating topics and subscriptions
  • 创建订阅筛选器Creating subscription filters
  • 将消息发送到主题Sending messages to a topic
  • 从订阅接收消息Receiving messages from a subscription
  • 删除主题和订阅Deleting topics and subscriptions

先决条件Prerequisites

  1. Azure 订阅。An Azure subscription. 若要完成本教程,需要一个 Azure 帐户。To complete this tutorial, you need an Azure account. 可以激活你的 Visual Studio 或 MSDN 订阅者权益或者注册试用帐户You can activate your Visual Studio or MSDN subscriber benefits or sign-up for a trial account.

  2. 按照快速入门:使用 Azure 门户创建一个服务总线主题和对此主题的订阅来创建服务总线命名空间并获取连接字符串Follow steps in the Quickstart: Use the Azure portal to create a Service Bus topic and subscriptions to the topic to create a Service Bus namespace and get the connection string.

    备注

    在本快速入门中,你将使用 Ruby 创建一个主题和对此主题的订阅You will create a topic and a subscription to the topic by using Ruby in this quickstart.

创建 Ruby 应用程序Create a Ruby application

有关说明,请参阅在 Azure 上创建 Ruby 应用程序For instructions, see Create a Ruby Application on Azure.

配置应用程序以使用服务总线Configure Your application to Use Service Bus

若要使用服务总线,请下载并使用 Azure Ruby 包,其中包括一组便于与存储 REST 服务进行通信的库。To use Service Bus, download and use the Azure Ruby package, which includes a set of convenience libraries that communicate with the storage REST services.

使用 RubyGems 获取该程序包Use RubyGems to obtain the package

  1. 使用命令行接口,例如 PowerShell (Windows)、Terminal (Mac) 或 Bash (Unix)。Use a command-line interface such as PowerShell (Windows), Terminal (Mac), or Bash (Unix).
  2. 在命令窗口中键入“gem install azure”以安装 gem 和依赖项。Type "gem install azure" in the command window to install the gem and dependencies.

导入包Import the package

使用常用的文本编辑器将以下内容添加到要在其中使用存储的 Ruby 文件的顶部:Using your favorite text editor, add the following to the top of the Ruby file in which you intend to use storage:

require "azure"

设置服务总线连接Set up a Service Bus connection

使用以下代码,设置命名空间、密钥名称、密钥、签名程序和主机的值:Use the following code to set the values of namespace, name of the key, key, signer and host:

Azure.configure do |config|
  config.sb_namespace = '<your azure service bus namespace>'
  config.sb_sas_key_name = '<your azure service bus access keyname>'
  config.sb_sas_key = '<your azure service bus access key>'
end
signer = Azure::ServiceBus::Auth::SharedAccessSigner.new
sb_host = "https://#{Azure.sb_namespace}.servicebus.chinacloudapi.cn"

将命名空间值设置为创建的值,而不是整个 URL 的值。Set the namespace value to the value you created rather than the entire URL. 例如,使用 "yourexamplenamespace",而不是 "yourexamplenamespace.servicebus.chinacloudapi.cn"。For example, use "yourexamplenamespace", not "yourexamplenamespace.servicebus.chinacloudapi.cn".

使用多个命名空间时,可以在创建 SharedAccessSigner 对象时将密钥及其名称传递到构造函数When working with multiple namespaces, you can pass the key and its name to the constructor while creating SharedAccessSigner objects

sb_namespace = '<your azure service bus namespace>'
sb_sas_key_name = '<your azure service bus access keyname>'
sb_sas_key = '<your azure service bus access key>'

signer = Azure::ServiceBus::Auth::SharedAccessSigner.new(sb_sas_key_name, sb_sas_key)
sb_host = "https://#{sb_namespace}.servicebus.chinacloudapi.cn"

创建主题Create a topic

可以通过 Azure::ServiceBusService 对象处理主题。The Azure::ServiceBusService object enables you to work with topics. 以下代码创建 Azure::ServiceBusService 对象。The following code creates an Azure::ServiceBusService object. 要创建主题,请使用 create_topic() 方法。To create a topic, use the create_topic() method. 以下示例将创建一个主题或输出任何错误。The following example creates a topic or prints out any errors.

azure_service_bus_service = Azure::ServiceBus::ServiceBusService.new(sb_host, { signer: signer})
begin
  topic = azure_service_bus_service.create_topic("test-topic")
rescue
  puts $!
end

还可以通过其他选项传递 Azure::ServiceBus::Topic 对象,借助这些选项,可以重写默认主题设置,如消息生存时间或最大队列大小。You can also pass an Azure::ServiceBus::Topic object with additional options, which enable you to override default topic settings such as message time to live or maximum queue size. 下面的示例演示如何将最大队列大小设置为 5 GB,将生存时间设置为 1 分钟:The following example shows setting the maximum queue size to 5 GB and time to live to 1 minute:

topic = Azure::ServiceBus::Topic.new("test-topic")
topic.max_size_in_megabytes = 5120
topic.default_message_time_to_live = "PT1M"

topic = azure_service_bus_service.create_topic(topic)

创建订阅Create subscriptions

主题订阅也是使用 Azure::ServiceBusService 对象创建的。Topic subscriptions are also created with the Azure::ServiceBusService object. 订阅已命名,并且具有一个限制传递到订阅的虚拟队列的消息集的可选筛选器。Subscriptions are named and can have an optional filter that restricts the set of messages delivered to the subscription's virtual queue.

默认情况下,订阅是永久性的。By default, subscriptions are persistent. 除非删除它或与之相关的主题,否则订阅将继续存在。They continue to exist until either they, or the topic they are associated with, are deleted. 如果应用程序包含创建订阅的逻辑,则它应首先使用 getSubscription 方法检查该订阅是否已经存在。If your application contains logic to create a subscription, it should first check if the subscription already exists by using the getSubscription method.

可以通过设置 AutoDeleteOnIdle 属性来自动删除订阅。You can have the subscriptions automatically deleted by setting the AutoDeleteOnIdle property.

创建具有默认 (MatchAll) 筛选器的订阅Create a subscription with the default (MatchAll) filter

如果在创建新订阅时未指定任何筛选器,则将使用默认的 MatchAll 筛选器。If no filter is specified when a new subscription is created, the MatchAll filter (default) is used. 使用 MatchAll 筛选器时,发布到主题的所有消息都会置于订阅的虚拟队列中。When the MatchAll filter is used, all messages published to the topic are placed in the subscription's virtual queue. 以下示例创建了名为“all-messages”的订阅并使用了默认的 MatchAll 筛选器。The following example creates a subscription named "all-messages" and uses the default MatchAll filter.

subscription = azure_service_bus_service.create_subscription("test-topic", "all-messages")

创建具有筛选器的订阅Create subscriptions with filters

还可以定义筛选器,以指定发送到主题的哪些消息应该在特定订阅中显示。You can also define filters that enable you to specify which messages sent to a topic should show up within a specific subscription.

订阅支持的最灵活的筛选器类型是 Azure::ServiceBus::SqlFilter,它实现了部分 SQL92 功能。The most flexible type of filter supported by subscriptions is the Azure::ServiceBus::SqlFilter, which implements a subset of SQL92. SQL 筛选器对发布到主题的消息的属性进行操作。SQL filters operate on the properties of the messages that are published to the topic. 有关可用于 SQL 筛选器的表达式的更多详细信息,请参阅 SqlFilter 语法。For more details about the expressions that can be used with a SQL filter, review the SqlFilter syntax.

可以使用 Azure::ServiceBusService 对象的 create_rule() 方法向订阅中添加筛选器。You can add filters to a subscription by using the create_rule() method of the Azure::ServiceBusService object. 此方法允许用户向现有订阅中添加新筛选器。This method enables you to add new filters to an existing subscription.

由于默认筛选器会自动应用到所有新订阅,因此,必须首先删除默认筛选器,否则 MatchAll 会替代可能指定的任何其他筛选器。Since the default filter is applied automatically to all new subscriptions, you must first remove the default filter, or the MatchAll overrides any other filters you may specify. 可以通过对 Azure::ServiceBusService 对象使用 delete_rule() 方法删除默认规则。You can remove the default rule by using the delete_rule() method on the Azure::ServiceBusService object.

以下示例将创建一个名为“high-messages”的订阅,该订阅包含一个 Azure::ServiceBus::SqlFilter,它仅选择自定义 message_number 属性大于 3 的消息:The following example creates a subscription named "high-messages" with an Azure::ServiceBus::SqlFilter that only selects messages that have a custom message_number property greater than 3:

subscription = azure_service_bus_service.create_subscription("test-topic", "high-messages")
azure_service_bus_service.delete_rule("test-topic", "high-messages", "$Default")

rule = Azure::ServiceBus::Rule.new("high-messages-rule")
rule.topic = "test-topic"
rule.subscription = "high-messages"
rule.filter = Azure::ServiceBus::SqlFilter.new({
  :sql_expression => "message_number > 3" })
rule = azure_service_bus_service.create_rule(rule)

类似地,以下示例创建一个名为 low-messages 的订阅,该订阅包含一个 Azure::ServiceBus::SqlFilter,它仅选择 message_number 属性小于或等于 3 的消息:Similarly, the following example creates a subscription named low-messages with an Azure::ServiceBus::SqlFilter that only selects messages that have a message_number property less than or equal to 3:

subscription = azure_service_bus_service.create_subscription("test-topic", "low-messages")
azure_service_bus_service.delete_rule("test-topic", "low-messages", "$Default")

rule = Azure::ServiceBus::Rule.new("low-messages-rule")
rule.topic = "test-topic"
rule.subscription = "low-messages"
rule.filter = Azure::ServiceBus::SqlFilter.new({
  :sql_expression => "message_number <= 3" })
rule = azure_service_bus_service.create_rule(rule)

现在,当消息发送到 test-topic 时,它始终会传送给订阅了 all-messages 主题订阅的接收者,并且选择性地传送给订阅了 high-messageslow-messages 主题订阅的接收者(具体取决于消息内容)。When a message is now sent to test-topic, it is always be delivered to receivers subscribed to the all-messages topic subscription, and selectively delivered to receivers subscribed to the high-messages and low-messages topic subscriptions (depending upon the message content).

将消息发送到主题Send messages to a topic

要将消息发送到服务总线主题,应用程序必须对 Azure::ServiceBusService 对象使用 send_topic_message() 方法。To send a message to a Service Bus topic, your application must use the send_topic_message() method on the Azure::ServiceBusService object. 发送到服务总线主题的消息是 Azure::ServiceBus::BrokeredMessage 对象的实例。Messages sent to Service Bus topics are instances of the Azure::ServiceBus::BrokeredMessage objects. Azure::ServiceBus::BrokeredMessage 对象具有一组标准属性(如 labeltime_to_live)、一个用于保存自定义的应用程序特定属性的字典,以及大量字符串数据。Azure::ServiceBus::BrokeredMessage objects have a set of standard properties (such as label and time_to_live), a dictionary that is used to hold custom application-specific properties, and a body of string data. 应用程序可以通过将字符串值传递给 send_topic_message() 方法设置消息正文,并且任何必需的标准属性将用默认值填充。An application can set the body of the message by passing a string value to the send_topic_message() method and any required standard properties are populated by default values.

以下示例演示如何向 test-topic发送五条测试消息。The following example demonstrates how to send five test messages to test-topic. 每条消息的 message_number 自定义属性值因循环迭代而异(这会确定接收消息的订阅):The message_number custom property value of each message varies on the iteration of the loop (it determines which subscription receives it):

5.times do |i|
  message = Azure::ServiceBus::BrokeredMessage.new("test message " + i,
    { :message_number => i })
  azure_service_bus_service.send_topic_message("test-topic", message)
end

服务总线主题在标准层中支持的最大消息大小为 256 KB,在高级层中则为 1 MB。Service Bus topics support a maximum message size of 256 KB in the Standard tier and 1 MB in the Premium tier. 标头最大大小为 64 KB,其中包括标准和自定义应用程序属性。The header, which includes the standard and custom application properties, can have a maximum size of 64 KB. 一个主题中包含的消息数量不受限制,但消息的总大小受限制。There is no limit on the number of messages held in a topic but there is a cap on the total size of the messages held by a topic. 此主题大小是在创建时定义的,上限为 5 GB。This topic size is defined at creation time, with an upper limit of 5 GB.

从订阅接收消息Receive messages from a subscription

对 Azure::ServiceBusService 对象使用 receive_subscription_message() 方法可从订阅接收消息。Messages are received from a subscription using the receive_subscription_message() method on the Azure::ServiceBusService object. 默认情况下,消息在被读取(查看)的同时会被锁定,从而无法从订阅中删除。By default, messages are read(peak) and locked without deleting it from the subscription. 但是,可以通过将 peek_lock 选项设置为“false”,读取消息并将其从订阅中删除。You can read and delete the message from the subscription by setting the peek_lock option to false.

默认行为使读取和删除变成一个两阶段操作,从而也有可能支持不允许遗漏消息的应用程序。The default behavior makes the reading and deleting a two-stage operation, which also makes it possible to support applications that cannot tolerate missing messages. 当 Service Bus 收到请求时,它会查找下一条要使用的消息,锁定该消息以防其他使用者接收,并将该消息返回到应用程序。When Service Bus receives a request, it finds the next message to be consumed, locks it to prevent other consumers receiving it, and then returns it to the application. 应用程序处理完该消息(或将它可靠地存储起来留待将来处理)后,通过调用 delete_subscription_message() 方法并提供要删除的消息作为参数,完成接收过程的第二阶段。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 delete_subscription_message() method and providing the message to be deleted as a parameter. delete_subscription_message() 方法会将消息标记为已使用,并将其从订阅中删除。The delete_subscription_message() method marks the message as being consumed and remove it from the subscription.

如果 :peek_lock 参数设置为“false”,读取并删除消息将是最简单的模式,并且最适合在发生故障时应用程序可以容忍不处理消息的情况。If the :peek_lock parameter is set to false, reading, and deleting the message becomes the simplest model, and works best for scenarios in which an application can tolerate not processing a message when a failure occurs. 可以考虑这样一种情形:使用者发出接收请求,但在处理该请求前发生了故障。Consider a scenario in which the consumer issues the receive request and then crashes before processing it. 由于服务总线已将消息标记为“已使用”,因此当应用程序重新启动并重新开始使用消息时,它会漏掉在发生崩溃前使用的消息。Because Service Bus has marked the message as being consumed, then when the application restarts and begins consuming messages again, it has missed the message that was consumed prior to the crash.

以下示例演示如何使用 receive_subscription_message() 接收和处理消息。The following example demonstrates how messages can be received and processed using receive_subscription_message(). 该示例先通过将 :peek_lock 设置为“false”从 low-messages 订阅接收一条消息并将其删除,然后再从 high-messages 接收另一条消息,最后使用 delete_subscription_message() 删除该消息:The example first receives and deletes a message from the low-messages subscription by using :peek_lock set to false, then it receives another message from the high-messages and then deletes the message using delete_subscription_message():

message = azure_service_bus_service.receive_subscription_message(
  "test-topic", "low-messages", { :peek_lock => false })
message = azure_service_bus_service.receive_subscription_message(
  "test-topic", "high-messages")
azure_service_bus_service.delete_subscription_message(message)

如何处理应用程序崩溃和不可读消息How to handle application crashes and unreadable messages

Service Bus 提供了相关功能来帮助你轻松地从应用程序错误或消息处理问题中恢复。Service Bus provides functionality to help you gracefully recover from errors in your application or difficulties processing a message. 如果接收方应用程序因某种原因无法处理消息,则它可以对 Azure::ServiceBusService 对象调用 unlock_subscription_message() 方法。If a receiver application is unable to process the message for some reason, then it can call the unlock_subscription_message() method on the Azure::ServiceBusService object. 这会导致服务总线解锁订阅中的消息并使其能够重新被同一个正在使用的应用程序或其他正在使用的应用程序接收。It causes Service Bus to unlock the message within the subscription and make it available to be received again, either by the same consuming application or by another consuming application.

另外,还存在与订阅中已锁定消息关联的超时,并且如果应用程序无法在锁定超时到期之前处理消息(例如,如果应用程序崩溃),则服务总线会自动解锁该消息并使其可再次被接收。There is also a timeout associated with a message locked within the subscription, and if the application fails to process the message before the lock timeout expires (for example, if the application crashes), then Service Bus unlocks the message automatically and make it available to be received again.

如果应用程序在处理消息之后,但在调用 delete_subscription_message() 方法之前崩溃,则在应用程序重启时会将该消息重新传送给它。In the event that the application crashes after processing the message but before the delete_subscription_message() method is called, then the message is redelivered to the application when it restarts. 此情况通常称作“至少处理一次”,即每条消息将至少被处理一次,但在某些情况下,同一消息可能会被重新传送。It is often called at least once processing; that is, each message is processed at least once but in certain situations the same message may be redelivered. 如果方案无法容忍重复处理,则应用程序开发人员应向其应用程序添加更多逻辑以处理重复消息传送。If the scenario cannot tolerate duplicate processing, then application developers should add additional logic to their application to handle duplicate message delivery. 此逻辑通常可通过使用消息的 message_id 属性实现,该属性在多次传送尝试中保持不变。This logic is often achieved using the message_id property of the message, which remains constant across delivery attempts.

删除主题和订阅Delete topics and subscriptions

除非设置 AutoDeleteOnIdle 属性,否则主题和订阅是永久性的。Topics and subscriptions are persistent unless the AutoDeleteOnIdle property is set. 可以通过 Azure 门户或以编程方式删除这些主题和订阅。They can be deleted either through the Azure portal or programmatically. 下面的示例演示如何删除名为 test-topic 的主题。The following example demonstrates how to delete the topic named test-topic.

azure_service_bus_service.delete_topic("test-topic")

删除某个主题也会删除向该主题注册的所有订阅。Deleting a topic also deletes any subscriptions that are registered with the topic. 也可以单独删除订阅。Subscriptions can also be deleted independently. 以下代码演示如何从 test-topic 主题删除名为 high-messages 的订阅:The following code demonstrates how to delete the subscription named high-messages from the test-topic topic:

azure_service_bus_service.delete_subscription("test-topic", "high-messages")

备注

可以使用服务总线资源管理器管理服务总线资源。You can manage Service Bus resources with Service Bus Explorer. 服务总线资源管理器允许用户连接到服务总线命名空间并以一种简单的方式管理消息传送实体。The Service Bus Explorer allows users to connect to a Service Bus namespace and administer messaging entities in an easy manner. 该工具提供高级功能,如导入/导出功能或用于对主题、队列、订阅、中继服务、通知中心和事件中心进行测试的功能。The tool provides advanced features like import/export functionality or the ability to test topic, queues, subscriptions, relay services, notification hubs and events hubs.

后续步骤Next steps

现在,已了解有关 Service Bus 主题的基础知识,单击下面的链接可了解更多信息。Now that you've learned the basics of Service Bus topics, follow these links to learn more.