

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

# 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)

# 編輯代理程式偏好設定
<a name="amazon-mq-rabbitmq-editing-broker-preferences"></a>

您可以編輯代理程式偏好設定，例如使用 啟用或停用 CloudWatch 日誌 AWS 管理主控台。

## 編輯 RabbitMQ 代理程式選項
<a name="rabbitmq-edit-current-configuration-console"></a>

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

1. 從代理程式清單，選取您的代理程式 (例如 **MyBroker**)，然後選擇 **Edit (編輯)**。

1. 在 **Edit *MyBroker* (編輯 MyBroker)** 頁面上，於 **Specifications (規格)** 區段中，選取 **Broker engine version (代理程式引擎版本)** 或**Broker Instance type (代理程式執行個體類型)**。

   

1. 在 **CloudWatch Logs** 區段中，按一下切換按鈕以啟用或停用一般日誌。不需要執行其他步驟。
**注意**  
對於 RabbitMQ 代理程式，Amazon MQ 會自動使用服務連結的角色 (SLR) 將一般日誌發佈到 CloudWatch。如需詳細資訊，請參閱 [使用 Amazon MQ 的服務連結角色](using-service-linked-roles.md)。
Amazon MQ 不支援 RabbitMQ 代理程式的稽核記錄。

1. 在 **Maintenance (維護)** 區段中，設定代理程式的維護排程：

   若要在 AWS 發行代理程式時將代理程式升級至新版本，請選擇**啟用自動次要版本升級**。自動升級會發生於由星期幾、一天中的時間 (24 小時制) 和時區 (預設為 UTC) 所定義的*維護時段*期間。

1. 選擇 **Schedule Modifications (排程修改)**。
**注意**  
如果您只選擇 **Enable automatic minor version upgrades (啟用自動次要版本升級)**，按鈕會變更為 **Save (儲存)**，因為無需重新啟動代理程式。

   會在指定時間將您的偏好設定套用至代理程式。

