

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# RabbitMQ 教學
<a name="rabbitmq-on-amazon-mq"></a>

以下教學說明如何在 Amazon MQ 上設定和使用 RabbitMQ。若要進一步了解如何以各種程式設計語言 (例如 Node.js、Python、.NET 等) 使用支援的用戶端程式庫，請參閱《*RabbitMQ 入門指南*》中的 [RabbitMQ 教學](https://www.rabbitmq.com/getstarted.html)。

**Topics**
+ [編輯代理程式偏好設定](amazon-mq-rabbitmq-editing-broker-preferences.md)
+ [將 Python Pika 與 Amazon MQ for RabbitMQ 搭配使用](amazon-mq-rabbitmq-pika.md)
+ [解決 RabbitMQ 暫停的佇列同步](rabbitmq-queue-sync.md)
+ [減少連線和通道的數量](reducing-connections-and-channels.md)
+ [步驟 2：將 JVM 型應用程式連接至您的代理程式](#rabbitmq-connect-jvm-application)
+ [Connect your Amazon MQ for RabbitMQ broker to Lambda](#rabbitmq-connect-to-lambda)
+ [使用 Amazon MQ for RabbitMQ 的 OAuth 2.0 身分驗證和授權](oauth-tutorial.md)
+ [使用 Amazon MQ for RabbitMQ 的 IAM 身分驗證和授權](rabbitmq-iam-tutorial.md)
+ [使用 Amazon MQ for RabbitMQ 的 LDAP 身分驗證和授權](rabbitmq-ldap-tutorial.md)
+ [使用 Amazon MQ for RabbitMQ 的 HTTP 身分驗證和授權](rabbitmq-http-tutorial.md)
+ [針對 Amazon MQ for RabbitMQ 使用 SSL 憑證身分驗證](rabbitmq-ssl-tutorial.md)
+ [將 mTLS 用於 AMQP 和管理端點](rabbitmq-mtls-tutorial.md)
+ [連接您的 JMS 應用程式](rabbitmq-tutorial-jms.md)

## 步驟 2：將 JVM 型應用程式連接至您的代理程式
<a name="rabbitmq-connect-jvm-application"></a>

 建立 RabbitMQ 代理程式後，您可以將應用程式連接到它。下列範例示範如何使用 [RabbitMQ Java 用戶端程式庫](https://www.rabbitmq.com/java-client.html)建立與代理程式的連線、建立佇列以及傳送訊息。您可使用各種語言支援的 RabbitMQ 用戶端程式庫來連線到 RabbitMQ 代理程式。如需支援的 RabbitMQ 用戶端程式庫的詳細資訊，請參閱 [RabbitMQ 用戶端程式庫和開發人員工具](https://www.rabbitmq.com/devtools.html)。

### 先決條件
<a name="rabbitmq-connect-application-prerequisites-getting-started"></a>

**注意**  
下列必要步驟僅適用於在沒有公用存取性的情況下建立的 RabbitMQ 代理程式。如果您正在建立具有公用存取性的代理程式，則可跳過這些步驟。

#### 啟用 VPC 屬性
<a name="rabbitmq-connect-application-enable-vpc-attributes-getting-started"></a>

若要確保代理程式可以在 VPC 內存取，您必須啟用 `enableDnsHostnames` 和 `enableDnsSupport` VPC 屬性。如需詳細資訊，請參閱《*Amazon VPC 使用者指南*》中的 [VPC 中的 DNS Support](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html#vpc-dns-support)。

#### 啟用傳入連線
<a name="rabbitmq-connect-application-allow-inbound-connections-getting-started"></a>

1. 登入 [Amazon MQ 主控台](https://console.aws.amazon.com/amazon-mq/)。

1. 從代理程式清單中，選擇您的代理程式名稱 (例如，**MyBroker**)。

1. 在 **{{MyBroker}}** 頁面的 **Connections (連線)** 區段中，記下代理程式 Web 主控台 URL 和線路通訊協定的位址和連接埠。

1. 在 **Details (詳細資訊)** 區段的 **Security and network (安全與網路)** 下，選擇您的安全群組名稱或 ![](http://docs.aws.amazon.com/zh_tw/amazon-mq/latest/developer-guide/images/amazon-mq-tutorials-broker-details-link.png)。

   隨即會顯示 EC2 儀表板的 **Security Groups (安全群組)** 頁面。

1. 從安全群組清單選擇您的安全群組。

1. 在頁面的最下方，選擇 **Inbound (傳入)**，然後選擇 **Edit (編輯)**。

1. 在 **Edit inbound rules (編輯傳入規則)** 對話方塊中，為您要公開存取的每個 URL 或端點新增規則 (下列範例顯示如何針對代理程式 Web 主控台執行此動作)。

   1. 選擇 **Add Rule** (新增規則)。

   1. 針對**類型**，選取**自訂 TCP**。

   1. 針對 **Source (來源)**，讓 **Custom (自訂)** 保持已選取狀態，然後輸入您希望能夠存取 Web 主控台的系統 IP 地址 (例如，`192.0.2.1`)。

   1. 選擇 **Save (儲存)**。

      您的代理程式現在已可接受傳入連線。

#### 新增 Java 相依性
<a name="rabbitmq-connect-application-java-dependencies-getting-started"></a>

如果您使用 Apache Maven 自動建置，請將以下相依性新增至 `pom.xml` 檔案。如需 Apache Maven 中專案物件模型檔案的詳細資訊，請參閱 [POM 簡介](https://maven.apache.org/guides/introduction/introduction-to-the-pom.html)。

```
<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>5.9.0</version>
</dependency>
```

如果您使用 [Gradle](https://docs.gradle.org/current/userguide/userguide.html) 自動建置，請宣告以下相依性。

```
dependencies {
    compile 'com.rabbitmq:amqp-client:5.9.0'
}
```

#### 匯入 `Connection` 和 `Channel` 類別
<a name="rabbitmq-import-connections-and-channels"></a>

 RabbitMQ Java 用戶端使用 `com.rabbitmq.client` 作為其頂層套件，而 `Connection` 和 `Channel` API 類別分別代表 AMQP 0-9-1 連線和通道。在使用前匯入 `Connection` 和 `Channel` 類別，如以下範例所示。

```
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
```

#### 建立 `ConnectionFactory` 並連接到您的代理程式
<a name="rabbitmq-create-connection-factory-and-connect"></a>

使用以下範例，透過給定的參數建立 `ConnectionFactory` 類別的執行個體。使用 `setHost` 方法來設定您稍早記下的代理程式端點。對於 `AMQPS` 線路層級連線, 使用連接埠 `5671`。

```
ConnectionFactory factory = new ConnectionFactory();

factory.setUsername(username);
factory.setPassword(password);

//Replace the URL with your information
factory.setHost("{{b-c8352341-ec91-4a78-ad9c-a43f23d325bb.mq.us-west-2.amazonaws.com}}");
factory.setPort(5671);

// Allows client to establish a connection over TLS
factory.useSslProtocol();

// Create a connection
Connection conn = factory.newConnection();

// Create a channel
Channel channel = conn.createChannel();
```

#### 將訊息發佈至交換
<a name="rabbitmq-publish-message"></a>

 您可使用 `Channel.basicPublish` 將訊息發佈至交換。下列範例使用 AMQP `Builder` 類別來建置具有內容類型 `plain/text` 的訊息屬性對象。

```
byte[] messageBodyBytes = "Hello, world!".getBytes();
channel.basicPublish(exchangeName, routingKey,
             new AMQP.BasicProperties.Builder()
               .contentType("text/plain")
               .userId("userId")
               .build(),
               messageBodyBytes);
```

**注意**  
請注意，`BasicProperties` 是自動產生的持有人類別 `AMQP` 的內部類別。

#### 訂閱佇列並接收訊息
<a name="rabbitmq-subscribe-receive-message"></a>

您可以使用 `Consumer` 界面，藉由訂閱佇列來接收訊息。訂閱後，訊息就會在送達時自動傳送。

實作 `Consumer` 的最簡單方法是使用子類別 `DefaultConsumer`。`DefaultConsumer` 物件可以作為 `basicConsume` 呼叫的一部分來傳遞，以設定訂閱，如以下範例所示。

```
boolean autoAck = false;
channel.basicConsume(queueName, autoAck, "myConsumerTag",
     new DefaultConsumer(channel) {
         @Override
         public void handleDelivery(String consumerTag,
                                    Envelope envelope,
                                    AMQP.BasicProperties properties,
                                    byte[] body)
             throws IOException
         {
             String routingKey = envelope.getRoutingKey();
             String contentType = properties.getContentType();
             long deliveryTag = envelope.getDeliveryTag();
             // (process the message components here ...)
             channel.basicAck(deliveryTag, false);
         }
     });
```

**注意**  
因為我們指定了 `autoAck = false`，則必須認可傳送至 `Consumer` 的訊息，最方便在 `handleDelivery` 方法中進行，如範例所示。

#### 關閉您的連線並中斷代理程式的連線
<a name="rabbitmq-disconnect"></a>

為了中斷與 RabbitMQ 代理程式的連線，請關閉通道和連線，如下面所示。

```
channel.close();
conn.close();
```

**注意**  
如需使用 RabbitMQ Java 用戶端程式庫的詳細資訊，請參閱 [RabbitMQ Java 用戶端 API 指南](https://www.rabbitmq.com/api-guide.html)。

## 步驟 3：（選用） 連接至 AWS Lambda 函數
<a name="rabbitmq-connect-to-lambda"></a>

 AWS Lambda 可以連線至您的 Amazon MQ 代理程式並使用訊息。當您將代理程式連接到 Lambda 時，您可以建立[事件來源映射](https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventsourcemapping.html)，其會讀取佇列中的訊息並[同步](https://docs.aws.amazon.com/lambda/latest/dg/invocation-sync.html)叫用函數。您建立的事件來源映射會分批讀取來自代理程式的訊息，並以 JSON 物件的形式將它們轉換為 Lambda 承載。

**將代理程式連接到 Lambda 函數**

1. 將下列 IAM 角色許可新增到 Lambda 函數[執行角色](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)。
   + [mq:DescribeBroker](https://docs.aws.amazon.com/amazon-mq/latest/api-reference/brokers-broker-id.html#brokers-broker-id-http-methods)
   + [ec2:CreateNetworkInterface](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateNetworkInterface.html)
   + [ec2:DeleteNetworkInterface](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteNetworkInterface.html)
   + [ec2:DescribeNetworkInterfaces](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeNetworkInterfaces.html)
   + [ec2:DescribeSecurityGroups](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSecurityGroups.html)
   + [ec2:DescribeSubnets](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSubnets.html)
   + [ec2:DescribeVpcs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeVpcs.html)
   + [logs:CreateLogGroup](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogGroup.html)
   + [logs:CreateLogStream](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogStream.html)
   + [日誌：PutLogEvents](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html)
   + [secretsmanager:GetSecretValue](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html)
**注意**  
若沒有必要的 IAM 許可，您的函數將無法成功從 Amazon MQ 資源讀取記錄。

1.  (選用) 如果您已建立沒有公開可存取性的代理程式，您必須執行下列其中一項作業，以允許 Lambda 連線到代理程式：
   +  為每個公用子網路設定一個 NAT 閘道。如需詳細資訊，請參閱 *AWS Lambda 開發人員指南*中的 [VPC 連線函數的網際網路和服務存取](https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html#vpc-internet)。
   + 使用 VPC 端點建立 Amazon Virtual Private Cloud (Amazon VPC) 與 Lambda 之間的連線。您的 Amazon VPC 也必須連線到 AWS Security Token Service (AWS STS) 和 Secrets Manager 端點。如需詳細資訊，請參閱 *AWS Lambda 開發人員指南*中的[設定 Lambda 的介面 VPC 端點](https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc-endpoints.html)。

1.  使用 AWS 管理主控台，針對 Lambda 函數[將您的代理程式設定為事件來源](https://docs.aws.amazon.com/lambda/latest/dg/with-mq.html#services-mq-eventsourcemapping)。您也可以使用 [https://docs.aws.amazon.com/cli/latest/reference/lambda/create-event-source-mapping.html](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-event-source-mapping.html) AWS Command Line Interface 命令。

1.  為 Lambda 函數編寫一些程式碼，以處理從代理程式取用的訊息。事件來源映射擷取的 Lambda 承載取決於代理程式的引擎類型。以下是 Amazon MQ for RabbitMQ 佇列的 Lambda 承載範例。
**注意**  
 在範例中，`test` 是佇列的名稱，`/` 是預設虛擬主機的名稱。接收訊息時，事件來源會在 `test::/` 列出訊息。

   ```
   {
     "eventSource": "aws:rmq",
     "eventSourceArn": "arn:aws:mq:us-west-2:112556298976:broker:test:b-9bcfa592-423a-4942-879d-eb284b418fc8",
     "rmqMessagesByQueue": {
       "test::/": [
         {
           "basicProperties": {
             "contentType": "text/plain",
             "contentEncoding": null,
             "headers": {
               "header1": {
                 "bytes": [
                   118,
                   97,
                   108,
                   117,
                   101,
                   49
                 ]
               },
               "header2": {
                 "bytes": [
                   118,
                   97,
                   108,
                   117,
                   101,
                   50
                 ]
               },
               "numberInHeader": 10
             }
             "deliveryMode": 1,
             "priority": 34,
             "correlationId": null,
             "replyTo": null,
             "expiration": "60000",
             "messageId": null,
             "timestamp": "Jan 1, 1970, 12:33:41 AM",
             "type": null,
             "userId": "AIDACKCEVSQ6C2EXAMPLE",
             "appId": null,
             "clusterId": null,
             "bodySize": 80
           },
           "redelivered": false,
           "data": "eyJ0aW1lb3V0IjowLCJkYXRhIjoiQ1pybWYwR3c4T3Y0YnFMUXhENEUifQ=="
         }
       ]
     }
   }
   ```

如需將 Amazon MQ 連線至 Lambda、Lambda 支援 Amazon MQ 事件來源的選項，以及事件來源映射錯誤的詳細資訊，請參閱《 *AWS Lambda 開發人員指南*》中的[搭配使用 Lambda 與 Amazon MQ](https://docs.aws.amazon.com/lambda/latest/dg/with-mq.html)。