選取您的 Cookie 偏好設定

我們使用提供自身網站和服務所需的基本 Cookie 和類似工具。我們使用效能 Cookie 收集匿名統計資料,以便了解客戶如何使用我們的網站並進行改進。基本 Cookie 無法停用,但可以按一下「自訂」或「拒絕」以拒絕效能 Cookie。

如果您同意,AWS 與經核准的第三方也會使用 Cookie 提供實用的網站功能、記住您的偏好設定,並顯示相關內容,包括相關廣告。若要接受或拒絕所有非必要 Cookie,請按一下「接受」或「拒絕」。若要進行更詳細的選擇,請按一下「自訂」。

教學課程: AWS Lambda 搭配 Amazon Simple Notification Service 使用

焦點模式
教學課程: AWS Lambda 搭配 Amazon Simple Notification Service 使用 - AWS Lambda

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

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

在本教學課程中,您會在其中一個中使用 Lambda 函數 AWS 帳戶 ,以個別方式訂閱 Amazon Simple Notification Service (Amazon SNS) 主題 AWS 帳戶。將訊息發佈至 Amazon SNS 主題時,Lambda 函數會讀取訊息的內容,並將其輸出到 Amazon CloudWatch Logs。若要完成本教學課程,請使用 AWS Command Line Interface (AWS CLI)。

連線至 Lambda 函數 (連線至 CloudWatch Logs 日誌群組) 的 Amazon SNS 主題

請執行下列步驟以完成本教學課程:

  • 帳戶 A 中建立 Amazon SNS 主題。

  • 帳戶 B 中建立 Lambda 函數,以讀取主題的訊息。

  • 帳戶 B 中建立主題的訂閱。

  • 將訊息發佈至帳戶 A 中的 Amazon SNS 主題,並確認帳戶 B 中的 Lambda 函數是否有將其輸出至 CloudWatch Logs。

完成這些步驟後,您將了解如何設定 Amazon SNS 主題來調用 Lambda 函數。您也將了解如何建立 AWS Identity and Access Management (IAM) 政策,以授予另一個 中資源呼叫 Lambda AWS 帳戶 的許可。

在此教學課程中,您會使用兩種獨立的  AWS 帳戶。這些 AWS CLI 命令使用兩個名為 accountA和 的設定檔來說明這一點accountB,每個設定檔都設定為與不同的 搭配使用 AWS 帳戶。若要了解如何將 AWS CLI 設定為使用不同的設定檔,請參閱《 第 AWS Command Line Interface 2 版使用者指南》中的組態和登入資料檔案設定。請務必 AWS 區域 為兩個設定檔設定相同的預設值。

如果您為這兩個設定檔建立的 AWS CLI 設定檔 AWS 帳戶 使用不同的名稱,或者您使用預設設定檔和一個具名設定檔,請視需要在下列步驟中修改 AWS CLI 命令。

先決條件

如果您尚未安裝 AWS Command Line Interface,請依照安裝或更新最新版本 AWS CLI中的步驟進行安裝。

本教學課程需使用命令列終端機或 Shell 來執行命令。在 Linux 和 macOS 中,使用您偏好的 Shell 和套件管理工具。

注意

在 Windows 中,作業系統的內建終端不支援您常與 Lambda 搭配使用的某些 Bash CLI 命令 (例如 zip)。若要取得 Ubuntu 和 Bash 的 Windows 整合版本,請安裝適用於 Linux 的 Windows 子系統

如果您尚未安裝 AWS Command Line Interface,請依照安裝或更新最新版本 AWS CLI中的步驟進行安裝。

本教學課程需使用命令列終端機或 Shell 來執行命令。在 Linux 和 macOS 中,使用您偏好的 Shell 和套件管理工具。

注意

在 Windows 中,作業系統的內建終端不支援您常與 Lambda 搭配使用的某些 Bash CLI 命令 (例如 zip)。若要取得 Ubuntu 和 Bash 的 Windows 整合版本,請安裝適用於 Linux 的 Windows 子系統

建立 Amazon SNS 主題 (帳戶 A)