# 將 Python Pika 與 Amazon MQ for RabbitMQ 搭配使用
<a name="amazon-mq-rabbitmq-pika"></a>

 以下教學課程說明如何設定 [Python Pika](https://github.com/pika/pika) 用戶端，同時設定 TLS 以便連線到 Amazon MQ for RabbitMQ 代理程式。Pika 是 RabbitMQ 之 AMQP 0-9-1 協定的 Python 實作。本教學課程會引導您完成安裝 Pika、宣告佇列、設定發佈者將訊息傳送到代理程式的預設交換，以及設定取用者從佇列接收訊息。

**Topics**
+ [先決條件](#amazon-mq-rabbitmq-pika-prerequisites)
+ [許可](#amazon-mq-rabbitmq-pika-permissions)
+ [步驟一：建立基本 Python Pika 用戶端](#amazon-mq-rabbitmq-pika-basic-client)
+ [步驟二：建立發行者並傳送訊息](#amazon-mq-rabbitmq-pika-publisher-basic-publish)
+ [步驟三：建立消費者並接收訊息](#amazon-mq-rabbitmq-pika-consumer-basic-get)
+ [步驟四：(選用) 設定事件迴圈並取用訊息](#amazon-mq-rabbitmq-pika-consumer-basic-consume)
+ [後續步驟？](#amazon-mq-rabbitmq-pika-whats-next)

## 先決條件
<a name="amazon-mq-rabbitmq-pika-prerequisites"></a>

 若要完成本教學課程的步驟，您需要以下先決條件：
+ 一個 Amazon MQ for RabbitMQ 代理程式。如需詳細資訊，請參閱[建立 Amazon MQ for RabbitMQ 代理程式](getting-started-rabbitmq.md#create-rabbitmq-broker)。
+ 您的作業系統應安裝 [Python 3](https://www.python.org/downloads/)。
+ 使用 Python `pip` 安裝 [Pika](https://pika.readthedocs.io/en/stable/)。若要安裝 Pika，請開啟新的終端機視窗並執行以下命令。

  ```
  $ python3 -m pip install pika
  ```

## 許可
<a name="amazon-mq-rabbitmq-pika-permissions"></a>

在本教學課程中，您至少需要一個 Amazon MQ for RabbitMQ 代理程式使用者，其具有寫入和讀取虛擬主機的許可。下表將必要的最低許可描述為規則表達式 (regexp) 模式。


| Tags (標籤) | 設定 regexp | 寫入 regexp | 讀取 regexp | 
| --- | --- | --- | --- | 
| none |  | .\$1 | .\$1 | 

 列出的使用者許可僅為使用者提供讀取和寫入許可，而不會授予對管理外掛程式的存取權，以便在代理程式上執行管理操作。您可以提供限制使用者存取指定佇列的規則運算式模式，進一步限制許可。例如，如果您將讀取規則表達式模式變更為 `^[hello world].*`，則使用者將僅擁有從以 `hello world` 開頭之佇列中進行讀取的許可。

如需建立 RabbitMQ 使用者及管理使用者標籤和許可的詳細資訊，請參閱 [Amazon MQ for RabbitMQ 代理程式使用者](rabbitmq-simple-auth-broker-users.md#rabbitmq-basic-elements-user)。

## 步驟一：建立基本 Python Pika 用戶端
<a name="amazon-mq-rabbitmq-pika-basic-client"></a>

若要建立 Python Pika 用戶端基本類別，以定義建構函數並在與 Amazon MQ for RabbitMQ 代理程式互動時提供 TLS 組態所需的 SSL 內容，請執行下列動作。

1.  開啟新終端機視窗，為您的專案建立新目錄，並導覽至該目錄。

   ```
   $ mkdir pika-tutorial
   $ cd pika-tutorial
   ```

1.  建立新檔案 `basicClient.py`，其包含下列 Python 程式碼。

   ```
   import ssl
   import pika
   
   class BasicPikaClient:
   
       def __init__(self, rabbitmq_broker_id, rabbitmq_user, rabbitmq_password, region):
   
           # SSL Context for TLS configuration of Amazon MQ for RabbitMQ
           ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
           ssl_context.set_ciphers('ECDHE+AESGCM:!ECDSA')
   
           url = f"amqps://{rabbitmq_user}:{rabbitmq_password}@{rabbitmq_broker_id}.mq.{region}.amazonaws.com:5671"
           parameters = pika.URLParameters(url)
           parameters.ssl_options = pika.SSLOptions(context=ssl_context)
   
           self.connection = pika.BlockingConnection(parameters)
           self.channel = self.connection.channel()
   ```

 您現在可以為繼承自 `BasicPikaClient` 的發行者和取用者定義其他類別。

## 步驟二：建立發行者並傳送訊息
<a name="amazon-mq-rabbitmq-pika-publisher-basic-publish"></a>

 若要建立宣告佇列並傳送單一訊息的發行者，請執行下列動作。

1.  複製下列程式碼範例的內容，並在上一個步驟建立的相同目錄中本機儲存為 `publisher.py`。

   ```
   from basicClient import BasicPikaClient
   
   class BasicMessageSender(BasicPikaClient):
   
       def declare_queue(self, queue_name):
           print(f"Trying to declare queue({queue_name})...")
           self.channel.queue_declare(queue=queue_name)
   
       def send_message(self, exchange, routing_key, body):
           channel = self.connection.channel()
           channel.basic_publish(exchange=exchange,
                                 routing_key=routing_key,
                                 body=body)
           print(f"Sent message. Exchange: {exchange}, Routing Key: {routing_key}, Body: {body}")
   
       def close(self):
           self.channel.close()
           self.connection.close()
   
   if __name__ == "__main__":
   
       # Initialize Basic Message Sender which creates a connection
       # and channel for sending messages.
       basic_message_sender = BasicMessageSender(
           "<broker-id>",
           "<username>",
           "<password>",
           "<region>"
       )
   
       # Declare a queue
       basic_message_sender.declare_queue("hello world queue")
   
       # Send a message to the queue.
       basic_message_sender.send_message(exchange="", routing_key="hello world queue", body=b'Hello World!')
   
       # Close connections.
       basic_message_sender.close()
   ```

    `BasicMessageSender` 類別繼承自 `BasicPikaClient` 並實作其他方法來宣告佇列、向佇列傳送訊息以及關閉連線。程式碼範例會將訊息路由傳送至預設交換，且路由金鑰等於佇列名稱。

1.  在 `if __name__ == "__main__":` 下方，請用下列資訊取代傳遞給 `BasicMessageSender` 建構函數陳述式的參數。
   +  **`<broker-id>`** – Amazon MQ 針對代理程式產生的唯一 ID。您可以從代理程式 ARN 解析 ID。例如，假定是以下 ARN `arn:aws:mq:us-east-2:123456789012:broker:MyBroker:b-1234a5b6-78cd-901e-2fgh-3i45j6k178l9`，代理程式 ID 會是 `b-1234a5b6-78cd-901e-2fgh-3i45j6k178l9`。
   +  **`<username>`** – 具有足夠許可可將訊息寫入代理程式的代理程式使用者的使用者名稱。
   +  **`<password>`** – 具有足夠許可可將訊息寫入代理程式的代理程式使用者的密碼。
   +  **`<region>`** – 您在其中建立 Amazon MQ for RabbitMQ 代理程式 AWS 的區域。例如 `us-west-2`。

1.  在您建立 `publisher.py` 的相同目錄中執行下列命令。

   ```
   $ python3 publisher.py
   ```

   如果程式碼執行成功，則您將在終端機視窗中看到下列輸出。

   ```
   Trying to declare queue(hello world queue)...
   Sent message. Exchange: , Routing Key: hello world queue, Body: b'Hello World!'
   ```

## 步驟三：建立消費者並接收訊息
<a name="amazon-mq-rabbitmq-pika-consumer-basic-get"></a>

 若要建立從佇列接收單一訊息的取用者，請執行下列動作。

1.  複製下列程式碼範例的內容，並在相同目錄中本機儲存為 `consumer.py`。

   ```
   from basicClient import BasicPikaClient
   
   class BasicMessageReceiver(BasicPikaClient):
   
       def get_message(self, queue):
           method_frame, header_frame, body = self.channel.basic_get(queue)
           if method_frame:
               print(method_frame, header_frame, body)
               self.channel.basic_ack(method_frame.delivery_tag)
               return method_frame, header_frame, body
           else:
               print('No message returned')
   
       def close(self):
           self.channel.close()
           self.connection.close()
   
   
   if __name__ == "__main__":
   
       # Create Basic Message Receiver which creates a connection
       # and channel for consuming messages.
       basic_message_receiver = BasicMessageReceiver(
           "<broker-id>",
           "<username>",
           "<password>",
           "<region>"
       )
   
       # Consume the message that was sent.
       basic_message_receiver.get_message("hello world queue")
   
       # Close connections.
       basic_message_receiver.close()
   ```

    與您在上一個步驟中建立的發佈者類似， `BasicMessageReceiver`繼承`BasicPikaClient`並實作接收單一訊息和關閉連線的其他方法。

1.  在 `if __name__ == "__main__":` 下方，請用您的資訊取代傳遞給 `BasicMessageReceiver` 建構函數的參數。

1.  在您的專案目錄中，執行下列命令。

   ```
   $ python3 consumer.py
   ```

   如果程式碼成功執行，則您會看到訊息內文以及包括路由金鑰在內的標頭，它們會顯示在終端機視窗中。

   ```
   <Basic.GetOk(['delivery_tag=1', 'exchange=', 'message_count=0', 'redelivered=False', 'routing_key=hello world queue'])> <BasicProperties> b'Hello World!'
   ```

## 步驟四：(選用) 設定事件迴圈並取用訊息
<a name="amazon-mq-rabbitmq-pika-consumer-basic-consume"></a>

 若要取用佇列中的多條訊息，請使用 Pika 的 [https://pika.readthedocs.io/en/stable/modules/channel.html#pika.channel.Channel.basic_consume](https://pika.readthedocs.io/en/stable/modules/channel.html#pika.channel.Channel.basic_consume) 方法和回呼函數，如下所示 

1.  在 `consumer.py` 中，請將下列方法定義新增至 `BasicMessageReceiver` 類別。

   ```
   def consume_messages(self, queue):
       def callback(ch, method, properties, body):
           print(" [x] Received %r" % body)
   
       self.channel.basic_consume(queue=queue, on_message_callback=callback, auto_ack=True)
   
       print(' [*] Waiting for messages. To exit press CTRL+C')
       self.channel.start_consuming()
   ```

1.  在 `consumer.py` 中，在 `if __name__ == "__main__":` 下方，叫用您在上一步驟中定義的 `consume_messages` 方法。

   ```
   if __name__ == "__main__":
   
       # Create Basic Message Receiver which creates a connection and channel for consuming messages.
       basic_message_receiver = BasicMessageReceiver(
           "<broker-id>",
           "<username>",
           "<password>",
           "<region>"
       )
   
       # Consume the message that was sent.
       # basic_message_receiver.get_message("hello world queue")
   
       # Consume multiple messages in an event loop.
       basic_message_receiver.consume_messages("hello world queue")
   
       # Close connections.
       basic_message_receiver.close()
   ```

1.  再次執行 `consumer.py`，如果成功，佇列訊息會顯示在終端機視窗中。

   ```
   [*] Waiting for messages. To exit press CTRL+C
   [x] Received b'Hello World!'
   [x] Received b'Hello World!'
   ...
   ```

## 後續步驟？
<a name="amazon-mq-rabbitmq-pika-whats-next"></a>
+  如需其他支援 RabbitMQ 用戶端程式庫的詳細資訊，請參閱 RabbitMQ 網站上的 [RabbitMQ 用戶端文件](https://www.rabbitmq.com/clients.html)。

# 解決 RabbitMQ 暫停的佇列同步
<a name="rabbitmq-queue-sync"></a>

在 Amazon MQ for RabbitMQ [叢集部署](rabbitmq-broker-architecture.md#rabbitmq-broker-architecture-cluster)中，發佈至每個佇列的訊息會跨三個代理程式節點進行複寫。此複寫 (稱為*鏡像*) 為 RabbitMQ 代理程式提供高可用性 (HA)。叢集部署中的佇列由一個節點上的*主要*複本和一或多個*鏡像*所組成。每個套用至鏡像佇列的作業 (包括排入佇列的訊息) 都會先套用至主要佇列，然後跨鏡像進行複寫。

例如，考量跨三個節點複寫的鏡像佇列：主要節點 (`main`) 和兩個鏡像 (`mirror-1` 和 `mirror-2`)。如果此鏡像佇列中的所有訊息都會成功傳播到所有鏡像，則會同步處理此佇列。如果節點 (`mirror-1`) 在一段時間內變得無法使用，佇列仍然可以運作，而且可以繼續將訊息排入佇列。不過，對於要同步處理的佇列，則在 `mirror-1` 無法使用時發佈至 `main` 的訊息必須複寫到 `mirror-1`。

如需鏡像的詳細資訊，請參閱 RabbitMQ 網站上的[傳統鏡像佇列](https://www.rabbitmq.com/ha.html)。

**維護與佇列同步**

在[維護時段](amazon-mq-rabbitmq-editing-broker-preferences.md#rabbitmq-edit-current-configuration-console)期間，Amazon MQ 會一次執行一個節點的所有維護工作，以確保代理程式維持運作狀態。因此，佇列可能需要在每個節點繼續操作時進行同步處理。在同步期間，需要複寫到鏡像的訊息會從對應的 Amazon Elastic Block Store (Amazon EBS) 磁碟區載入記憶體中，以便分批處理。分批處理訊息可讓佇列更快速地同步處理。

如果佇列保持簡短且訊息很小，則佇列會成功同步處理並繼續如預期般操作。不過，如果批次中的資料量接近節點的記憶體限制，節點就會引發高記憶體警示，暫停佇列同步。您可比較 `RabbitMemUsed` 與 `RabbitMqMemLimit` [CloudWatch 中的代理程式節點指標](amazon-mq-accessing-metrics.md)，以確認記憶體使用量。直到取用或刪除訊息或減少批次中的訊息數目，才能完成同步處理。

**注意**  
減少佇列同步處理批次大小可能會導致較高的複寫交易數目。

若要解決暫停的佇列同步處理，請遵循本教學中的步驟，其中示範如何套用 `ha-sync-batch-size` 政策並重新啟動佇列同步處理。

**Topics**
+ [先決條件](#rabbitmq-queue-sync-prerequisites)
+ [步驟 1：套用 `ha-sync-batch-size` 政策](#rabbitmq-queue-sync-step-1)
+ [步驟 2：重新啟動佇列同步](#rabbitmq-queue-sync-step-2)
+ [後續步驟](#rabbitmq-queue-sync-next-steps)
+ [相關資源](#rabbitmq-queue-sync-related-resources)

## 先決條件
<a name="rabbitmq-queue-sync-prerequisites"></a>

在本教學中，您必須有具備管理員許可的 Amazon MQ for RabbitMQ 代理程式使用者。您可以使用第一次建立代理程式時建立的管理員使用者，或您之後可能建立的其他使用者。下表提供必要的管理員使用者標籤和許可作為規則表達式 (regexp) 模式。


| Tags (標籤) | 讀取 regexp | 設定 regexp | 寫入 regexp | 
| --- | --- | --- | --- | 
| administrator | .\$1 | .\$1 | .\$1 | 

如需建立 RabbitMQ 使用者及管理使用者標籤和許可的詳細資訊，請參閱 [Amazon MQ for RabbitMQ 代理程式使用者](rabbitmq-simple-auth-broker-users.md#rabbitmq-basic-elements-user)。

## 步驟 1：套用 `ha-sync-batch-size` 政策
<a name="rabbitmq-queue-sync-step-1"></a>

下列程序示範如何新增適用於代理程式上建立之所有佇列的政策。您可以使用 RabbitMQ Web 主控台或 RabbitMQ 管理 API。如需詳細資訊，請參閱 RabbitMQ 網站上的[管理外掛程式](https://www.rabbitmq.com/management.html)。

**使用 RabbitMQ Web 主控台套用 `ha-sync-batch-size` 政策**

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

1. 在左側導覽窗格中選擇 **Brokers (代理程式)**。

1. 從代理程式清單中，選擇您要套用新政策的代理程式名稱。

1. 在代理程式頁面的 **Connections (連線)** 區段中，選擇 **RabbitMQ web console (RabbitMQ Web 主控台)** URL。RabbitMQ Web 主控台會在新的瀏覽器索引標籤或視窗中開啟。

1. 使用您的代理程式管理員登入憑證登入 RabbitMQ Web 主控台。

1. 在 RabbitMQ Web 主控台的頁面頂端，選擇 **Admin (管理員)**。

1. 在 **Admin (管理員)** 頁面的右側導覽窗格中，選擇 **Policies (政策)**。

1. 在 **Policies (政策)** 頁面上，您可看到代理程式目前的 **User policies (使用者政策)** 清單。在 **User policies (使用者政策)** 下方，展開 **Add / update a policy (新增/更新政策)**。
**注意**  
根據預設，使用名為 `ha-all-AWS-OWNED-DO-NOT-DELETE` 的初始代理程式政策建立 Amazon MQ for RabbitMQ 叢集。Amazon MQ 會管理此政策，以確保代理程式上的每個佇列都會複寫到所有三個節點，並自動同步佇列。

1. 若要建立新的代理程式政策，請在 **Add / update a policy (新增/更新政策)** 之下，執行下列操作：

   1. 針對 **Name (名稱)**，輸入您的政策名稱，例如 **batch-size-policy**。

   1. 針對 **Pattern (模式)**，輸入 regexp 模式 **.\$1**，以便政策符合代理程式上的所有佇列。

   1. 針對 **Apply to (套用至)**，從下拉式清單中選擇 **Exchanges and queues (交換和佇列\$1**。

   1. 針對 **Priority (優先順序)**，輸入大於套用至虛擬主機的所有其他策略的整數。您可以在任何指定的時間將一組政策定義套用至 RabbitMQ 佇列和交換。RabbitMQ 會選擇具有最高優先順序值的相符政策。如需政策優先順序及如何合併政策的詳細資訊，請參閱 RabbitMQ 伺服器文件中的[政策](https://www.rabbitmq.com/parameters.html#policies)。

   1. 針對 **Definition (定義)**，新增下列鍵值組：
      + **ha-sync-batch-size**=*100*。從下拉式清單中選擇 **Number (數字)**。
**注意**  
您可能需要根據佇列中未同步的訊息數目和大小，調整和校準 `ha-sync-batch-size` 的值。
      + **ha-mode**=**all**。從下拉式清單中選擇 **String (字串)**。
**重要**  
所有 HA 相關政策都需要 `ha-mode` 定義。省略它會導致驗證失敗。
      + **ha-sync-mode**=**automatic**。從下拉式清單中選擇 **String (字串)**。
**注意**  
所有自訂政策都需要 `ha-sync-mode` 定義。若已省略，Amazon MQ 會自動附加定義。

   1. 選擇 **Add / update policy (新增 / 更新政策)**。

1. 確認新政策出現在 **User policies (使用者政策)** 清單中。

**使用 RabbitMQ 管理 API 套用 `ha-sync-batch-size` 政策**

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

1. 在左側導覽窗格中選擇 **Brokers (代理程式)**。

1. 從代理程式清單中，選擇您要套用新政策的代理程式名稱。

1. 在代理程式頁面的 **Connections (連線)** 區段中，記下 **RabbitMQ web console (RabbitMQ Web 主控台)** URL。這是您在 HTTP 請求中使用的代理程式端點。

1. 開啟新的終端機或您所選的命令列視窗。

1. 若要建立新的代理程式政策，請輸入下列 `curl` 命令。此命令會假設預設 `/` 虛擬主機上的佇列，其編碼為 `%2F`。
**注意**  
將*使用者名稱*和*密碼*取代為您的代理管理員登入憑證。您可能需要根據佇列中未同步的訊息數目和大小，調整和校準 `ha-sync-batch-size` 的值 (*100*)。以您先前記下的 URL 取代代理程式端點。

   ```
   curl -i -u username:password -H "content-type:application/json" -XPUT \
   -d '{"pattern":".*", "priority":1, "definition":{"ha-sync-batch-size":100, "ha-mode":"all", "ha-sync-mode":"automatic"}}' \
   https://b-589c045f-f8ln-4ab0-a89c-co62e1c32ef8.mq.us-west-2.amazonaws.com/api/policies/%2F/batch-size-policy
   ```

1. 若要確認新政策已新增至代理程式的使用者政策，請輸入下列 `curl` 命令以列出所有代理程式政策。

   ```
   curl -i -u username:password https://b-589c045f-f8ln-4ab0-a89c-co62e1c32ef8.mq.us-west-2.amazonaws.com/api/policies
   ```

## 步驟 2：重新啟動佇列同步
<a name="rabbitmq-queue-sync-step-2"></a>

在將新的 `ha-sync-batch-size` 政策套用至代理程式之後，請重新啟動佇列同步處理。

**使用 RabbitMQ Web 主控台重新啟動佇列同步**
**注意**  
若要開啟 RabbitMQ Web 主控台，請參閱本教學的步驟 1 中的先前指示。

1. 在 RabbitMQ Web 主控台的頁面頂端，選擇 **Queues (佇列)**。

1. 在 **Queues (佇列)** 頁面的 **All queues (所有佇列)** 之下，找出您已暫停的佇列。在**政策**列中，您的佇列應列出您建立的新政策名稱 （例如 `batch-size-policy`)。

1. 若要以較低的批次大小重新啟動同步程序，請先取消佇列同步。然後重新啟動佇列同步。

**注意**  
如果同步處理暫停且無法順利完成，請嘗試縮減 `ha-sync-batch-size` 值，然後再次重新啟動佇列同步處理。

## 後續步驟
<a name="rabbitmq-queue-sync-next-steps"></a>
+ 佇列成功同步後，您可檢視 Amazon CloudWatch 指標 `RabbitMQMemUsed` 以監控 RabbitMQ 節點使用的記憶體數量。您也可以檢視 `RabbitMQMemLimit` 指標來監控節點的記憶體限制。如需詳細資訊，請參閱 [存取 Amazon MQ 的 CloudWatch 指標](amazon-mq-accessing-metrics.md) 及 [Amazon MQ for RabbitMQ 代理程式可用的 CloudWatch 指標](rabbitmq-logging-monitoring.md)。
+ 若要避免暫停的佇列同步處理，建議將佇列保持簡短並處理訊息。對於訊息大小較大的工作負載，我們也建議將代理程式執行個體類型升級為具有更多記憶體的較大執行個體大小。如需代理程式執行個體類型和編輯代理程式偏好設定的詳細資訊，請參閱 [編輯代理程式偏好設定](amazon-mq-rabbitmq-editing-broker-preferences.md)。
+  當您建立新的 Amazon MQ for RabbitMQ 代理程式時，Amazon MQ 會套用一組預設政策和虛擬主機限制，以最佳化代理程式效能。如果您的代理程式沒有建議的預設政策和限制，我們建議您自行建立。如需建立預設政策和虛擬主機限制的詳細資訊，請參閱 [https://docs.aws.amazon.com//amazon-mq/latest/developer-guide/rabbitmq-defaults.html](https://docs.aws.amazon.com//amazon-mq/latest/developer-guide/rabbitmq-defaults.html)。

## 相關資源
<a name="rabbitmq-queue-sync-related-resources"></a>
+  [UpdateBrokerInput](https://docs.aws.amazon.com/amazon-mq/latest/api-reference/brokers-broker-id.html#brokers-broker-id-model-updatebrokerinput) – 使用 Amazon MQ API ，可利用此代理程式屬性更新代理程式執行個體類型。
+ [參數和政策](https://www.rabbitmq.com/parameters.html) (RabbitMQ 伺服器文件) – 進一步了解 RabbitMQ 網站上的 RabbitMQ 參數和政策。
+ [RabbitMQ 管理 HTTP API](https://pulse.mozilla.org/api/) – 進一步了解 RabbitMQ 管理 API。

# 減少連線和通道的數量
<a name="reducing-connections-and-channels"></a>

用戶端應用程式可以使用 RabbitMQ Web 主控台手動關閉與 Amazon MQ 代理程式 RabbitMQ 的連線。若要使用 RabbitMQ Web 主控台關閉連線，請執行下列動作：

1. 登入 AWS 管理主控台 並開啟代理程式的 RabbitMQ Web 主控台。

1.  在 RabbitMQ 主控台上，選擇 **Connections** (連線) 索引標籤。

1. 在 **Connections** (連線) 頁面上，**All connections** (所有連線) 下，從清單中選擇您要關閉的連線名稱。

1.  在連線詳細資訊頁面上，選擇 **Close this connection** (關閉此連線) 以展開區段，然後選擇 **Force Close** (強制關閉)。或者，您也可以使用自己的描述取代 **Reason** (原因) 的預設文字。當您關閉連線時，Amazon MQ 上的 RabbitMQ Amazon MQ 會將您指定的原因傳回給用戶端。

1.  在對話方塊上選擇 **OK** (確定) 以確認並關閉連線。

 關閉連線時，還會關閉與關閉連線關聯的所有通道。

**注意**  
 您的用戶端應用程式可以設定為在關閉後自動重新建立與代理程式的連線。在這種情況下，從代理程式 Web 主控台關閉連線不足以減少連線或通道計數。

對於沒有公開存取的代理程式，您可以透過拒絕相應訊息通訊協定連接埠 (例如，適用於 AMQP 連線的連接埠 `5671`) 上的傳入流量來臨時阻止連線。您可以在建立代理程式時阻止您提供給 Amazon MQ 之安全群組中的連接埠。如需有關修改安全群組的詳細資訊，請參閱《*Amazon VPC 使用者指南*》中的[新增規則至安全群組](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html#adding-security-group-rules)。

## 步驟 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 (安全與網路)** 下，選擇您的安全群組名稱或 ![\[Pencil icon indicating an edit or modification action.\]](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)。

# 使用 Amazon MQ for RabbitMQ 的 OAuth 2.0 身分驗證和授權
<a name="oauth-tutorial"></a>

本教學說明如何使用 Amazon Cognito 做為 [OAuth 2.0](oauth-for-amq-for-rabbitmq.md) 供應商，為您的 Amazon MQ for RabbitMQ 代理程式設定 OAuth 2.0 身分驗證。

**注意**  
Amazon Cognito 不適用於中國 （北京） 和中國 （寧夏）。

**重要**  
本教學課程專屬於 Amazon Cognito，但您可以使用其他身分提供者 (IdPs)。如需詳細資訊，請參閱 [OAuth 2.0 身分驗證範例。](https://www.rabbitmq.com/docs/oauth2-examples)

**Topics**
+ [設定 OAuth 2.0 身分驗證的先決條件](#oauth-tutorial-prerequisites)
+ [使用 設定 Amazon Cognito 的 OAuth 2.0 身分驗證 AWS CLI](#oauth-tutorial-config-cognito-using-cli)
+ [使用 Amazon Cognito 設定 OAuth 2.0 和簡易身分驗證](#oauth-tutorial-config-both-auth-methods-using-cli)

## 設定 OAuth 2.0 身分驗證的先決條件
<a name="oauth-tutorial-prerequisites"></a>

您可以部署 AWS CDK 堆疊、Amazon Cognito [ RabbitMQ OAuth 2 的 Amazon Cognito 堆疊外掛程式，藉此設定本教學課程中所需的 Amazon Cognito ](https://github.com/aws-samples/amazon-mq-samples/tree/main/rabbitmq-samples/rabbitmq-oauth2-cognito-sample)資源。如果您要手動設定 Amazon Cognito，請確保您在 Amazon MQ for RabbitMQ 代理程式上設定 OAuth 2.0 之前符合下列先決條件：

**設定 Amazon Cognito 的先決條件**
+ 透過建立使用者集區來設定 Amazon Cognito 端點。若要這樣做，請參閱 [Amazon Cognito 中名為如何使用 OAuth 2.0 的部落格：了解不同的 OAuth 2.0 授予](https://aws.amazon.com/blogs/security/how-to-use-oauth-2-0-in-amazon-cognito-learn-about-the-different-oauth-2-0-grants/)。
+ 在使用者集區`rabbitmq`中建立名為 的資源伺服器，並定義下列範圍：`read:all`、`configure:all`、 `write:all`和 `tag:administrator`。這些範圍將與 RabbitMQ 許可相關聯。

  如需建立資源伺服器的相關資訊，請參閱《*Amazon Cognito 開發人員指南*》中的[為您的使用者集區 (AWS 管理主控台) 定義資源伺服器](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-define-resource-servers.html#cognito-user-pools-define-resource-servers-console)。
+ 建立下列應用程式用戶端：
  + 類型為 之使用者集區的應用程式用戶端`Machine-to-Machine application`。這是機密用戶端，其用戶端秘密將用於 RabbitMQ AMQP 用戶端。如需應用程式用戶端和建立用戶端的詳細資訊，請參閱[應用程式用戶端類型](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html#user-pool-settings-client-app-client-types)和[建立應用程式用戶端](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html#cognito-user-pools-app-idp-settings-console-create)。
  + 類型為 之使用者集區的應用程式用戶端`Single-page application`。這是公有用戶端，將用於登入 RabbitMQ 管理主控台的使用者。您必須更新此應用程式用戶端，以包含您將在下列程序中建立的 Amazon MQ for RabbitMQ 代理程式端點，做為允許的回呼 URL。如需詳細資訊，請參閱[使用 Amazon Cognito 主控台設定受管登入](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-managed-login.html#set-up-managed-login)。

**設定 Amazon MQ 的先決條件**
+ 執行 bash 指令碼的工作 [Docker](https://docs.docker.com/engine/install/) 安裝，以驗證 OAuth 2.0 設定是否成功。
+ AWS CLI 版本 >= `2.28.23` 以在代理程式建立期間選擇性新增使用者名稱和密碼。

## 使用 設定 Amazon Cognito 的 OAuth 2.0 身分驗證 AWS CLI
<a name="oauth-tutorial-config-cognito-using-cli"></a>

下列程序說明如何使用 Amazon Cognito 做為 IdP，為您的 Amazon MQ for RabbitMQ 代理程式設定 OAuth 2.0 身分驗證。 Amazon Cognito IdP 此程序使用 AWS CLI 來建立和設定必要的資源。

在下列程序中，請務必將 configurationID 和 Revision、*<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>* 和 *<2>* 等預留位置值取代為實際值。

1. 使用 [create-configuration](https://docs.aws.amazon.com/cli/latest/reference/mq/create-configuration.html) AWS CLI 命令建立新的組態，如下列範例所示。

   ```
   aws mq create-configuration \
     --name "rabbitmq-oauth2-config" \
     --engine-type "RABBITMQ" \
     --engine-version "3.13"
   ```

   此命令會傳回類似下列範例的回應。

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "AuthenticationStrategy": "simple",
       "Created": "2025-07-17T16:03:01.759943+00:00",
       "Id": "c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "LatestRevision": {
       "Created": "2025-07-17T16:03:01.759000+00:00",
       "Description": "Auto-generated default for rabbitmq-oauth2-config on RabbitMQ 3.13",
       "Revision": 1
       },
       "Name": "rabbitmq-oauth2-config"
   }
   ```

1. 建立名為 的組態檔案**rabbitmq.conf**，以使用 OAuth 2.0 做為身分驗證和授權方法，如下列範例所示。

   ```
   auth_backends.1 = oauth2
   
   # FIXME: Update this value with the token signing key URL of your Amazon Cognito user pool.
   # If you used the AWS CDK stack to deploy Amazon Cognito, this is one of the stack outputs.
   auth_oauth2.jwks_url = ${RabbitMqOAuth2TestStack.JwksUri}
   auth_oauth2.resource_server_id = rabbitmq
   # Amazon Cognito does not include an audience field in access tokens
   auth_oauth2.verify_aud = false 
   
   # Amazon Cognito does not allow * in its custom scopes. Use aliases to translate between Amazon Cognito and RabbitMQ.
   auth_oauth2.scope_prefix = rabbitmq/
   auth_oauth2.scope_aliases.1.alias = rabbitmq/read:all
   auth_oauth2.scope_aliases.1.scope = rabbitmq/read:*/*
   auth_oauth2.scope_aliases.2.alias = rabbitmq/write:all
   auth_oauth2.scope_aliases.2.scope = rabbitmq/write:*/*
   auth_oauth2.scope_aliases.3.alias = rabbitmq/configure:all
   auth_oauth2.scope_aliases.3.scope = rabbitmq/configure:*/*
   
   # Allow OAuth 2.0 login for RabbitMQ management console
   management.oauth_enabled = true
   # FIXME: Update this value with the client ID of your public application client
   management.oauth_client_id = ${RabbitMqOAuth2TestStack.ManagementConsoleAppClientId}
   # FIXME: Update this value with the base JWKS URI (without /.well-known/jwks.json)
   auth_oauth2.issuer = ${RabbitMqOAuth2TestStack.Issuer}
   management.oauth_scopes = rabbitmq/tag:administrator
   ```

   此組態使用[範圍別名](https://www.rabbitmq.com/docs/oauth2#scope-translation)，將 Amazon Cognito 中定義的範圍映射至 RabbitMQ 相容範圍。

1. 使用 [update-configuration](https://docs.aws.amazon.com/cli/latest/reference/mq/update-configuration.html) AWS CLI 命令更新組態，如下列範例所示。在此命令中，新增您在此程序步驟 1 的回應中收到的組態 ID。例如 **c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca**。

   ```
   aws mq update-configuration \
     --configuration-id "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>" \
     --data "$(cat rabbitmq.conf | base64 --wrap=0)"
   ```

   此命令會傳回類似下列範例的回應。

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-b600ac8e-8183-4f74-a713-983e59f30e3d",
       "Created": "2025-07-17T16:57:04.520931+00:00",
       "Id": "c-b600ac8e-8183-4f74-a713-983e59f30e3d",
       "LatestRevision": {
           "Created": "2025-07-17T16:57:39.172000+00:00",
           "Revision": 2
       },
       "Name": "rabbitmq-oauth2-config",
       "Warnings": []
   }
   ```

1. 使用您在此程序的步驟 2 中建立的 OAuth 2.0 組態來建立代理程式。若要這樣做，請使用 [create-broker](https://docs.aws.amazon.com/cli/latest/reference/mq/create-broker.html) AWS CLI 命令，如下列範例所示。在此命令中，分別提供您在步驟 1 和 2 回應中取得的組態 ID 和修訂編號。例如，**c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca** 和 **2**。

   ```
   aws mq create-broker \
    --broker-name "rabbitmq-oauth2-broker" \ 
    --engine-type "RABBITMQ" \
    --engine-version "3.13" \
    --host-instance-type "mq.m7g.large" \
    --deployment-mode "CLUSTER_MULTI_AZ" \
    --logs '{"General": true}' \
    --publicly-accessible \
    --configuration '{"Id": "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>","Revision": <2>}' \
   ```

   此命令會傳回類似下列範例的回應。

   ```
   {
       "BrokerArn": "arn:aws:mq:us-west-2:123456789012:broker:rabbitmq-oauth2-broker:b-2a1b5133-a10c-49d2-879b-8c176c34cf73",
       "BrokerId": "b-2a1b5133-a10c-49d2-879b-8c176c34cf73"
   }
   ```

1. 使用 [describe-broker](https://docs.aws.amazon.com/cli/latest/reference/mq/describe-broker.html) AWS CLI 命令，確認代理程式的狀態從 轉換為 `CREATION_IN_PROGRESS` `RUNNING`，如下列範例所示。在此命令中，提供您在上一個步驟的結果中取得的代理程式 ID 例如，**b-2a1b5133-a10c-49d2-879b-8c176c34cf73**。

   ```
   aws mq describe-broker \
    --broker-id "<b-2a1b5133-a10c-49d2-879b-8c176c34cf73>"
   ```

   此命令會傳回類似下列範例的回應。下列回應是 `describe-broker`命令傳回的完整輸出的縮寫版本。此回應顯示代理程式狀態和用於保護代理程式的身分驗證策略。在此情況下，`config_managed`身分驗證策略表示代理程式使用 OAuth 2 身分驗證方法。

   ```
   {
       "AuthenticationStrategy": "config_managed",
       ...,
       "BrokerState": "RUNNING",
       ...
   }
   ```

    若要使用 OAuth2 登入 RabbitMQ 管理主控台，代理程式端點需要在對應的 Amazon Cognito 應用程式用戶端中新增為有效的回呼 URL。如需詳細資訊，請參閱 [Amazon Cognito CDK 堆疊](https://github.com/aws-samples/amazon-mq-samples/tree/main/rabbitmq-samples/rabbitmq-oauth2-cognito-sample#step-5-update-callback-urls-if-using-placeholder-urls)範例設定中的步驟 5。

1. 使用以下`perf-test.sh`指令碼驗證 OAuth 2.0 身分驗證和授權。

   使用此 bash 指令碼來測試 Amazon MQ for RabbitMQ 代理程式的連線能力。此指令碼會從 Amazon Cognito 取得權杖，並驗證連線是否已正確設定。如果設定成功，您會看到代理程式發佈並取用訊息。

   如果收到`ACCESS_REFUSED`錯誤，您可以使用代理程式的 CloudWatch 日誌對組態設定進行疑難排解。您可以在 Amazon MQ 主控台中找到代理程式的 CloudWatch 日誌群組連結。

   在此指令碼中，您需要提供下列值：
   + `CLIENT_ID` 和 `CLIENT_SECRET`：您可以在 Amazon Cognito 主控台**的應用程式用戶端**頁面上找到這些值。
   + Cognito 網域：您可以在 Amazon Cognito 主控台中找到此項目。在**品牌**下，選擇**網域**。在**網域**頁面上，您可以在**資源伺服器**區段下找到此值。
   + Amazon MQ 代理程式端點：您可以在 Amazon MQ 主控台代理程式詳細資訊頁面上的**連線**下找到此值。

   ```
   #! /bin/bash
   set -e
   
   # Client information
   ## FIXME: Update this value with the client ID and secret of your confidential application client
   CLIENT_ID=${RabbitMqOAuth2TestStack.AmqpAppClientId}
   CLIENT_SECRET=${RabbitMqOAuth2TestStack.AmqpAppClientSecret}
   
   # FIXME: Update this value with the domain of your Amazon Cognito user pool
   RESPONSE=$(curl -X POST ${RabbitMqOAuth2TestStack.TokenEndpoint} \
                   -H "Content-Type: application/x-www-form-urlencoded" \
                   -d "grant_type=client_credentials&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&scope=rabbitmq/configure:all rabbitmq/read:all rabbitmq/tag:administrator rabbitmq/write:all")
   
   
   # Extract the access_token from the response.
   # This token will be passed in the password field when connecting to the broker.
   # Note that the username is left blank, the field is ignored by the plugin.
   BROKER_PASSWORD=$(echo ${RESPONSE} | jq -r '.access_token')
   
   # FIXME: Update this value with the endpoint of your broker. For example, b-89424106-7e0e-4abe-8e98-8de0dada7630.mq.us-east-1.on.aws.
   BROKER_DNS=<broker_dns>
   CONNECTION_STRING=amqps://:${BROKER_PASSWORD}@${BROKER_DNS}:5671 
   
   # Produce/consume messages using the above connection string
   QUEUES_COUNT=1
   PRODUCERS_COUNT=1
   CONSUMERS_COUNT=1
   PRODUCER_RATE=1
   
   docker run -it --rm --ulimit nofile=40960:40960 pivotalrabbitmq/perf-test:latest \
       --queue-pattern 'test-queue-%d' --queue-pattern-from 1 --queue-pattern-to $QUEUES_COUNT \
       --producers $PRODUCERS_COUNT --consumers $CONSUMERS_COUNT \
       --id "test${QUEUES_COUNT}q${PRODUCERS_COUNT}p${CONSUMERS_COUNT}c${PRODUCER_RATE}r" \
       --uri ${CONNECTION_STRING} \
       --flag persistent --rate $PRODUCER_RATE
   ```

## 使用 Amazon Cognito 設定 OAuth 2.0 和簡易身分驗證
<a name="oauth-tutorial-config-both-auth-methods-using-cli"></a>

當您使用 OAuth 2.0 身分驗證建立代理程式時，您可以指定下列其中一種身分驗證方法：
+ 僅限 **OAuth 2.0**：若要使用此方法，請勿在建立代理程式時提供使用者名稱和密碼。[先前的程序](#oauth-tutorial-config-cognito-using-cli)說明如何僅使用 OAuth 2.0 身分驗證方法。
+ **OAuth 2.0 和簡單身分驗證**：若要使用此方法，請在建立代理程式時提供使用者名稱和密碼。此外，請將 `auth_backends.2 = internal`新增至您的代理程式組態，如下列程序所示。

在下列程序中，請務必以其實際值取代預留位置值，例如 *<ConfigurationId>* 和 *<Revision>*。

1. 若要使用這兩種身分驗證方法，請建立您的代理程式組態，如下列範例所示。

   ```
   auth_backends.1 = oauth2
   auth_backends.2 = internal
   
   # FIXME: Update this value with the token signing key URL of your Amazon Cognito user pool
   auth_oauth2.jwks_url = ${RabbitMqOAuth2TestStack.JwksUri}
   auth_oauth2.resource_server_id = rabbitmq
   auth_oauth2.verify_aud = false
   
   auth_oauth2.scope_prefix = rabbitmq/
   auth_oauth2.scope_aliases.1.alias = rabbitmq/read:all
   auth_oauth2.scope_aliases.1.scope = rabbitmq/read:*/*
   auth_oauth2.scope_aliases.2.alias = rabbitmq/write:all
   auth_oauth2.scope_aliases.2.scope = rabbitmq/write:*/*
   auth_oauth2.scope_aliases.3.alias = rabbitmq/configure:all
   auth_oauth2.scope_aliases.3.scope = rabbitmq/configure:*/*
   ```

   此組態使用[範圍別名](https://www.rabbitmq.com/docs/oauth2#scope-translation)，將 Amazon Cognito 中定義的範圍映射至 RabbitMQ 相容範圍。

1. 建立同時使用身分驗證方法的代理程式，如下列範例所示。

   ```
   aws mq create-broker \
    --broker-name "rabbitmq-oauth2-broker-with-internal-user" \
    --engine-type "RABBITMQ" \
    --engine-version "3.13" \
    --host-instance-type "mq.m7g.large" \
    --deployment-mode "CLUSTER_MULTI_AZ" \
    --logs '{"General": true}' \
    --publicly-accessible \
    --configuration '{"Id": "<ConfigurationId>","Revision": <Revision>}' \
    --users '[{"Username":"<myUser>","Password":"<myPassword11>"}]'
   ```

1. 驗證代理程式狀態和設定身分驗證方法的組態是否成功，如[使用 Amazon Cognito 設定 OAuth 2.0 身分驗證](#oauth-tutorial-config-cognito-using-cli)程序的步驟 5 和 6 所述。

# 使用 Amazon MQ for RabbitMQ 的 IAM 身分驗證和授權
<a name="rabbitmq-iam-tutorial"></a>

下列程序示範如何啟用 AWS Amazon MQ for RabbitMQ 代理程式的 IAM 身分驗證和授權。啟用 IAM 後，使用者可以使用 AWS IAM 憑證進行身分驗證，以存取 RabbitMQ Management API 並透過 AMQP 連線。如需 IAM 身分驗證如何與 Amazon MQ for RabbitMQ 搭配使用的詳細資訊，請參閱 [Amazon MQ for RabbitMQ 的 IAM 身分驗證和授權](iam-for-amq-for-rabbitmq.md)。

## 先決條件
<a name="iam-tutorial-prerequisites"></a>
+ AWS 擁有 Amazon MQ for RabbitMQ 代理程式 AWS 之帳戶的管理員登入資料
+ 使用這些管理員登入資料設定的 shell 環境 （使用 CLI AWS 設定檔或環境變數）
+ AWS 已安裝和設定的 CLI
+ `jq` 已安裝命令列 JSON 處理器
+ `curl` 已安裝命令列工具

## 使用 設定 IAM 身分驗證和授權 AWS CLI
<a name="iam-tutorial-procedure"></a>

1. **設定環境變數**

   為您的代理程式設定所需的環境變數：

   ```
   export AWS_DEFAULT_REGION=<region>
   export BROKER_ID=<broker-id>
   ```

1. **啟用傳出 JWT 字符**

   為 AWS 您的帳戶啟用傳出 Web 聯合身分：

   ```
   ISSUER_IDENTIFIER=$(aws iam enable-outbound-web-identity-federation --query 'IssuerIdentifier' --output text)
   echo $ISSUER_IDENTIFIER
   ```

   輸出會以 格式顯示您帳戶的唯一發行者識別符 URL`https://<id>.tokens.sts.global.api.aws`。

1. **建立 IAM 政策文件**

   建立政策文件，授予取得 Web 身分字符的許可：

   ```
   cat > policy.json << 'EOF'
   {
       "Version": "2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "VisualEditor0",
               "Effect": "Allow",
               "Action": [
                   "sts:GetWebIdentityToken",
                   "sts:TagGetWebIdentityToken"
               ],
               "Resource": "*"
           }
       ]
   }
   EOF
   ```

1. **建立信任政策**

   擷取您的發起人身分並建立信任政策文件：

   ```
   CALLER_ARN=$(aws sts get-caller-identity --query Arn --output text)
   cat > trust-policy.json << EOF
   {
       "Version": "2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": {
                   "AWS": "$CALLER_ARN"
               },
               "Action": "sts:AssumeRole"
           }
       ]
   }
   EOF
   ```

1. **建立 IAM 角色**

   建立 IAM 角色並連接政策：

   ```
   aws iam create-role --role-name RabbitMqAdminRole --assume-role-policy-document file://trust-policy.json
   aws iam put-role-policy --role-name RabbitMqAdminRole --policy-name RabbitMqAdminRolePolicy --policy-document file://policy.json
   ```

1. **設定 RabbitMQ OAuth2 設定**

   使用 OAuth2 身分驗證和授權設定建立 RabbitMQ 組態檔案：

   ```
   cat > rabbitmq.conf << EOF
   auth_backends.1 = oauth2
   auth_backends.2 = internal
   
   auth_oauth2.jwks_url = ${ISSUER_IDENTIFIER}/.well-known/jwks.json
   auth_oauth2.resource_server_id = rabbitmq
   auth_oauth2.scope_prefix = rabbitmq/
   
   auth_oauth2.additional_scopes_key = sub
   auth_oauth2.scope_aliases.1.alias = arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):role/RabbitMqAdminRole
   auth_oauth2.scope_aliases.1.scope = rabbitmq/tag:administrator rabbitmq/read:*/* rabbitmq/write:*/* rabbitmq/configure:*/*
   auth_oauth2.https.hostname_verification = wildcard
   
   management.oauth_enabled = true
   EOF
   ```

1. **更新代理程式組態**

   將新組態套用至您的代理程式：

   ```
   # Retrieve the configuration ID
   CONFIG_ID=$(aws mq describe-broker --broker-id $BROKER_ID --query 'Configurations[0].Id' --output text)
   
   # Create a new configuration revision
   REVISION=$(aws mq update-configuration --configuration-id $CONFIG_ID --data "$(cat rabbitmq.conf | base64 --wrap=0)" --query 'LatestRevision.Revision' --output text)
   
   # Apply the configuration to the broker
   aws mq update-broker --broker-id $BROKER_ID --configuration Id=$CONFIG_ID,Revision=$REVISION
   
   # Reboot the broker to apply changes
   aws mq reboot-broker --broker-id $BROKER_ID
   ```

   等待代理程式狀態回到 ，`RUNNING`再繼續下一個步驟。

1. **取得 JWT 字符**

   擔任 IAM 角色並取得 Web 身分字符：

   ```
   # Assume the RabbitMqAdminRole
   ROLE_CREDS=$(aws sts assume-role --role-arn arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):role/RabbitMqAdminRole --role-session-name rabbitmq-session)
   
   # Configure the session with temporary credentials
   export AWS_ACCESS_KEY_ID=$(echo "$ROLE_CREDS" | jq -r '.Credentials.AccessKeyId')
   export AWS_SECRET_ACCESS_KEY=$(echo "$ROLE_CREDS" | jq -r '.Credentials.SecretAccessKey')
   export AWS_SESSION_TOKEN=$(echo "$ROLE_CREDS" | jq -r '.Credentials.SessionToken')
   
   # Obtain the web identity token
   TOKEN_RESPONSE=$(aws sts get-web-identity-token \
       --audience "rabbitmq" \
       --signing-algorithm ES384 \
       --duration-seconds 300 \
       --tags Key=scope,Value="rabbitmq/tag:administrator")
   
   # Extract the token
   TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.WebIdentityToken')
   ```

1. **存取 RabbitMQ Management API**

   使用 JWT 字符存取 RabbitMQ 管理 API：

   ```
   BROKER_URL=<broker-id>.mq.<region>.on.aws
   
   curl -u ":$TOKEN" \
       -X GET https://${BROKER_URL}/api/overview \
       -H "Content-Type: application/json"
   ```

   成功的回應會確認 IAM 身分驗證是否正常運作。回應包含 JSON 格式的代理程式概觀資訊。

1. **使用 JWT 字符透過 AMQP 連接**

   使用 JWT 字符搭配 perf-test 工具測試 AMQP 連線：

   ```
   BROKER_DNS=<broker-endpoint>
   CONNECTION_STRING=amqps://:${TOKEN}@${BROKER_DNS}:5671
   
   docker run -it --rm --ulimit nofile=40960:40960 pivotalrabbitmq/perf-test:latest \
       --queue-pattern 'test-queue-%d' --queue-pattern-from 1 --queue-pattern-to 1 \
       --producers 1 --consumers 1 \
       --uri ${CONNECTION_STRING} \
       --flag persistent --rate 1
   ```

   如果您收到`ACCESS_REFUSED`錯誤，您可以使用代理程式的 CloudWatch 日誌對組態設定進行疑難排解。您可以在 Amazon MQ 主控台中找到代理程式的 CloudWatch Logs 日誌群組連結。

# 使用 Amazon MQ for RabbitMQ 的 LDAP 身分驗證和授權
<a name="rabbitmq-ldap-tutorial"></a>

本教學說明如何使用 設定 Amazon MQ for RabbitMQ 代理程式的 LDAP 身分驗證和授權 AWS Managed Microsoft AD。

**Topics**
+ [設定 LDAP 身分驗證和授權的先決條件](#rabbitmq-ldap-tutorial-prerequisites)
+ [使用 CLI 在 RabbitMQ AWS 中設定 LDAP](#rabbitmq-ldap-tutorial-configure-cli)

## 設定 LDAP 身分驗證和授權的先決條件
<a name="rabbitmq-ldap-tutorial-prerequisites"></a>

您可以部署 [AWS Amazon MQ for RabbitMQ LDAP 整合的 CDK 堆疊 AWS Managed Microsoft AD](https://github.com/aws-samples/amazon-mq-samples/blob/main/rabbitmq-samples/rabbitmq-ldap-activedirectory-sample/)，藉此設定本教學課程中所需的 AWS 資源。

此 CDK 堆疊會自動建立所有必要 AWS 的資源 AWS Managed Microsoft AD，包括 LDAP 使用者和群組、Network Load Balancer、憑證和 IAM 角色。如需堆疊所建立資源的完整清單，請參閱套件 README。

如果您要手動設定資源，而不是使用 CDK 堆疊，請確保在 Amazon MQ for RabbitMQ 代理程式上設定 LDAP 之前，已具備同等的基礎設施。

### 設定 Amazon MQ 的先決條件
<a name="rabbitmq-ldap-tutorial-prerequisite-cli"></a>

AWS CLI 版本 >= 2.28.23，以便在建立代理程式期間選擇性新增使用者名稱和密碼。

## 使用 CLI 在 RabbitMQ AWS 中設定 LDAP
<a name="rabbitmq-ldap-tutorial-configure-cli"></a>

此程序使用 AWS CLI 來建立和設定必要的資源。在下列程序中，請務必使用其實際值取代預留位置值，例如 configurationID 和 Revision`<2>`，`<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>`以及 。

1. 使用 `create-configuration` AWS CLI 命令建立新的組態，如下列範例所示。

   ```
   aws mq create-configuration \
     --name "rabbitmq-ldap-config" \
     --engine-type "RABBITMQ" \
     --engine-version "3.13"
   ```

   此命令會傳回類似下列範例的回應。

   ```
   {
   "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "AuthenticationStrategy": "simple",
       "Created": "2025-07-17T16:03:01.759943+00:00",
       "Id": "c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "LatestRevision": {
   "Created": "2025-07-17T16:03:01.759000+00:00",
       "Description": "Auto-generated default for rabbitmq-ldap-config on RabbitMQ 3.13",
       "Revision": 1
       },
       "Name": "rabbitmq-ldap-config"
   }
   ```

1. 建立名為 的組態檔案`rabbitmq.conf`，以使用 LDAP 做為身分驗證和授權方法，如下列範例所示。將範本中的所有預留位置值 （以 標記`${RabbitMqLdapTestStack.*}`) 取代為您部署 AWS CDK 的先決條件堆疊輸出或同等基礎設施的實際值。

   ```
   auth_backends.1 = ldap
   
   # LDAP authentication settings - For more information,
   # see https://www.rabbitmq.com/docs/ldap#basic
   
   # FIXME: Replace the ${RabbitMqLdapTestStack.*} placeholders with actual values
   # from your deployed prerequisite CDK stack outputs.
   auth_ldap.servers.1 = ${RabbitMqLdapTestStack.NlbDnsName}
   auth_ldap.dn_lookup_bind.user_dn = ${RabbitMqLdapTestStack.DnLookupUserDn}
   auth_ldap.dn_lookup_base = ${RabbitMqLdapTestStack.DnLookupBase}
   auth_ldap.dn_lookup_attribute = ${RabbitMqLdapTestStack.DnLookupAttribute}
   auth_ldap.port = 636
   auth_ldap.use_ssl = true
   auth_ldap.ssl_options.verify = verify_peer
   auth_ldap.log = network
   
   # AWS integration for secure credential retrieval
   # - see: https://github.com/amazon-mq/rabbitmq-aws
   # The aws plugin allows RabbitMQ to securely retrieve credentials and certificates
   # from AWS services.
   
   # Replace the ${RabbitMqLdapTestStack.*} placeholders with actual ARN values
   # from your deployed prerequisite CDK stack outputs.
   aws.arns.auth_ldap.ssl_options.cacertfile = ${RabbitMqLdapTestStack.CaCertArn}
   aws.arns.auth_ldap.dn_lookup_bind.password = ${RabbitMqLdapTestStack.DnLookupUserPasswordArn}
   aws.arns.assume_role_arn = ${RabbitMqLdapTestStack.AmazonMqAssumeRoleArn}
   
   # LDAP authorization queries - For more information,
   # see: https://www.rabbitmq.com/docs/ldap#authorisation
   
   # FIXME: Replace the ${RabbitMqLdapTestStack.*} placeholders with actual group DN
   # values from your deployed prerequisite CDK stack outputs
   # Uses Active Directory groups created by the prerequisite CDK stack
   auth_ldap.queries.tags = '''
   [{administrator, {in_group, "${RabbitMqLdapTestStack.RabbitMqAdministratorsGroupDn}"}},
   {management,    {in_group, "${RabbitMqLdapTestStack.RabbitMqMonitoringUsersGroupDn}"}}]
   '''
   
   # FIXME: This provides all authenticated users access to all vhosts
   # - update to restrict access as required
   auth_ldap.queries.vhost_access = '''
   {constant, true}
   '''
   
   # FIXME: This provides all authenticated users full access to all
   # queues and exchanges - update to restrict access as required
   auth_ldap.queries.resource_access = '''
   {for, [    {permission, configure, {constant, true}},
        {permission, write,
         {for, [{resource, queue,    {constant, true}},
                {resource, exchange, {constant, true}}]}},
        {permission, read,
         {for, [{resource, exchange, {constant, true}},
                {resource, queue,    {constant, true}}]}}
       ]
   }
   '''
   
   # FIXME: This provides all authenticated users access to all topics
   # - update to restrict access as required
   auth_ldap.queries.topic_access = '''
   {for, [{permission, write, {constant, true}},
        {permission, read,  {constant, true}}
       ]
   }
   '''
   ```

1. 使用 `update-configuration` AWS CLI 命令更新組態，如下列範例所示。在此命令中，新增您在此程序步驟 1 的回應中收到的組態 ID。例如 `c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca`。

   ```
   aws mq update-configuration \
     --configuration-id "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>" \
     --data "$(cat rabbitmq.conf | base64 --wrap=0)"
   ```

   此命令會傳回類似下列範例的回應。

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-b600ac8e-8183-4f74-a713-983e59f30e3d",
       "Created": "2025-07-17T16:57:04.520931+00:00",
       "Id": "c-b600ac8e-8183-4f74-a713-983e59f30e3d",
       "LatestRevision": {
           "Created": "2025-07-17T16:57:39.172000+00:00",
           "Revision": 2
       },
       "Name": "rabbitmq-ldap-config",
       "Warnings": []
   }
   ```

1. 使用您在此程序的步驟 2 中建立的 LDAP 組態來建立代理程式。若要這樣做，請使用 `create-broker` AWS CLI 命令，如下列範例所示。在此命令中，分別提供您在步驟 1 和 2 回應中取得的組態 ID 和修訂編號。例如，`c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca` 和 `2`。

   ```
   aws mq create-broker \
    --broker-name "rabbitmq-ldap-test-1" \
    --engine-type "RABBITMQ" \
    --engine-version "3.13" \
    --host-instance-type "mq.m7g.large" \
    --deployment-mode "CLUSTER_MULTI_AZ" \
    --logs '{"General": true}' \
    --publicly-accessible \
    --configuration '{"Id": "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>","Revision": <2>}'
   ```

   此命令會傳回類似下列範例的回應。

   ```
   {
       "BrokerArn": "arn:aws:mq:us-west-2:123456789012:broker:rabbitmq-ldap-broker:b-2a1b5133-a10c-49d2-879b-8c176c34cf73",
       "BrokerId": "b-2a1b5133-a10c-49d2-879b-8c176c34cf73"
   }
   ```
**中介裝置命名限制**  
先決條件 CDK 堆疊建立的 IAM 角色會將代理程式名稱限制為以 開頭`rabbitmq-ldap-test`。確保您的代理程式名稱遵循此模式，否則 IAM 角色將無法擔任 ARN 解析的角色。

1. 使用 `describe-broker` AWS CLI 命令，確認代理程式的狀態從 轉換為 `CREATION_IN_PROGRESS` `RUNNING`，如下列範例所示。在此命令中，提供您在上一個步驟的結果中取得的代理程式 ID 例如，`b-2a1b5133-a10c-49d2-879b-8c176c34cf73`。

   ```
   aws mq describe-broker \
    --broker-id "<b-2a1b5133-a10c-49d2-879b-8c176c34cf73>"
   ```

   此命令會傳回類似下列範例的回應。下列回應是 `describe-broker`命令傳回的完整輸出的縮寫版本。此回應顯示代理程式狀態和用於保護代理程式的身分驗證策略。在此情況下，`config_managed`身分驗證策略表示代理程式使用 LDAP 身分驗證方法。

   ```
   {
   "AuthenticationStrategy": "config_managed",
       ...,
       "BrokerState": "RUNNING",
       ...
   }
   ```

1. 使用先決條件 CDK 堆疊建立的其中一個測試使用者來驗證 RabbitMQ 存取

   ```
   # FIXME: Replace ${RabbitMqLdapTestStack.ConsoleUserPasswordArn} with the actual ARN from your deployed prerequisite CDK stack outputs
   CONSOLE_PASSWORD=$(aws secretsmanager get-secret-value \
     --secret-id ${RabbitMqLdapTestStack.ConsoleUserPasswordArn} \
     --query 'SecretString' --output text)
   
   # FIXME: Replace BrokerConsoleURL with the actual ConsoleURL retrieved by
   # calling describe-broker for the broker created above
   # Call management API /api/overview (should succeed)
   curl -u RabbitMqConsoleUser:$CONSOLE_PASSWORD \
     https://${BrokerConsoleURL}/api/overview
   
   # Try to create a user (should fail - console user only has monitoring permissions)
   curl -u RabbitMqConsoleUser:$CONSOLE_PASSWORD \
     -X PUT https://${BrokerConsoleURL}/api/users/testuser \
     -H "Content-Type: application/json" \
     -d '{"password":"testpass","tags":"management"}'
   ```

# 使用 Amazon MQ for RabbitMQ 的 HTTP 身分驗證和授權
<a name="rabbitmq-http-tutorial"></a>

本教學說明如何使用外部 HTTP 伺服器設定 Amazon MQ for RabbitMQ 代理程式的 HTTP 身分驗證和授權。

**注意**  
HTTP 身分驗證外掛程式僅適用於 Amazon MQ for RabbitMQ 第 4 版及更新版本。

**Topics**
+ [設定 HTTP 身分驗證和授權的先決條件](#rabbitmq-http-tutorial-prerequisites)
+ [使用 CLI 在 RabbitMQ 中設定 HTTP AWS 身分驗證](#rabbitmq-http-tutorial-configure-cli)

## 設定 HTTP 身分驗證和授權的先決條件
<a name="rabbitmq-http-tutorial-prerequisites"></a>

您可以部署 [AWS Amazon MQ for RabbitMQ HTTP 身分驗證整合的 CDK 堆疊](https://github.com/aws-samples/amazon-mq-samples/blob/main/rabbitmq-samples/rabbitmq-http-sample/)，藉此設定本教學課程中所需的 AWS 資源。

此 CDK 堆疊會自動建立所有必要 AWS 的資源，包括 HTTP 身分驗證伺服器、憑證和 IAM 角色。如需堆疊所建立資源的完整清單，請參閱套件 README。

如果您要手動設定資源，而不是使用 CDK 堆疊，請確保在 Amazon MQ for RabbitMQ 代理程式上設定 HTTP 身分驗證之前，已具備同等的基礎設施。

### 設定 Amazon MQ 的先決條件
<a name="rabbitmq-http-tutorial-prerequisite-cli"></a>

AWS CLI 版本 >= 2.28.23，以便在建立代理程式期間選擇性新增使用者名稱和密碼。

## 使用 CLI 在 RabbitMQ 中設定 HTTP AWS 身分驗證
<a name="rabbitmq-http-tutorial-configure-cli"></a>

此程序使用 AWS CLI 來建立和設定必要的資源。在下列程序中，請務必將預留位置值取代為其實際值。

1. 使用 `create-configuration` AWS CLI 命令建立新的組態，如下列範例所示。

   ```
   aws mq create-configuration \
     --name "rabbitmq-http-config" \
     --engine-type "RABBITMQ" \
     --engine-version "4.2"
   ```

   此命令會傳回類似下列範例的回應。

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "AuthenticationStrategy": "simple",
       "Created": "2025-07-17T16:03:01.759943+00:00",
       "Id": "c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "LatestRevision": {
           "Created": "2025-07-17T16:03:01.759000+00:00",
           "Description": "Auto-generated default for rabbitmq-http-config on RabbitMQ 4.2",
           "Revision": 1
       },
       "Name": "rabbitmq-http-config"
   }
   ```

1. 建立名為 的組態檔案`rabbitmq.conf`，以使用 HTTP 做為身分驗證和授權方法，如下列範例所示。將範本中的所有預留位置值 （以 標示`${...}`) 取代為您部署 AWS CDK 的先決條件堆疊輸出或同等基礎設施的實際值。

   ```
   auth_backends.1 = cache
   auth_backends.2 = http
   auth_cache.cached_backend = http
   
   # HTTP authentication settings
   # For more information, see https://github.com/rabbitmq/rabbitmq-auth-backend-http
   
   # FIXME: Replace the ${...} placeholders with actual values
   # from your deployed prerequisite CDK stack outputs.
   auth_http.http_method = post
   auth_http.user_path = ${HttpServerUserPath}
   auth_http.vhost_path = ${HttpServerVhostPath}
   auth_http.resource_path = ${HttpServerResourcePath}
   auth_http.topic_path = ${HttpServerTopicPath}
   
   # TLS/HTTPS configuration
   auth_http.ssl_options.verify = verify_peer
   auth_http.ssl_options.sni = test.amazonaws.com
   
   # AWS integration for secure credential retrieval
   # For more information, see https://github.com/amazon-mq/rabbitmq-aws
   
   # Replace the ${...} placeholders with actual ARN values
   # from your deployed prerequisite CDK stack outputs.
   aws.arns.assume_role_arn = ${AmazonMqAssumeRoleArn}
   aws.arns.auth_http.ssl_options.cacertfile = ${CaCertArn}
   ```

1. 使用 `update-configuration` AWS CLI 命令更新組態。使用步驟 3 中的組態 ID。

   ```
   aws mq update-configuration \
     --configuration-id "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>" \
     --data "$(cat rabbitmq.conf | base64 --wrap=0)"
   ```

   此命令會傳回類似下列範例的回應。

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "Created": "2025-07-17T16:57:04.520931+00:00",
       "Id": "c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "LatestRevision": {
           "Created": "2025-07-17T16:57:39.172000+00:00",
           "Revision": 2
       },
       "Name": "rabbitmq-http-config",
       "Warnings": []
   }
   ```

1. 使用 HTTP 組態建立代理程式。使用先前步驟中的組態 ID 和修訂編號。

   ```
   aws mq create-broker \
     --broker-name "rabbitmq-http-test-1" \
     --engine-type "RABBITMQ" \
     --engine-version "4.2" \
     --host-instance-type "mq.m7g.large" \
     --deployment-mode "SINGLE_INSTANCE" \
     --logs '{"General": true}' \
     --publicly-accessible \
     --configuration '{"Id": "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>","Revision": <2>}'
   ```

   此命令會傳回類似下列範例的回應。

   ```
   {
       "BrokerArn": "arn:aws:mq:us-west-2:123456789012:broker:rabbitmq-http-test-1:b-2a1b5133-a10c-49d2-879b-8c176c34cf73",
       "BrokerId": "b-2a1b5133-a10c-49d2-879b-8c176c34cf73"
   }
   ```

1. 使用 `describe-broker` AWS CLI `CREATION_IN_PROGRESS` 命令`RUNNING`，確認代理程式的狀態從 轉換為 。

   ```
   aws mq describe-broker \
     --broker-id "<b-2a1b5133-a10c-49d2-879b-8c176c34cf73>"
   ```

   此命令會傳回類似下列範例的回應。`config_managed` 身分驗證策略表示代理程式使用 HTTP 身分驗證方法。

   ```
   {
       "AuthenticationStrategy": "config_managed",
       ...,
       "BrokerState": "RUNNING",
       ...
   }
   ```

1. 使用先決條件 CDK 堆疊建立的其中一個測試使用者來驗證 RabbitMQ 存取

   ```
   # FIXME: Replace ${RabbitMqHttpAuthElbStack.ConsoleUserPasswordArn} with the actual ARN from your deployed prerequisite CDK stack outputs
   CONSOLE_PASSWORD=$(aws secretsmanager get-secret-value \
     --secret-id ${RabbitMqHttpAuthElbStack.ConsoleUserPasswordArn} \
     --query 'SecretString' --output text)
   
   # FIXME: Replace BrokerConsoleURL with the actual ConsoleURL retrieved by
   # calling describe-broker for the broker created above
   # Call management API /api/overview (should succeed)
   curl -u RabbitMqConsoleUser:$CONSOLE_PASSWORD \
     https://${BrokerConsoleURL}/api/overview
   
   # Try to create a vhost (should fail - console user only has management permissions)
   curl -u RabbitMqConsoleUser:$CONSOLE_PASSWORD \
     -X PUT https://${BrokerConsoleURL}/api/vhosts/test-vhost \
     -H "Content-Type: application/json" \
     -d '{}'
   ```

# 針對 Amazon MQ for RabbitMQ 使用 SSL 憑證身分驗證
<a name="rabbitmq-ssl-tutorial"></a>

本教學課程說明如何使用私有憑證授權機構設定 Amazon MQ for RabbitMQ 代理程式的 SSL 憑證驗證。

**注意**  
SSL 憑證身分驗證外掛程式僅適用於 Amazon MQ for RabbitMQ 第 4 版及更高版本。

**Topics**
+ [設定 SSL 憑證身分驗證的先決條件](#rabbitmq-ssl-tutorial-prerequisites)
+ [使用 CLI 在 RabbitMQ 中設定 SSL AWS 憑證身分驗證](#rabbitmq-ssl-tutorial-configure-cli)

## 設定 SSL 憑證身分驗證的先決條件
<a name="rabbitmq-ssl-tutorial-prerequisites"></a>

SSL 憑證驗證使用交互 TLS (mTLS) 來驗證使用 X.509 憑證的用戶端。您可以部署 [AWS Amazon MQ for RabbitMQ mTLS 整合的 CDK 堆疊](https://github.com/aws-samples/amazon-mq-samples/blob/main/rabbitmq-samples/rabbitmq-mtls-sample/)，藉此設定本教學課程中所需的 AWS 資源。

此 CDK 堆疊會自動建立所有必要 AWS 的資源，包括憑證授權單位、用戶端憑證和 IAM 角色。如需堆疊所建立資源的完整清單，請參閱套件 README。

**注意**  
部署 CDK 堆疊之前，請設定 `RABBITMQ_TEST_USER_NAME`環境變數。此值將用作用戶端憑證中的通用名稱 (CN)，並且必須符合您在教學課程中使用的使用者名稱。例如：`export RABBITMQ_TEST_USER_NAME="myuser"`

如果您要手動設定資源，而不是使用 CDK 堆疊，請確保在 Amazon MQ for RabbitMQ 代理程式上設定 SSL 憑證身分驗證之前，已具備同等的基礎設施。

### 設定 Amazon MQ 的先決條件
<a name="rabbitmq-ssl-tutorial-prerequisite-cli"></a>

AWS CLI 版本 >= 2.28.23，以便在建立代理程式期間選擇性新增使用者名稱和密碼。

## 使用 CLI 在 RabbitMQ 中設定 SSL AWS 憑證身分驗證
<a name="rabbitmq-ssl-tutorial-configure-cli"></a>

此程序使用 AWS CLI 來建立和設定必要的資源。在下列程序中，請務必使用其實際值取代預留位置值，例如 configurationID 和 Revision`<2>`，`<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>`以及 。

1. 使用 `create-configuration` AWS CLI 命令建立新的組態，如下列範例所示。

   ```
   aws mq create-configuration \
     --name "rabbitmq-ssl-config" \
     --engine-type "RABBITMQ" \
     --engine-version "4.2"
   ```

   此命令會傳回類似下列範例的回應。

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "AuthenticationStrategy": "simple",
       "Created": "2025-07-17T16:03:01.759943+00:00",
       "Id": "c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "LatestRevision": {
           "Created": "2025-07-17T16:03:01.759000+00:00",
           "Description": "Auto-generated default for rabbitmq-ssl-config on RabbitMQ 4.2",
           "Revision": 1
       },
       "Name": "rabbitmq-ssl-config"
   }
   ```

1. 建立名為 的組態檔案`rabbitmq.conf`，以使用 SSL 憑證身分驗證，如下列範例所示。將範本中的所有預留位置值 （以 標示`${...}`) 取代為您部署 AWS CDK 的先決條件堆疊輸出或同等基礎設施的實際值。

   ```
   auth_mechanisms.1 = EXTERNAL
   ssl_cert_login_from = common_name
   
   auth_backends.1 = internal
   
   # Reject if no client cert
   ssl_options.verify = verify_peer
   ssl_options.fail_if_no_peer_cert = true
   
   # AWS integration for secure credential retrieval
   # For more information, see https://github.com/amazon-mq/rabbitmq-aws
   
   # FIXME: Replace the ${...} placeholders with actual ARN values
   # from your deployed prerequisite CDK stack outputs.
   aws.arns.assume_role_arn = ${AmazonMqAssumeRoleArn}
   aws.arns.ssl_options.cacertfile = ${CaCertArn}
   ```

1. 使用 `update-configuration` AWS CLI 命令更新組態，如下列範例所示。在此命令中，新增您在此程序步驟 1 的回應中收到的組態 ID。例如 `c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca`。

   ```
   aws mq update-configuration \
     --configuration-id "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>" \
     --data "$(cat rabbitmq.conf | base64 --wrap=0)"
   ```

   此命令會傳回類似下列範例的回應。

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "Created": "2025-07-17T16:57:04.520931+00:00",
       "Id": "c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "LatestRevision": {
           "Created": "2025-07-17T16:57:39.172000+00:00",
           "Revision": 2
       },
       "Name": "rabbitmq-ssl-config",
       "Warnings": []
   }
   ```

1. 使用您在此程序的步驟 2 中建立的 SSL 憑證身分驗證組態來建立代理程式。若要這樣做，請使用 `create-broker` AWS CLI 命令，如下列範例所示。在此命令中，分別提供您在步驟 1 和 2 回應中取得的組態 ID 和修訂編號。例如，`c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca` 和 `2`。

   ```
   aws mq create-broker \
     --broker-name "rabbitmq-ssl-test-1" \
     --engine-type "RABBITMQ" \
     --engine-version "4.2" \
     --host-instance-type "mq.m7g.large" \
     --deployment-mode "SINGLE_INSTANCE" \
     --logs '{"General": true}' \
     --publicly-accessible \
     --configuration '{"Id": "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>","Revision": <2>}' \
     --users '[{"Username":"testuser","Password":"testpassword"}]'
   ```

   此命令會傳回類似下列範例的回應。

   ```
   {
       "BrokerArn": "arn:aws:mq:us-west-2:123456789012:broker:rabbitmq-ssl-test-1:b-2a1b5133-a10c-49d2-879b-8c176c34cf73",
       "BrokerId": "b-2a1b5133-a10c-49d2-879b-8c176c34cf73"
   }
   ```

1. 使用 `describe-broker` AWS CLI 命令，確認代理程式的狀態從 轉換為 `CREATION_IN_PROGRESS` `RUNNING`，如下列範例所示。在此命令中，提供您在上一個步驟的結果中取得的代理程式 ID。例如 `b-2a1b5133-a10c-49d2-879b-8c176c34cf73`。

   ```
   aws mq describe-broker \
     --broker-id "<b-2a1b5133-a10c-49d2-879b-8c176c34cf73>"
   ```

   此命令會傳回類似下列範例的回應。下列回應是 `describe-broker`命令傳回的完整輸出的縮寫版本。此回應顯示代理程式狀態和用於保護代理程式的身分驗證策略。在此情況下，`config_managed`身分驗證策略表示代理程式使用 SSL 憑證身分驗證方法。

   ```
   {
       "AuthenticationStrategy": "config_managed",
       ...,
       "BrokerState": "RUNNING",
       ...
   }
   ```

1. 使用以下`ssl.sh`指令碼驗證 SSL 憑證身分驗證。

   使用此 bash 指令碼來測試 Amazon MQ for RabbitMQ 代理程式的連線能力。此指令碼使用您的用戶端憑證進行身分驗證，並驗證連線是否已正確設定。如果設定成功，您會看到代理程式發佈並取用訊息。

   如果您收到`ACCESS_REFUSED`錯誤，您可以使用代理程式的 CloudWatch 日誌對組態設定進行疑難排解。您可以在 Amazon MQ 主控台中找到代理程式的 CloudWatch 日誌群組連結。

   在此指令碼中，您需要提供下列值：
   + `USERNAME`：用戶端憑證的通用名稱 (CN)。
   + `CLIENT_KEYSTORE`：用戶端金鑰存放區檔案的路徑 (PKCS12 格式）。如果您使用先決條件 CDK 堆疊，預設路徑為 `$(pwd)/certs/client-keystore.p12`。
   + `KEYSTORE_PASSWORD`：用戶端金鑰存放區的密碼。如果您使用先決條件 CDK 堆疊，預設密碼為 `changeit`。
   + `BROKER_DNS`：您可以在 Amazon MQ 主控台的代理程式詳細資訊頁面的**連線**下找到此值。

   ```
   #! /bin/bash
   set -e
   
   # Client information
   ## FIXME: Update this value with the client ID and secret of your confidential application client
   USERNAME=<client_cert_common_name>
   CLIENT_KEYSTORE=$(pwd)/certs/client-keystore.p12
   KEYSTORE_PASSWORD=changeit
   
   BROKER_DNS=<broker_dns>
   CONNECTION_STRING=amqps://${BROKER_DNS}:5671 
   
   # Produce/consume messages using the above connection string
   QUEUES_COUNT=1
   PRODUCERS_COUNT=1
   CONSUMERS_COUNT=1
   PRODUCER_RATE=1
   
   finch run --rm --ulimit nofile=40960:40960 \
       -v ${CLIENT_KEYSTORE}:/certs/client-keystore.p12:ro \
       -e JAVA_TOOL_OPTIONS="-Djavax.net.ssl.keyStore=/certs/client-keystore.p12 -Djavax.net.ssl.keyStorePassword=${KEYSTORE_PASSWORD} -Djavax.net.ssl.keyStoreType=PKCS12" \
       pivotalrabbitmq/perf-test:latest \
       --queue-pattern 'test-queue-cert-%d' --queue-pattern-from 1 --queue-pattern-to $QUEUES_COUNT \
       --producers $PRODUCERS_COUNT --consumers $CONSUMERS_COUNT \
       --id "cert-test${QUEUES_COUNT}q${PRODUCERS_COUNT}p${CONSUMERS_COUNT}c${PRODUCER_RATE}r" \
       --uri ${CONNECTION_STRING} \
       --sasl-external \
       --use-default-ssl-context \
       --flag persistent --rate $PRODUCER_RATE
   ```

# 將 mTLS 用於 AMQP 和管理端點
<a name="rabbitmq-mtls-tutorial"></a>

本教學課程說明如何使用私有憑證授權機構為 AMQP 用戶端連線和 RabbitMQ 管理界面設定交互 TLS (mTLS)。

**注意**  
針對 mTLS 使用私有憑證授權單位僅適用於 Amazon MQ for RabbitMQ 第 4 版及更高版本。

**Topics**
+ [設定 mTLS 的先決條件](#rabbitmq-mtls-tutorial-prerequisites)
+ [使用 CLI 在 RabbitMQ AWS 中設定 mTLS](#rabbitmq-mtls-tutorial-configure-cli)

## 設定 mTLS 的先決條件
<a name="rabbitmq-mtls-tutorial-prerequisites"></a>

您可以部署 [AWS Amazon MQ for RabbitMQ mTLS 與 整合的 CDK 堆疊](https://github.com/aws-samples/amazon-mq-samples/blob/main/rabbitmq-samples/rabbitmq-mtls-sample/)，藉此設定本教學課程中所需的 AWS 資源。

此 CDK 堆疊會自動建立所有必要 AWS 的資源，包括憑證授權單位、用戶端憑證和 IAM 角色。如需堆疊所建立資源的完整清單，請參閱套件 README。

如果您要手動設定資源，而不是使用 CDK 堆疊，請確保您在 Amazon MQ for RabbitMQ 代理程式上設定 mTLS 之前已具備同等的基礎設施。

### 設定 Amazon MQ 的先決條件
<a name="rabbitmq-mtls-tutorial-prerequisite-cli"></a>

AWS CLI 版本 >= 2.28.23，以便在建立代理程式期間選擇性新增使用者名稱和密碼。

## 使用 CLI 在 RabbitMQ AWS 中設定 mTLS
<a name="rabbitmq-mtls-tutorial-configure-cli"></a>

此程序使用 AWS CLI 來建立和設定必要的資源。在下列程序中，請務必使用其實際值取代預留位置值，例如 configurationID 和 Revision`<2>`，`<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>`以及 。

1. 使用 `create-configuration` AWS CLI 命令建立新的組態，如下列範例所示。

   ```
   aws mq create-configuration \
     --name "rabbitmq-mtls-config" \
     --engine-type "RABBITMQ" \
     --engine-version "4.2"
   ```

   此命令會傳回類似下列範例的回應。

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "AuthenticationStrategy": "simple",
       "Created": "2025-07-17T16:03:01.759943+00:00",
       "Id": "c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "LatestRevision": {
           "Created": "2025-07-17T16:03:01.759000+00:00",
           "Description": "Auto-generated default for rabbitmq-mtls-config on RabbitMQ 4.2",
           "Revision": 1
       },
       "Name": "rabbitmq-mtls-config"
   }
   ```

1. 建立名為 的組態檔案`rabbitmq.conf`，以設定 AMQP 和管理端點的 mTLS，如下列範例所示。將範本中的所有預留位置值 （以 標示`${...}`) 取代為您部署 AWS CDK 的先決條件堆疊輸出或同等基礎設施的實際值。

   ```
   auth_backends.1 = internal
   
   # TLS configuration
   ssl_options.verify = verify_peer
   ssl_options.fail_if_no_peer_cert = true
   management.ssl.verify = verify_peer
   
   # AWS integration for secure credential retrieval
   # For more information, see https://github.com/amazon-mq/rabbitmq-aws
   
   # FIXME: Replace the ${...} placeholders with actual ARN values
   # from your deployed prerequisite CDK stack outputs.
   aws.arns.assume_role_arn = ${AmazonMqAssumeRoleArn}
   aws.arns.ssl_options.cacertfile = ${CaCertArn}
   aws.arns.management.ssl.cacertfile = ${CaCertArn}
   ```

1. 使用 `update-configuration` AWS CLI 命令更新組態，如下列範例所示。在此命令中，新增您在此程序步驟 1 的回應中收到的組態 ID。例如 `c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca`。

   ```
   aws mq update-configuration \
     --configuration-id "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>" \
     --data "$(cat rabbitmq.conf | base64 --wrap=0)"
   ```

   此命令會傳回類似下列範例的回應。

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "Created": "2025-07-17T16:57:04.520931+00:00",
       "Id": "c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "LatestRevision": {
           "Created": "2025-07-17T16:57:39.172000+00:00",
           "Revision": 2
       },
       "Name": "rabbitmq-mtls-config",
       "Warnings": []
   }
   ```

1. 使用您在此程序的步驟 2 中建立的 mTLS 組態來建立代理程式。若要這樣做，請使用 `create-broker` AWS CLI 命令，如下列範例所示。在此命令中，分別提供您在步驟 1 和 2 回應中取得的組態 ID 和修訂編號。例如，`c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca` 和 `2`。

   ```
   aws mq create-broker \
     --broker-name "rabbitmq-mtls-test-1" \
     --engine-type "RABBITMQ" \
     --engine-version "4.2" \
     --host-instance-type "mq.m7g.large" \
     --deployment-mode "SINGLE_INSTANCE" \
     --logs '{"General": true}' \
     --publicly-accessible \
     --configuration '{"Id": "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>","Revision": <2>}' \
     --users '[{"Username":"testuser","Password":"testpassword"}]'
   ```

   此命令會傳回類似下列範例的回應。

   ```
   {
       "BrokerArn": "arn:aws:mq:us-west-2:123456789012:broker:rabbitmq-mtls-test-1:b-2a1b5133-a10c-49d2-879b-8c176c34cf73",
       "BrokerId": "b-2a1b5133-a10c-49d2-879b-8c176c34cf73"
   }
   ```

1. 使用 `describe-broker` AWS CLI 命令，確認代理程式的狀態從 轉換為 `CREATION_IN_PROGRESS` `RUNNING`，如下列範例所示。在此命令中，提供您在上一個步驟的結果中取得的代理程式 ID。例如 `b-2a1b5133-a10c-49d2-879b-8c176c34cf73`。

   ```
   aws mq describe-broker \
     --broker-id "<b-2a1b5133-a10c-49d2-879b-8c176c34cf73>"
   ```

   此命令會傳回類似下列範例的回應。下列回應是 `describe-broker`命令傳回的完整輸出的縮寫版本。

   ```
   {
       "AuthenticationStrategy": "simple",
       ...,
       "BrokerState": "RUNNING",
       ...
   }
   ```

1. 使用以下`mtls.sh`指令碼驗證 mTLS 身分驗證。

   使用此 bash 指令碼來測試 Amazon MQ for RabbitMQ 代理程式的連線能力。此指令碼使用您的用戶端憑證來驗證和驗證連線是否已正確設定。如果設定成功，您會看到代理程式發佈並取用訊息。

   如果您收到`ACCESS_REFUSED`錯誤，您可以使用代理程式的 CloudWatch 日誌對組態設定進行疑難排解。您可以在 Amazon MQ 主控台中找到代理程式的 CloudWatch 日誌群組連結。

   在此指令碼中，您需要提供下列值：
   + `USERNAME` 和 `PASSWORD`：您使用代理程式建立的 RabbitMQ 使用者登入資料。
   + `CLIENT_KEYSTORE`：用戶端金鑰存放區檔案的路徑 (PKCS12 格式）。如果您使用先決條件 CDK 堆疊，預設路徑為 `$(pwd)/certs/client-keystore.p12`。
   + `KEYSTORE_PASSWORD`：用戶端金鑰存放區的密碼。如果您使用先決條件 CDK 堆疊，預設密碼為 `changeit`。
   + `BROKER_DNS`：您可以在 Amazon MQ 主控台的代理程式詳細資訊頁面的**連線**下找到此值。

   ```
   #! /bin/bash
   set -e
   
   # Client information
   ## FIXME: Update this value with the client ID and secret of your confidential application client
   USERNAME=<testuser>
   PASSWORD=<testpassword>
   CLIENT_KEYSTORE=$(pwd)/certs/client-keystore.p12
   KEYSTORE_PASSWORD=changeit
   
   BROKER_DNS=<broker_dns>
   CONNECTION_STRING=amqps://${USERNAME}:${PASSWORD}@${BROKER_DNS}:5671 
   
   # Produce/consume messages using the above connection string
   QUEUES_COUNT=1
   PRODUCERS_COUNT=1
   CONSUMERS_COUNT=1
   PRODUCER_RATE=1
   
   finch run --rm --ulimit nofile=40960:40960 \
       -v ${CLIENT_KEYSTORE}:/certs/client-keystore.p12:ro \
       -e JAVA_TOOL_OPTIONS="-Djavax.net.ssl.keyStore=/certs/client-keystore.p12 -Djavax.net.ssl.keyStorePassword=${KEYSTORE_PASSWORD} -Djavax.net.ssl.keyStoreType=PKCS12" \
       pivotalrabbitmq/perf-test:latest \
       --queue-pattern 'test-queue-cert-%d' --queue-pattern-from 1 --queue-pattern-to $QUEUES_COUNT \
       --producers $PRODUCERS_COUNT --consumers $CONSUMERS_COUNT \
       --id "cert-test${QUEUES_COUNT}q${PRODUCERS_COUNT}p${CONSUMERS_COUNT}c${PRODUCER_RATE}r" \
       --uri ${CONNECTION_STRING} \
       --use-default-ssl-context \
       --flag persistent --rate $PRODUCER_RATE
   ```

# 連接您的 JMS 應用程式
<a name="rabbitmq-tutorial-jms"></a>

 本教學課程說明如何使用 RabbitMQ JMS 用戶端將 JMS 應用程式連線至 Amazon MQ for RabbitMQ 代理程式。您將了解如何建立生產者以傳送訊息，以及建立取用者以接收來自 RabbitMQ 佇列的訊息。

 開始之前，請將適當的 RabbitMQ JMS 相依性新增至 Maven 專案：

 對於 JMS 1.1 和 2.0：

```
<dependencies>

  <dependency>
    <groupId>com.rabbitmq.jms</groupId>
    <artifactId>rabbitmq-jms</artifactId>
    <version>2.12.0</version>
  </dependency>

</dependencies>
```

 對於 JMS 3.1：

```
<dependencies>

  <dependency>
    <groupId>com.rabbitmq.jms</groupId>
    <artifactId>rabbitmq-jms</artifactId>
    <version>3.5.0</version>
  </dependency>

</dependencies>
```

## 建立生產者
<a name="rabbitmq-tutorial-jms-producer"></a>

 下列程式碼範例示範如何使用 JMS 寫入 RabbitMQ 佇列：

```
import jakarta.jms.*;
import com.rabbitmq.jms.admin.*;

// Setting the connection factory
RMQConnectionFactory factory = new RMQConnectionFactory();
factory.setHost(envProps.getProperty("RABBITMQ_HOST", "localhost"));
factory.setPort(Integer.parseInt(envProps.getProperty("RABBITMQ_PORT", "5672")));
factory.setUsername(envProps.getProperty("RABBITMQ_USERNAME", "guest"));
factory.setPassword(envProps.getProperty("RABBITMQ_PASSWORD", "guest"));
factory.setVirtualHost(envProps.getProperty("RABBITMQ_VIRTUAL_HOST", "/"));
factory.useSslProtocol();

connection = factory.createConnection();
connection.start();

String queueName = "test-queue-jms";
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

RMQDestination destination = new RMQDestination(queueName, true, false);

// Send the message to the queue
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);

String msg_content = "Hello World!!";
TextMessage textMessage = session.createTextMessage(msg_content);
producer.send(textMessage);

System.out.printf("Published to AMQP queue '%s': %s", queueName, msg_content);
```

## 建立取用者
<a name="rabbitmq-tutorial-jms-consumer"></a>

 下列程式碼範例示範如何使用 JMS 從 RabbitMQ 佇列讀取：

```
import jakarta.jms.*;
import com.rabbitmq.jms.admin.*;

// Setting the connection factory
RMQConnectionFactory factory = new RMQConnectionFactory();
factory.setHost(envProps.getProperty("RABBITMQ_HOST", "localhost"));
factory.setPort(Integer.parseInt(envProps.getProperty("RABBITMQ_PORT", "5672")));
factory.setUsername(envProps.getProperty("RABBITMQ_USERNAME", "guest"));
factory.setPassword(envProps.getProperty("RABBITMQ_PASSWORD", "guest"));
factory.setVirtualHost(envProps.getProperty("RABBITMQ_VIRTUAL_HOST", "/"));
factory.useSslProtocol();

// Establish the connection and session
jakarta.jms.Connection connection = factory.createConnection();

String queueName = "test-queue-jms";
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

RMQDestination destination = new RMQDestination();
destination.setDestinationName(queueName);
destination.setAmqp(true);
destination.setAmqpQueueName(queueName);

// Initialize consumer
MessageConsumer consumer = session.createConsumer(destination);
consumer.setMessageListener(message -> {
    try {
        if (message instanceof TextMessage) {
            TextMessage textMessage = (TextMessage) message;
            System.out.printf("Message: %s%n", textMessage.getText());
        } else if (message instanceof BytesMessage) {
            BytesMessage bytesMessage = (BytesMessage) message;
            byte[] bytes = new byte[(int) bytesMessage.getBodyLength()];
            bytesMessage.readBytes(bytes);
            String content = new String(bytes);
            System.out.printf("Message: %s%n", content);
        } else {
            System.out.printf("Message: [%s]%n", message.getClass().getSimpleName());
        }
    } catch (JMSException e) {
        System.err.printf("Error processing message: %s%n", e.getMessage());
    }
});

connection.start();
```