返回文章列表

SQS和SNS無伺服器訊息佇列與通知

本文介紹如何在無伺服器架構中使用 AWS SQS 和 SNS 進行訊息佇列和通知處理,包含使用 AWS CLI 和 Java SDK 建立 SQS 佇列、傳送和接收訊息,以及使用 CloudFormation 建立 SQS 佇列等實務操作,並提供 Lambda 函式與 SQS 整合的程式碼範例,說明如何批次處

雲端服務 無伺服器架構

在無伺服器架構中,訊息佇列和通知服務扮演著關鍵角色。Amazon SQS 提供可靠的訊息佇列服務,而 SNS 則負責訊息的釋出和訂閱。透過 AWS CLI 或 CloudFormation,可以快速建立和管理 SQS 佇列。Java SDK 簡化了 SQS 訊息的傳送、接收和批次處理,並能與 Lambda 函式整合,實作根據事件驅動的無伺服器應用。此外,文章也涵蓋了使用 CloudFormation 進行 SQS 資源的佈署,以及如何設定必要的 IAM 許可權以確保操作安全。

訊息佇列與通知:SQS和SNS基礎

本章節將介紹如何在無伺服器架構中加入訊息佇列和通知功能。主要內容包括使用SQS(簡單佇列服務)和SNS(簡單通知服務)來實作訊息的傳遞和Lambda函式的觸發。

主要內容

  1. 建立第一個SQS佇列:使用AWS CLI和CloudFormation範本。
  2. 使用SDK傳送和接收SQS訊息:以Java為例,示範如何傳送和批次處理SQS訊息。
  3. SNS主題的建立與發布:使用AWS CLI和Java SDK,建立SNS主題並發布訊息。

準備工作

  • 具備有效的AWS帳戶。
  • 按照第一章的指示組態AWS CLI。

重點步驟

建立SQS佇列

使用AWS CLI建立一個基本的SQS佇列:

aws sqs create-queue \
--queue-name 'my-first-queue' \
--profile admin

此命令將建立一個名為my-first-queue的SQS佇列。

結語

本章節為讀者提供了在無伺服器架構中使用SQS和SNS進行訊息佇列和通知處理的基礎知識。透過這些服務,可以構建更加靈活和可擴充套件的應用程式。下一章將進一步探討無伺服器架構的其他應用場景。

內容解密:

  1. 使用aws sqs create-queue命令建立SQS佇列是實作訊息佇列服務的第一步。
  2. --queue-name引數指定了佇列的名稱,方便管理和識別。
  3. --profile admin表示使用名為admin的AWS CLI組態檔來執行命令,確保了操作的許可權和安全性。

程式碼解析:

aws sqs create-queue \
--queue-name 'my-first-queue' \
--profile admin

此CLI命令用於建立一個名為my-first-queue的SQS佇列,其中:

  • aws sqs create-queue是建立SQS佇列的基本命令。
  • --queue-name 'my-first-queue'指定了所建立佇列的名稱。
  • --profile admin選項指定了執行該命令所使用的AWS組態檔名稱。

後續步驟:

  1. 進一步探索如何使用Java SDK與SQS互動,包括傳送、接收和刪除訊息。
  2. 研究如何將SQS與Lambda函式結合,實作根據事件驅動的無伺服器架構。

使用SQS和SNS進行訊息傳遞與通知(第六章)

建立SQS佇列

AWS提供了一個名為Simple Queue Service(SQS)的服務,用於處理訊息佇列。我們可以使用AWS CLI或CloudFormation來建立SQS佇列。

使用AWS CLI建立SQS佇列

要使用AWS CLI建立SQS佇列,可以執行以下命令:

aws sqs create-queue --queue-name my-first-queue --profile admin

此命令將建立一個名為my-first-queue的SQS佇列。

使用CloudFormation建立SQS佇列

我們也可以使用CloudFormation範本來建立SQS佇列。以下是一個範例範本:

Resources:
  SQSQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: my-first-sqs-queue-cf