第一步:建立 Amazon SNS 主題
若要建立 主題
  • 帳戶 A 中,使用以下 AWS CLI 命令建立 Amazon SNS 標準主題。

    aws sns create-topic --name sns-topic-for-lambda --profile accountA

    您應該會看到類似下列的輸出。

    { "TopicArn": "arn:aws:sns:us-west-2:123456789012:sns-topic-for-lambda" }

    記下主題的 Amazon Resource Name (ARN)。當您新增許可到 Lambda 函數以訂閱主題時,稍後會在教學課程中用上它。

建立函數執行角色 (帳戶 B)

下一步:建立執行角色

執行角色是 IAM 角色,授予 Lambda 函數存取 AWS 服務 和資源的許可。在帳戶 B 建立函數前,您必須建立一個角色,該角色會授與將日誌寫入 CloudWatch Logs 的函數基本許可。我們將在稍後的步驟中新增要從 Amazon SNS 主題讀取的許可。

若要建立執行角色
  1. 帳戶 B 中開啟 IAM 主控台的角色頁面

  2. 選擇建立角色

  3. 針對信任的實體類型,請選擇 AWS 服務

  4. 針對使用案例,請選擇 Lambda

  5. 選擇 Next (下一步)

  6. 透過下列步驟將基本許可政策新增至角色:

    1. 許可政策搜尋方塊中,輸入 AWSLambdaBasicExecutionRole

    2. 選擇 Next (下一步)

  7. 執行下列動作來完成角色的建立:

    1. 角色詳細資訊下方的角色名稱中輸入 lambda-sns-role

    2. 選擇建立角色

建立 Lambda 函數 (帳戶 B)

下一步:建立函數

建立可處理 Amazon SQS 訊息的 Lambda 函數。函數程式碼會將每筆記錄的訊息內容記錄到 Amazon CloudWatch Logs。

本教學課程使用 Node.js 18.x 執行期,但我們也有提供其他執行期語言的範例程式碼。您可以在下列方塊中選取索引標籤,查看您感興趣的執行期程式碼。此步驟要使用的 JavaScript 程式碼,位於 JavaScript 索引標籤中顯示的第一個範例。

.NET
SDK for .NET
注意

GitHub 上提供更多範例。尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 .NET 搭配 Lambda 來使用 SNS 事件。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 using Amazon.Lambda.Core; using Amazon.Lambda.SNSEvents; // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] namespace SnsIntegration; public class Function { public async Task FunctionHandler(SNSEvent evnt, ILambdaContext context) { foreach (var record in evnt.Records) { await ProcessRecordAsync(record, context); } context.Logger.LogInformation("done"); } private async Task ProcessRecordAsync(SNSEvent.SNSRecord record, ILambdaContext context) { try { context.Logger.LogInformation($"Processed record {record.Sns.Message}"); // TODO: Do interesting work based on the new message await Task.CompletedTask; } catch (Exception e) { //You can use Dead Letter Queue to handle failures. By configuring a Lambda DLQ. context.Logger.LogError($"An error occurred"); throw; } } }
Go
SDK for Go V2
注意

