如何通过 Ruby 使用服务总线队列How to use Service Bus queues with Ruby

本教程介绍如何创建 Ruby 应用程序,以便向服务总线队列发送消息以及从中接收消息。In this tutorial, you learn how to create Ruby applications to send messages to and receive messages from a Service Bus queue. 相关示例用 Ruby 编写且使用 Azure gem。The samples are written in Ruby and use the Azure gem.

先决条件Prerequisites

  1. Azure 订阅。An Azure subscription. 若要完成本教程,需要一个 Azure 帐户。To complete this tutorial, you need an Azure account. 可以激活 MSDN 订阅者权益注册试用帐户You can activate your MSDN subscriber benefits or sign up for a trial account.
  2. 按照使用 Azure 门户创建服务总线队列一文中的步骤操作。Follow steps in the Use Azure portal to create a Service Bus queue article.
    1. 阅读服务总线队列的快速概述Read the quick overview of Service Bus queues.

    2. 创建一个服务总线命名空间Create a Service Bus namespace.

    3. 获取连接字符串Get the connection string.

      Note

      在本教程中,需使用 Ruby 在服务总线命名空间中创建一个队列You will create a queue in the Service Bus namespace by using Ruby in this tutorial.

创建 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".

如何创建队列How to create a queue

可以通过 Azure::ServiceBusService 对象处理队列。The Azure::ServiceBusService object enables you to work with queues. 若要创建队列,请使用 create_queue() 方法。To create a queue, use the create_queue() method. 以下示例创建一个队列或输出任何错误。The following example creates a queue or prints out any errors.

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

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

queue = Azure::ServiceBus::Queue.new("test-queue")
queue.max_size_in_megabytes = 5120
queue.default_message_time_to_live = "PT1M"

queue = azure_service_bus_service.create_queue(queue)

如何向队列发送消息How to send messages to a queue

要向服务总线队列发送消息,应用程序需对 Azure::ServiceBusService 对象调用 send_queue_message() 方法。To send a message to a Service Bus queue, your application calls the send_queue_message() method on the Azure::ServiceBusService object. 发往服务总线队列的消息以及从服务总线队列接收的消息是 Azure::ServiceBus::BrokeredMessage 对象,它们具有一组标准属性(如 labeltime_to_live)、一个用于保存自定义的应用程序特定属性的字典和大量任意应用程序数据。Messages sent to (and received from) Service Bus queues are Azure::ServiceBus::BrokeredMessage objects, and 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 arbitrary application data. 应用程序可以通过将字符串值作为消息传送设置消息正文,任何必需的标准属性会用默认值填充。An application can set the body of the message by passing a string value as the message and any required standard properties are populated with default values.

以下示例演示如何使用 send_queue_message() 向名为 test-queue 的队列发送一条测试消息:The following example demonstrates how to send a test message to the queue named test-queue using send_queue_message():

message = Azure::ServiceBus::BrokeredMessage.new("test queue message")
message.correlation_id = "test-correlation-id"
azure_service_bus_service.send_queue_message("test-queue", message)

服务总线队列在标准层中支持的最大消息大小为 256 KB,在高级层中则为 1 MB。Service Bus queues 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 queue but there is a cap on the total size of the messages held by a queue. 此队列大小在创建时定义,上限为 5 GB。This queue size is defined at creation time, with an upper limit of 5 GB.

如何从队列接收消息How to receive messages from a queue

对 Azure::ServiceBusService 对象使用 receive_queue_message() 方法可从队列接收消息。Messages are received from a queue using the receive_queue_message() method on the Azure::ServiceBusService object. 默认情况下,消息在被读取的同时会被锁定,从而无法从队列中删除。By default, messages are read and locked without being deleted from the queue. 但是,可以通过将 :peek_lock 选项设置为“false”,在读取消息时将其从队列中删除。However, you can delete messages from the queue as they are read 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_queue_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_queue_message() method and providing the message to be deleted as a parameter. delete_queue_message() 方法会将消息标记为已使用,并从队列中将其删除。The delete_queue_message() method will mark the message as being consumed and remove it from the queue.

如果 :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 in the event of a failure. 为了理解这一点,可以考虑这样一种情形:使用方发出接收请求,但在处理该请求前发生了崩溃。To understand this, 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, when the application restarts and begins consuming messages again, it will have missed the message that was consumed prior to the crash.

以下示例演示如何使用 receive_queue_message() 接收和处理消息。The following example demonstrates how to receive and process messages using receive_queue_message(). 该示例先通过将 :peek_lock 设置为“false”接收并删除一条消息,然后再接收另一条消息,最后使用 delete_queue_message() 删除该消息:The example first receives and deletes a message by using :peek_lock set to false, then it receives another message and then deletes the message using delete_queue_message():

message = azure_service_bus_service.receive_queue_message("test-queue",
  { :peek_lock => false })
message = azure_service_bus_service.receive_queue_message("test-queue")
azure_service_bus_service.delete_queue_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_queue_message() 方法。If a receiver application is unable to process the message for some reason, then it can call the unlock_queue_message() method on the Azure::ServiceBusService object. 此调用会导致服务总线解锁队列中的消息并使其能够重新被同一个正在使用的应用程序或其他正在使用的应用程序接收。This call causes Service Bus to unlock the message within the queue 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 queue, 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 makes it available to be received again.

如果应用程序在处理消息之后,但在调用 delete_queue_message() 方法之前崩溃,则在应用程序重启时会将该消息重新传送给它。In the event that the application crashes after processing the message but before the delete_queue_message() method is called, then the message is redelivered to the application when it restarts. 此过程通常称作“至少处理一次”,即每条消息将至少被处理一次,但在某些情况下,同一消息可能会被重新传送。This process 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 is often achieved using the message_id property of the message, which remains constant across delivery attempts.

后续步骤Next Steps

现在,已了解有关服务总线队列的基础知识,请访问下面的链接以获取详细信息。Now that you've learned the basics of Service Bus queues, follow these links to learn more.

有关本文中讨论的 Azure 服务总线队列与如何通过 Ruby 使用队列存储一文中讨论的 Azure 队列的比较,请参阅 Azure 队列和 Azure 服务总线队列 - 比较与对照For a comparison between the Azure Service Bus Queues discussed in this article and Azure Queues discussed in the How to use Queue storage from Ruby article, see Azure Queues and Azure Service Bus Queues - Compared and Contrasted