Output:
  SQSQueueURL:
    Value: !Ref SQSQueue
    Export:
      Name: "SQSQueueURL"
  SQSQueueArn:
    Value: !GetAtt SQSQueue.Arn
    Export:
      Name: "SQSQueueArn"

這個範本定義了一個名為SQSQueue的SQS佇列,並輸出佇列的URL和ARN。

傳送和接收訊息

我們可以使用AWS CLI來傳送和接收訊息到SQS佇列。以下是範例命令:

aws sqs send-message --queue-url https://queue.amazonaws.com/<account id>/my-first-queue --message-body 'This is a test message' --profile admin

aws sqs receive-message --queue-url https://queue.amazonaws.com/<account id>/my-first-queue --profile admin

第一個命令將傳送一條訊息到SQS佇列,第二個命令將接收佇列中的訊息。

訊息屬性

當我們傳送和接收訊息時,AWS CLI將傳回一些屬性,例如:

  • MessageId:訊息的ID
  • MD5ofBody:訊息內容的MD5摘要,用於驗證訊息是否正確傳輸
  • ReceiptHandle:接收訊息時傳回的控制程式碼,用於刪除訊息

更多資訊

SQS佇列有多個屬性可以設定,例如:

  • ContentBasedDeduplication:布林值,用於啟用或停用內容重複刪除
  • DelaySeconds:整數,用於設定訊息延遲時間
  • FifoQueue:布林值,用於啟用或停用FIFO佇列

使用Java SDK建立SQS佇列和傳送訊息

我們可以使用Java SDK來建立SQS佇列和傳送訊息。以下是一個範例程式碼:

// 建立SQS客戶端
AmazonSQS sqsClient = AmazonSQSClientBuilder.standard().build();

// 建立佇列
CreateQueueResult createResult = sqsClient.createQueue("my-queue");
String queueUrl = createResult.getQueueUrl();

// 傳送訊息
SendMessageRequest sendMessageRequest = new SendMessageRequest()
    .withQueueUrl(queueUrl)
    .withMessageBody("This is a test message")
    .withDelaySeconds(5);
sqsClient.sendMessage(sendMessageRequest);

程式碼解析:

  1. 建立SQS客戶端:使用AmazonSQSClientBuilder來建立一個SQS客戶端。
  2. 建立佇列:使用sqsClient.createQueue方法來建立一個名為my-queue的SQS佇列,並取得佇列的URL。
  3. 傳送訊息:使用sqsClient.sendMessage方法來傳送一條訊息到SQS佇列,設定訊息內容和延遲時間。

使用Lambda函式處理SQS訊息

我們可以建立一個Lambda函式來處理SQS訊息。以下是一個範例程式碼:

// 定義Lambda函式處理器
public class SqsHandler implements RequestHandler<SQSEvent, String> {
    @Override
    public String handleRequest(SQSEvent event, Context context) {
        // 處理SQS訊息
        for (SQSEvent.SQSMessage message : event.getRecords()) {
            System.out.println("Received message: " + message.getBody());
        }
        return "Processed " + event.getRecords().size() + " messages";
    }
}

程式碼解析:

  1. 定義Lambda函式處理器:實作RequestHandler介面來處理SQS事件。
  2. 處理SQS訊息:在handleRequest方法中,遍歷SQS事件中的訊息並進行處理。

使用 SQS 和 SNS 進行訊息傳遞與通知(第 6 章)

Lambda 與 SQS SDK 的建立與訊息傳送

LambdaSqsSdkCreateSendHandler.java 中,我們初始化 SQS 客戶端並將其傳遞給服務類別。

SQS 客戶端的初始化

private final AmazonSQS sqsClient;

public LambdaSqsSdkCreateSendHandler() {
    this.sqsClient = AmazonSQSClientBuilder.standard()
            .withRegion(System.getenv("AWS_REGION"))
            .build();
}

呼叫服務方法

public Response handleRequest(final Request request, final Context context) {
    final SqsService sqsService = new SqsServiceImpl(this.sqsClient);
    return sqsService.createQueueAndSendMessage(request, context.getLogger());
}