GitHub 上提供更多範例。尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 Go 搭配 Lambda 來使用 SNS 事件。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package main import ( "context" "fmt" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ) func handler(ctx context.Context, snsEvent events.SNSEvent) { for _, record := range snsEvent.Records { processMessage(record) } fmt.Println("done") } func processMessage(record events.SNSEventRecord) { message := record.SNS.Message fmt.Printf("Processed message: %s\n", message) // TODO: Process your record here } func main() { lambda.Start(handler) }
Java
SDK for Java 2.x
注意

GitHub 上提供更多範例。尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 Java 搭配 Lambda 來使用 SNS 事件。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package example; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.LambdaLogger; import com.amazonaws.services.lambda.runtime.RequestHandler; import com.amazonaws.services.lambda.runtime.events.SNSEvent; import com.amazonaws.services.lambda.runtime.events.SNSEvent.SNSRecord; import java.util.Iterator; import java.util.List; public class SNSEventHandler implements RequestHandler<SNSEvent, Boolean> { LambdaLogger logger; @Override public Boolean handleRequest(SNSEvent event, Context context) { logger = context.getLogger(); List<SNSRecord> records = event.getRecords(); if (!records.isEmpty()) { Iterator<SNSRecord> recordsIter = records.iterator(); while (recordsIter.hasNext()) { processRecord(recordsIter.next()); } } return Boolean.TRUE; } public void processRecord(SNSRecord record) { try { String message = record.getSNS().getMessage(); logger.log("message: " + message); } catch (Exception e) { throw new RuntimeException(e); } } }
JavaScript
SDK for JavaScript (v3)
注意

GitHub 上提供更多範例。尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 JavaScript 搭配 Lambda 來使用 SNS 事件。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 exports.handler = async (event, context) => { for (const record of event.Records) { await processMessageAsync(record); } console.info("done"); }; async function processMessageAsync(record) { try { const message = JSON.stringify(record.Sns.Message); console.log(`Processed message ${message}`); await Promise.resolve(1); //Placeholder for actual async work } catch (err) { console.error("An error occurred"); throw err; } }

使用 TypeScript 搭配 Lambda 來使用 SNS 事件。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { SNSEvent, Context, SNSHandler, SNSEventRecord } from "aws-lambda"; export const functionHandler: SNSHandler = async ( event: SNSEvent, context: Context ): Promise<void> => { for (const record of event.Records) { await processMessageAsync(record); } console.info("done"); }; async function processMessageAsync(record: SNSEventRecord): Promise<any> { try { const message: string = JSON.stringify(record.Sns.Message); console.log(`Processed message ${message}`); await Promise.resolve(1); //Placeholder for actual async work } catch (err) { console.error("An error occurred"); throw err; } }
PHP
SDK for PHP
注意

GitHub 上提供更多範例。尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 PHP 搭配 Lambda 來使用 SNS 事件。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 <?php /* Since native PHP support for AWS Lambda is not available, we are utilizing Bref's PHP functions runtime for AWS Lambda. For more information on Bref's PHP runtime for Lambda, refer to: https://bref.sh/docs/runtimes/function Another approach would be to create a custom runtime. A practical example can be found here: https://aws.amazon.com/blogs/apn/aws-lambda-custom-runtime-for-php-a-practical-example/ */ // Additional composer packages may be required when using Bref or any other PHP functions runtime. // require __DIR__ . '/vendor/autoload.php'; use Bref\Context\Context; use Bref\Event\Sns\SnsEvent; use Bref\Event\Sns\SnsHandler; class Handler extends SnsHandler { public function handleSns(SnsEvent $event, Context $context): void { foreach ($event->getRecords() as $record) { $message = $record->getMessage(); // TODO: Implement your custom processing logic here // Any exception thrown will be logged and the invocation will be marked as failed echo "Processed Message: $message" . PHP_EOL; } } } return new Handler();
Python
SDK for Python (Boto3)
注意

GitHub 上提供更多範例。尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 Python 搭配 Lambda 來使用 SNS 事件。

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 def lambda_handler(event, context): for record in event['Records']: process_message(record) print("done") def process_message(record): try: message = record['Sns']['Message'] print(f"Processed message {message}") # TODO; Process your record here except Exception as e: print("An error occurred") raise e
Ruby
SDK for Ruby
注意

GitHub 上提供更多範例。尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 Ruby 搭配 Lambda 來使用 SNS 事件。

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 def lambda_handler(event:, context:) event['Records'].map { |record| process_message(record) } end def process_message(record) message = record['Sns']['Message'] puts("Processing message: #{message}") rescue StandardError => e puts("Error processing message: #{e}") raise end
Rust
SDK for Rust
注意

GitHub 上提供更多範例。尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 Rust 搭配 Lambda 來使用 SNS 事件。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 use aws_lambda_events::event::sns::SnsEvent; use aws_lambda_events::sns::SnsRecord; use lambda_runtime::{run, service_fn, Error, LambdaEvent}; use tracing::info; // Built with the following dependencies: // aws_lambda_events = { version = "0.10.0", default-features = false, features = ["sns"] } // lambda_runtime = "0.8.1" // tokio = { version = "1", features = ["macros"] } // tracing = { version = "0.1", features = ["log"] } // tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt"] } async fn function_handler(event: LambdaEvent<SnsEvent>) -> Result<(), Error> { for event in event.payload.records { process_record(&event)?; } Ok(()) } fn process_record(record: &SnsRecord) -> Result<(), Error> { info!("Processing SNS Message: {}", record.sns.message); // Implement your record handling code here. Ok(()) } #[tokio::main] async fn main() -> Result<(), Error> { tracing_subscriber::fmt() .with_max_level(tracing::Level::INFO) .with_target(false) .without_time() .init(); run(service_fn(function_handler)).await }
SDK for .NET
注意

GitHub 上提供更多範例。尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 .NET 搭配 Lambda 來使用 SNS 事件。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 using Amazon.Lambda.Core; using Amazon.Lambda.SNSEvents; // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] namespace SnsIntegration; public class Function { public async Task FunctionHandler(SNSEvent evnt, ILambdaContext context) { foreach (var record in evnt.Records) { await ProcessRecordAsync(record, context); } context.Logger.LogInformation("done"); } private async Task ProcessRecordAsync(SNSEvent.SNSRecord record, ILambdaContext context) { try { context.Logger.LogInformation($"Processed record {record.Sns.Message}"); // TODO: Do interesting work based on the new message await Task.CompletedTask; } catch (Exception e) { //You can use Dead Letter Queue to handle failures. By configuring a Lambda DLQ. context.Logger.LogError($"An error occurred"); throw; } } }
建立函數
  1. 建立專案的目錄,然後切換至該目錄。

    mkdir sns-tutorial cd sns-tutorial
  2. 將範例 JavaScript 程式碼複製到名為 index.js 的新檔案。

  3. 使用以下 zip 命令建立部署套件。

    zip function.zip index.js
  4. 執行下列 AWS CLI 命令,在帳戶 B 中建立您的 Lambda 函數。

    aws lambda create-function --function-name Function-With-SNS \ --zip-file fileb://function.zip --handler index.handler --runtime nodejs18.x \ --role arn:aws:iam::<AccountB_ID>:role/lambda-sns-role \ --timeout 60 --profile accountB

    您應該會看到類似下列的輸出。

    { "FunctionName": "Function-With-SNS", "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:Function-With-SNS", "Runtime": "nodejs18.x", "Role": "arn:aws:iam::123456789012:role/lambda_basic_role", "Handler": "index.handler", ... "RuntimeVersionConfig": { "RuntimeVersionArn": "arn:aws:lambda:us-west-2::runtime:7d5f06b69c951da8a48b926ce280a9daf2e8bb1a74fc4a2672580c787d608206" } }
  5. 記錄函數的 Amazon Resource Name (ARN)。當您新增許可以允許 Amazon SNS 調用您的函數時,稍後會在教學課程中用上它。

為函數新增許可 (帳戶 B)

下一步:新增許可至函數

若要使用 Amazon SNS 調用函數,您必須在以資源為基礎之政策的陳述式中授予許可。您可以使用 命令新增此陳述式 AWS CLI add-permission

若要授予 Amazon SNS 調用您函數的許可
  • 帳戶 B 中,針對您先前記錄的 Amazon SNS 主題,使用 ARN 執行下列 AWS CLI 命令。

    aws lambda add-permission --function-name Function-With-SNS \ --source-arn arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda \ --statement-id function-with-sns --action "lambda:InvokeFunction" \ --principal sns.amazonaws.com --profile accountB

    您應該會看到類似下列的輸出。

    { "Statement": "{\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\": \"arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda\"}}, \"Action\":[\"lambda:InvokeFunction\"], \"Resource\":\"arn:aws:lambda:us-east-1:<AccountB_ID>:function:Function-With-SNS\", \"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sns.amazonaws.com\"}, \"Sid\":\"function-with-sns\"}" }
注意

如果具有 Amazon SNS 主題的帳戶託管在選擇加入 AWS 區域中,您需要在主體中指定區域。例如,如果您使用亞太區域 (香港)的 Amazon SNS 主題,則需要為主體指定 sns.ap-east-1.amazonaws.com,而不是 sns.amazonaws.com

授予 Amazon SNS 訂閱的跨帳戶許可 (帳戶 A)

下一步:授予跨帳戶許可

若要讓帳戶 B 中的 Lambda 函數訂閱您在帳戶 A 中建立的 Amazon SNS 主題,您必須向帳戶 B 授予訂閱您主題的許可。您可以使用 AWS CLI add-permission命令授予此許可。

若要向帳戶 B 授予訂閱主題的許可
  • 帳戶 A 中,執行下列 AWS CLI 命令。將 ARN 用於之前記錄的 Amazon SNS 主題。

    aws sns add-permission --label lambda-access --aws-account-id <AccountB_ID> \ --topic-arn arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda \ --action-name Subscribe ListSubscriptionsByTopic --profile accountA

建立訂閱 (帳戶 B)

下一步:建立訂閱

帳戶 B 中,您現在讓 Lambda 函數訂閱您在教學課程開始時透過帳戶 A 建立的 Amazon SNS 主題。當訊息傳送至此主題 (sns-topic-for-lambda) 時,Amazon SNS 會調用您帳戶 B 中的 Lambda 函數 Function-With-SNS

若要建立訂閱
  • 帳戶 B 中,執行下列 AWS CLI 命令。使用您建立主題的預設區域,以及主題和 Lambda 函數的 ARN。

    aws sns subscribe --protocol lambda \ --region us-east-1 \ --topic-arn arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda \ --notification-endpoint arn:aws:lambda:us-east-1:<AccountB_ID>:function:Function-With-SNS \ --profile accountB

    您應該會看到類似下列的輸出。

    { "SubscriptionArn": "arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda:5d906xxxx-7c8x-45dx-a9dx-0484e31c98xx" }

將訊息發佈至主題 (帳戶 A 和帳戶 B)

下一步:發布訊息

帳戶 B 中的 Lambda 函數已訂閱您帳戶 A 中的 Amazon SNS 主題後,是時候將訊息發佈至您的主題來測試您的設定了。若要確認 Amazon SNS 是否已調用 Lambda 函數,請使用 CloudWatch Logs 來檢視函數的輸出。

若要將訊息發佈到您的主題並檢視函數的輸出
  1. 輸入 Hello World 至文字檔,並儲存為 message.txt

  2. 從您儲存文字檔案所在的相同目錄中,在帳戶 A 中執行下列 AWS CLI 命令。 針對您自己的主題使用 ARN。

    aws sns publish --message file://message.txt --subject Test \ --topic-arn arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda \ --profile accountA

    這將傳回具有唯一識別符的訊息 ID,表示 Amazon SNS 已接受訊息。接著,Amazon SNS 會嘗試將訊息傳遞給主題訂閱者。若要確認 Amazon SNS 是否已調用 Lambda 函數,請使用 CloudWatch Logs 來檢視函數的輸出:

  3. 帳戶 B中開啟 Amazon CloudWatch 主控台的日誌群組頁面。

  4. 為函數 (/aws/lambda/Function-With-SNS) 選擇日誌群組名稱。

  5. 選擇最新的日誌串流。

  6. 如果您的函數有被正確調用,您將會看到類似下方的輸出,顯示您發佈到主題的訊息內容。

    2023-07-31T21:42:51.250Z c1cba6b8-ade9-4380-aa32-d1a225da0e48 INFO Processed message Hello World 2023-07-31T21:42:51.250Z c1cba6b8-ade9-4380-aa32-d1a225da0e48 INFO done

清除您的資源

除非您想要保留為此教學課程建立的資源,否則您現在便可刪除。透過刪除不再使用 AWS 的資源,您可以避免不必要的費用 AWS 帳戶。

帳戶 A 中,清除您的 Amazon SNS 主題。

刪除 Amazon SNS 主題
  1. 在 Amazon SNS 主控台開啟 Topics (主題) 頁面

  2. 選擇您建立的主題。

  3. 選擇 刪除

  4. 在文字輸入欄位中輸入 delete me

  5. 選擇 刪除

帳戶 B 中,清除您的執行角色、Lambda 函數以及 Amazon SNS 訂閱。

刪除執行角色
  1. 開啟 IAM 主控台中的 角色頁面

  2. 選取您建立的執行角色。

  3. 選擇刪除

  4. 在文字輸入欄位中輸入角色的名稱,然後選擇 刪除

若要刪除 Lambda 函數
  1. 開啟 Lambda 主控台中的 函數頁面

  2. 選擇您建立的函數。

  3. 選擇 Actions (動作)、Delete (刪除)。

  4. 在文字輸入欄位中輸入 confirm,然後選擇 刪除

刪除 Amazon SNS 訂閱
  1. 在 Amazon SNS 主控台開啟 Subscriptions (訂閱) 頁面

  2. 選取您建立的訂閱。

  3. 選擇刪除刪除

下一個主題:

Lambda 許可

上一個主題:

SNS
隱私權網站條款Cookie 偏好設定
© 2025, Amazon Web Services, Inc.或其附屬公司。保留所有權利。