使用 AWS CLI 佈署和測試 Lambda

  1. 編譯並封裝 Lambda 專案:執行 mvn clean package 以建立 Uber JAR。
  2. 上傳 Uber JAR 至 S3

aws s3 cp target/lambda-sqs-sdk-create-send-0.0.1-SNAPSHOT.jar s3://serverless-cookbook/lambda-sqs-sdk-create-send-0.0.1-SNAPSHOT.jar –profile admin


3. **建立 Lambda 執行角色**:
   ```bash
aws iam create-role --role-name lambda-sqs-create-send-role --assume-role-policy-document file://iam-role-trust-relationship.txt --profile admin

iam-role-trust-relationship.txt 的內容如下:

{
 "Version": "2012-10-17",
 "Statement": [
     {
         "Effect": "Allow",
         "Principal": {
             "Service": "lambda.amazonaws.com"
         },
         "Action": "sts:AssumeRole"
     }
 ]
}
  1. 建立基本日誌許可權政策並附加至角色

aws iam create-policy –policy-name lambda-basic-iam-policy –policy-document file://basic-lambda-permissions.txt –profile admin aws iam attach-role-policy –role-name lambda-sqs-create-send-role –policy-arn arn:aws:iam::855923912133:policy/lambda-basic-iam-policy –profile admin


   `basic-lambda-permissions.txt` 的內容如下:
   ```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:*:*:*"
            ]
        }
    ]
}
  1. 建立 SQS 許可權政策並附加至角色: 建立 lambda-sqs-create-send-permissions.txt,內容如下:

{ “Version”: “2012-10-17”, “Statement”: [ { “Effect”: “Allow”, “Action”: [ “sqs:CreateQueue”, “sqs:GetQueueUrl”, “sqs:SendMessage” ], “Resource”: [ “arn:aws:sqs:::*” ] } ] }


   ```bash
aws iam create-policy --policy-name lambda-sqs-create-send-policy --policy-document file://lambda-sqs-create-send-permissions.txt --profile admin
aws iam attach-role-policy --role-name lambda-sqs-create-send-role --policy-arn arn:aws:iam::855923912133:policy/lambda-sqs-create-send-policy --profile admin
  1. 建立 Lambda 函式

aws lambda create-function –function-name lambda-sqs-create-send –runtime java8 –role arn:aws:iam:::role/lambda-sqs-create-send-role –handler tech.heartin.books.serverlesscookbook.LambdaSqsSdkCreateSendHandler::handleRequest –code S3Bucket=serverless-cookbook,S3Key=lambda-sqs-sdk-create-send-0.0.1-SNAPSHOT.jar –timeout 15 –memory-size 512 –region us-east-1 –profile admin


7. **呼叫 Lambda 函式**:
   ```bash
aws lambda invoke --invocation-type RequestResponse --function-name lambda-sqs-create-send --log-type Tail --payload file://payload.json --region us-east-1 --profile admin outputfile.txt

payload.json 的內容如下:

{
 "queueName": "create-send-demo-queue",
 "message": "test payload 1"
}
  1. 驗證訊息是否已傳送至佇列

aws sqs receive-message –queue-url https://queue.amazonaws.com/855923912133/create-send-demo-queue –profile admin


#### 內容解密:
此段落主要說明如何使用 AWS CLI 佈署和測試 Lambda 函式。透過一系列的指令,建立 Lambda 執行角色、設定許可權、建立 Lambda 函式並呼叫它,最後驗證訊息是否成功傳送至 SQS 佇列。

### 使用 SDK(Java)批次接收和傳送 SQS 訊息

#### Lambda 專案程式碼(Java)
此範例將建立一個 Lambda 函式,用於從一個 SQS 佇列接收訊息,將這些訊息批次傳送到另一個 SQS 佇列,並刪除原始佇列中的訊息。

#### Maven 相依性設定
```xml
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-sqs</artifactId>
    <version>${aws.sdk.version}</version>
</dependency>

內容解密:

此部分主要介紹如何使用 Java SDK 在 Lambda 中操作 SQS,包括接收、傳送和刪除訊息。透過 Maven 相依性設定引入必要的 AWS SDK,以支援 SQS 操作。