

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

# 使用 Go 建置 Lambda 函數
<a name="lambda-golang"></a>

Go 的實作方式與其他受管執行期不同。由於 Go 程式碼原生編譯至可執行的二進位檔，因此不需要專用語言執行時期。應使用[僅限作業系統的執行時期](runtimes-provided.md) (`provided` 執行時期系列) 將 Go 函數部署至 Lambda。

**Topics**
+ [

## Go 執行期支援
](#golang-al1)
+ [

## 工具與程式庫
](#golang-libraries)
+ [

# 定義 Go 格式的 Lambda 函數處理常式
](golang-handler.md)
+ [

# 使用 Lambda 內容物件擷取 Go 函數資訊
](golang-context.md)
+ [

# 使用 .zip 封存檔部署 Go Lambda 函數
](golang-package.md)
+ [

# 使用容器映像來部署 Go Lambda 函數
](go-image.md)
+ [

# 使用 Go Lambda 函數的層
](golang-layers.md)
+ [

# 記錄和監控 Go Lambda 函數
](golang-logging.md)
+ [

# 在 中檢測 Go 程式碼 AWS Lambda
](golang-tracing.md)

## Go 執行期支援
<a name="golang-al1"></a>

Lambda 的 Go 1.x 受管執行時期已[棄用](lambda-runtimes.md#runtime-support-policy)。如果擁有使用 Go 1.x 執行時期的函數，則必須將函數遷移至 `provided.al2023` 或 `provided.al2`。`provided.al2023` 與 相比， 和 `provided.al2`執行時間提供多種優勢`go1.x`，包括支援 arm64 架構 (AWS Graviton2 處理器）、較小的二進位檔，以及稍快的調用時間。

本次遷移不需要變更任何程式碼。唯一必須做出的變更與建置部署套件的方式以及用來建立函數的執行期有關。如需詳細資訊，請參閱*AWS 運算部落格*上的[將 AWS Lambda 函數從 Go1.x 執行時間遷移至 Amazon Linux 2 上的自訂執行時間。](https://aws.amazon.com/blogs/compute/migrating-aws-lambda-functions-from-the-go1-x-runtime-to-the-custom-runtime-on-amazon-linux-2/)


| Name | 識別符 | 作業系統 | 取代日期 | 封鎖函數建立 | 封鎖函數更新 | 
| --- | --- | --- | --- | --- | --- | 
|  僅限作業系統的執行期  |  `provided.al2023`  |  Amazon Linux 2023  |   2029 年 6 月 30 日   |   2029 年 7 月 31 日   |   2029 年 8 月 31 日   | 
|  僅限作業系統的執行期  |  `provided.al2`  |  Amazon Linux 2  |   2026 年 7 月 31 日   |   2026 年 8 月 31 日   |   2026 年 9 月 30 日   | 

## 工具與程式庫
<a name="golang-libraries"></a>

Lambda 為 Go 執行時間提供以下工具和程式庫：
+ [適用於 Go 的 AWS SDK v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2)：適用於 Go 程式設計語言的官方 AWS SDK。
+ [github.com/aws/aws-lambda-go/lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda)：針對 Go 實作 Lambda 程式設計模型。此套件由 AWS Lambda 用來叫用您的[處理常式](golang-handler.md)。
+ [github.com/aws/aws-lambda-go/lambdacontext](https://github.com/aws/aws-lambda-go/tree/master/lambdacontext)：從[內容物件](golang-context.md)取得內容資訊的輔助工具。
+ [github.com/aws/aws-lambda-go/events](https://github.com/aws/aws-lambda-go/tree/master/events)：此程式庫提供常用事件來源整合的類型定義。
+ [github.com/aws/aws-lambda-go/cmd/build-lambda-zip](https://github.com/aws/aws-lambda-go/tree/master/cmd/build-lambda-zip)：這個工具可以用來在 Windows 上建立 .zip 檔案封存。

如需詳細資訊，請參閱 GitHub 上的 [aws-lambda-go](https://github.com/aws/aws-lambda-go)

Lambda 為 Go 執行時間提供下列範例應用程式：

**以 Go 編寫的範例 Lambda 應用程式**
+ [go-al2](https://github.com/aws-samples/sessions-with-aws-sam/tree/master/go-al2)：傳回公有 IP 地址的「hello world」函數。此應用程式使用 `provided.al2` 自訂執行期。
+ [blank-go](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-go) – Go 函數，顯示 Lambda Go 程式庫、記錄、環境變數和 AWS SDK 的使用方式。此應用程式使用 `go1.x` 執行期。

# 定義 Go 格式的 Lambda 函數處理常式
<a name="golang-handler"></a>

Lambda 函數*處理常式*是您的函數程式碼中處理事件的方法。當有人呼叫您的函數時，Lambda 會執行處理常式方法。函數會執行，直到處理常式傳回回應、結束或逾時為止。

此頁面說明如何使用 Go 處理 Lambda 函數處理常式，包括專案設定、命名慣例和最佳實務。本頁還提供了一個 Go Lambda 函式範例，該函式會取得訂單的相關資訊、產生文字檔案收據，並將該檔案放入 Amazon Simple Storage Service (Amazon S3) 儲存貯體。如需編寫函數後如何部署函數的詳細資訊，請參閱[使用 .zip 封存檔部署 Go Lambda 函數](golang-package.md)或[使用容器映像來部署 Go Lambda 函數](go-image.md)。

**Topics**
+ [

## 設定 Go 處理常式專案
](#golang-handler-setup)
+ [

## 範例 Go Lambda 函數程式碼
](#golang-example-code)
+ [

## 處理常式命名慣例
](#golang-handler-naming)
+ [

## 定義和存取輸入事件物件
](#golang-example-input)
+ [

## 存取和使用 Lambda 內容物件
](#golang-example-context)
+ [

## Go 處理常式的有效處理常式簽章
](#golang-handler-signatures)
+ [

## 在處理常式中使用 適用於 Go 的 AWS SDK v2
](#golang-example-sdk-usage)
+ [

## 存取環境變數
](#golang-example-envvars)
+ [

## 使用全域狀態
](#golang-handler-state)
+ [

## Go Lambda 函數的程式碼最佳實務
](#go-best-practices)

## 設定 Go 處理常式專案
<a name="golang-handler-setup"></a>

以 [Go](https://golang.org/) 撰寫的 Lambda 函數被製作成 Go 可執行檔。與初始化任何其他 Go 專案相同，您可以使用以下 `go mod init` 命令初始化一個 Go Lambda 函數專案：

```
go mod init example-go
```

此處 `example-go` 是模組名稱。您可以將其取代為任何值。此命令會初始化專案，並產生列有專案相依項的 `go.mod` 檔案。

使用 `go get` 命令將任何外部相依項新增至專案。例如，對於以 Go 編寫的所有 Lambda 函數程式碼，您需要納入 [github.com/aws/aws-lambda-go/lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) 套件，它可針對 Go 實作 Lambda 程式設計模型。使用以下 `go get` 命令納入此套件：

```
go get github.com/aws/aws-lambda-go
```

函數程式碼應該存在於 Go 檔案中。在以下範例中，我們將此檔案命名為 `main.go`。在此檔案中，您會在處理常式方法中實作核心函數邏輯，以及呼叫此處理常式的 `main()` 函數。

## 範例 Go Lambda 函數程式碼
<a name="golang-example-code"></a>

以下範例 Go Lambda 函數程式碼會取得訂單的相關資訊、產生文字檔案收據，並將此檔案放入 Amazon S3 儲存貯體。

**Example `main.go` Lambda 函數**  

```
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/aws/aws-lambda-go/lambda"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/s3"
)

type Order struct {
	OrderID string  `json:"order_id"`
	Amount  float64 `json:"amount"`
	Item    string  `json:"item"`
}

var (
	s3Client *s3.Client
)

func init() {
	// Initialize the S3 client outside of the handler, during the init phase
	cfg, err := config.LoadDefaultConfig(context.TODO())
	if err != nil {
		log.Fatalf("unable to load SDK config, %v", err)
	}

	s3Client = s3.NewFromConfig(cfg)
}

func uploadReceiptToS3(ctx context.Context, bucketName, key, receiptContent string) error {
	_, err := s3Client.PutObject(ctx, &s3.PutObjectInput{
		Bucket: &bucketName,
		Key:    &key,
		Body:   strings.NewReader(receiptContent),
	})
	if err != nil {
		log.Printf("Failed to upload receipt to S3: %v", err)
		return err
	}
	return nil
}

func handleRequest(ctx context.Context, event json.RawMessage) error {
	// Parse the input event
	var order Order
	if err := json.Unmarshal(event, &order); err != nil {
		log.Printf("Failed to unmarshal event: %v", err)
		return err
	}

	// Access environment variables
	bucketName := os.Getenv("RECEIPT_BUCKET")
	if bucketName == "" {
		log.Printf("RECEIPT_BUCKET environment variable is not set")
		return fmt.Errorf("missing required environment variable RECEIPT_BUCKET")
	}

	// Create the receipt content and key destination
	receiptContent := fmt.Sprintf("OrderID: %s\nAmount: $%.2f\nItem: %s",
		order.OrderID, order.Amount, order.Item)
	key := "receipts/" + order.OrderID + ".txt"

	// Upload the receipt to S3 using the helper method
	if err := uploadReceiptToS3(ctx, bucketName, key, receiptContent); err != nil {
		return err
	}

	log.Printf("Successfully processed order %s and stored receipt in S3 bucket %s", order.OrderID, bucketName)
	return nil
}

func main() {
	lambda.Start(handleRequest)
}
```

此 `main.go` 檔案包含以下程式碼區段：
+ `package main`：在 Go 中，包含 `func main()` 函數的套件一律要命名為 `main`。
+ `import` 區塊：用於納入 Lambda 函數所需的程式碼。
+ `type Order struct {}` 區塊：定義此 Go struct 中預期輸入事件的形狀。
+ `var ()` 區塊：用於定義將在 Lambda 函數中使用的任何全域變數。
+ `func init() {}`：在此 `init()` 方法的中包含您希望 Lambda 在[初始化階段](lambda-runtime-environment.md#runtimes-lifecycle-ib)執行的任何程式碼。
+ `func uploadReceiptToS3(...) {}`：這是主要 `handleRequest` 處理常式方法所參考的協助程式方法。
+ `func handleRequest(ctx context.Context, event json.RawMessage) error {}`：這是**主要處理常式方法**，其中包含應用程式的主要邏輯。
+ `func main() {}`：這是 Lambda 處理常式的必要進入點。`lambda.Start()` 方法的引數是主要處理常式方法。

若要讓此函數正常運作，其[執行角色](lambda-intro-execution-role.md)必須允許 `s3:PutObject` 動作。此外，請確保定義 `RECEIPT_BUCKET` 環境變數。成功調用後，Amazon S3 儲存貯體應包含收據檔案。

## 處理常式命名慣例
<a name="golang-handler-naming"></a>

對於以 Go 編寫的 Lambda 函數，處理常式的命名不受限制。在此範例中，處理常式方法的名稱為 `handleRequest`。若要參考程式碼中的處理常式值，您可以使用 `_HANDLER` 環境變數。

對於使用 [.zip 部署套件](golang-package.md)部署的 Go 函數，含有函數程式碼的可執行檔必須命名為 `bootstrap`。此外，`bootstrap` 檔案必須位於 .zip 檔案的根層級。對於使用[容器映像](go-image.md#go-image-provided)部署的 Go 函數，可執行檔的名稱不受限制。

## 定義和存取輸入事件物件
<a name="golang-example-input"></a>

JSON 是 Lambda 函數最常見的標準輸入格式。在此範例中，函數預期輸入類似以下內容：

```
{
    "order_id": "12345",
    "amount": 199.99,
    "item": "Wireless Headphones"
}
```

使用以 Go 編寫的 Lambda 函數時，您可以將預期輸入事件的形狀定義為 Go struct。在此範例中，我們透過定義 struct 來代表 `Order`：

```
type Order struct {
    OrderID string  `json:"order_id"`
    Amount  float64 `json:"amount"`
    Item    string  `json:"item"`
}
```

此 struct 符合預期的輸入形狀。定義 struct 之後，可以撰寫處理常式簽章，該簽章採用與 [encoding/json standard library](https://pkg.go.dev/encoding/json) 相容的一般 JSON 類型。然後，可以使用 [func Unmarshal](https://golang.org/pkg/encoding/json/#Unmarshal) 函數將其還原序列化至該 struct。這在處理常式的前幾行中得以曾現：

```
func handleRequest(ctx context.Context, event json.RawMessage) error {
    // Parse the input event
    var order Order
    if err := json.Unmarshal(event, &order); err != nil {
        log.Printf("Failed to unmarshal event: %v", err)
        return err
    ...
}
```

在此還原序列化操作之後，您可以存取 `order` 變數的欄位。例如，使用 `"order_id"` 可以從原始輸入擷取 `order.OrderID` 的值。

**注意**  
`encoding/json` 套件只能存取匯出的欄位。若要匯出，事件結構中的欄位名稱必須大寫。

## 存取和使用 Lambda 內容物件
<a name="golang-example-context"></a>

Lambda [內容物件](golang-context.md) 包含有關調用、函數以及執行環境的資訊。在此範例中，我們在處理常式簽章中將此變數宣告為 `ctx`：

```
func handleRequest(ctx context.Context, event json.RawMessage) error {
    ...
}
```

`ctx context.Context` 輸入是函數處理常式的一個選用引數。如需可接受處理常式簽章的詳細資訊，請參閱[Go 處理常式的有效處理常式簽章](#golang-handler-signatures)。

如果您使用 AWS SDK 呼叫其他服務，則有幾個關鍵區域需要內容物件。例如，您可以使用內容物件載入正確的 AWS SDK 組態，以正確初始化 SDK 用戶端。如下所示：

```
// Load AWS SDK configuration using the default credential provider chain
    cfg, err := config.LoadDefaultConfig(ctx)
```

SDK 呼叫本身可能需要內容物件做為輸入。例如，`s3Client.PutObject` 呼叫接受內容物件做為其第一個引數：

```
// Upload the receipt to S3
    _, err = s3Client.PutObject(ctx, &s3.PutObjectInput{
        ...
    })
```

除了 AWS SDK 請求之外，您也可以將內容物件用於函數監控。如需內容物件的詳細資訊，請參閱[使用 Lambda 內容物件擷取 Go 函數資訊](golang-context.md)。

## Go 處理常式的有效處理常式簽章
<a name="golang-handler-signatures"></a>

當您以 Go 建置 Lambda 函數處理常式時，會有數個選項，但務必堅守以下規則：
+ 處理常式必須是一個函式。
+ 處理常式採用 0 到 2 之間的引數。如果有兩個引數，第一個引數必須實作 `context.Context`。
+ 處理常式傳回 0 到 2 之間的引數。若有單一傳回值，它必須實作 `error`。如果有兩個傳回值，第二個值必須實作 `error`。

下方將列出有效的處理常式簽章。`TIn` 和 `TOut` 皆代表與 *encoding/json* 標準程式庫相容的類型。如需詳細資訊，請參閱 [func Unmarshal](https://golang.org/pkg/encoding/json/#Unmarshal) 以了解這些類型如何還原序列化。
+ 

  ```
  func ()
  ```
+ 

  ```
  func () error
  ```
+ 

  ```
  func () (TOut, error)
  ```
+ 

  ```
  func (TIn) error
  ```
+ 

  ```
  func (TIn) (TOut, error)
  ```
+ 

  ```
  func (context.Context) error
  ```
+ 

  ```
  func (context.Context) (TOut, error)
  ```
+ 

  ```
  func (context.Context, TIn) error
  ```
+ 

  ```
  func (context.Context, TIn) (TOut, error)
  ```

## 在處理常式中使用 適用於 Go 的 AWS SDK v2
<a name="golang-example-sdk-usage"></a>

通常，您會使用 Lambda 函數與其他 AWS 資源互動或進行更新。與這些資源互動的最簡單方法便是使用 [適用於 Go 的 AWS SDK v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2)。

**注意**  
適用於 Go 的 AWS SDK (v1) 目前處於維護模式，並且將於 2025 年 7 月 31 日終止支援。我們建議您在之後僅使用 適用於 Go 的 AWS SDK v2。

若要將 SDK 相依項新增至函數，請針對您需要的特定 SDK 用戶端使用 `go get` 命令。在前面的範例程式碼中，我們使用了 `config` 程式庫和 `s3` 程式庫。請在包含 `go.mod` 和 `main.go ` 檔案的目錄中執行下列命令，來新增這些相依項：

```
go get github.com/aws/aws-sdk-go-v2/config
go get github.com/aws/aws-sdk-go-v2/service/s3
```

然後，在函數的 import 區塊中相應地匯入相依項：

```
import (
    ...
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)
```

在處理常式中使用 SDK 時，須對用戶端進行正確設定。最簡單的方法是使用[預設憑證提供者鏈](https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html#credentialProviderChain)。此範例說明了載入此組態的其中一種方式：

```
// Load AWS SDK configuration using the default credential provider chain
    cfg, err := config.LoadDefaultConfig(ctx)
    if err != nil {
        log.Printf("Failed to load AWS SDK config: %v", err)
        return err
    }
```

將此組態載入 `cfg` 變數後，可以將此變數傳遞至用戶端執行個體。範例程式碼會執行個體化一個 Amazon S3 用戶端，如下所示：

```
// Create an S3 client
    s3Client := s3.NewFromConfig(cfg)
```

在此範例中，我們在 `init()` 函數中初始化 Amazon S3 用戶端，以避免每次調用函數時都必須初始化它。問題是，在 `init()` 函數中，Lambda 無法存取內容物件。為解決此問題，您可以在初始化階段傳遞類似 `context.TODO()` 這樣的預留位置。稍後，當您使用用戶端進行呼叫時，再傳遞完整的內容物件。[在 AWS SDK 用戶端初始化和呼叫中使用內容](golang-context.md#golang-context-sdk)對此解決方法也有所說明。

設定並初始化 SDK 用戶端之後，您就可以使用它與其他 AWS 服務互動。此範例程式碼會呼叫 Amazon S3 `PutObject` API，如下所示：

```
_, err = s3Client.PutObject(ctx, &s3.PutObjectInput{
    Bucket: &bucketName,
    Key:    &key,
    Body:   strings.NewReader(receiptContent),
})
```

## 存取環境變數
<a name="golang-example-envvars"></a>

在處理常式程式碼中，您可以使用 `os.Getenv()` 方法參考任何[環境變數](configuration-envvars.md)。在此範例中，我們使用以下程式碼來參考定義的 `RECEIPT_BUCKET` 環境變數：

```
// Access environment variables
    bucketName := os.Getenv("RECEIPT_BUCKET")
    if bucketName == "" {
        log.Printf("RECEIPT_BUCKET environment variable is not set")
        return fmt.Errorf("missing required environment variable RECEIPT_BUCKET")
    }
```

## 使用全域狀態
<a name="golang-handler-state"></a>

為了避免每次調用函數時建立新的資源，您可以在處理常式程式碼之外宣告和修改 Lambda 函數的全域變數。您可以在 `var` 區塊或陳述式中定義這些全域變數。此外，處理常式可能會宣告在[初始化階段](lambda-runtime-environment.md#runtimes-lifecycle-ib)執行的 `init()` 函數。在 AWS Lambda 中，`init` 方法的行為與標準的 Go 程式相同。

## Go Lambda 函數的程式碼最佳實務
<a name="go-best-practices"></a>

請遵循下列清單中的準則，在建置 Lambda 函數時使用最佳編碼實務：
+ **區隔 Lambda 處理常式與您的核心邏輯。**能允許您製作更多可測單位的函式。
+ **最小化依存項目的複雜性。**偏好更簡易的框架，其可快速在[執行環境](lambda-runtime-environment.md)啟動時載入。
+ **將部署套件最小化至執行時期所必要的套件大小。**這能減少您的部署套件被下載與呼叫前解壓縮的時間。

**請利用執行環境重新使用來改看函式的效能。**在函式處理常式之外初始化 SDK 用戶端和資料庫連線，並在本機快取 `/tmp` 目錄中的靜態資產。由您函式的相同執行個體處理的後續叫用可以重複使用這些資源。這可藉由減少函數執行時間來節省成本。

若要避免叫用間洩漏潛在資料，請不要使用執行環境來儲存使用者資料、事件，或其他牽涉安全性的資訊。如果您的函式依賴無法存放在處理常式內記憶體中的可變狀態，請考慮為每個使用者建立個別函式或個別函式版本。

**使用 Keep-Alive 指令維持持續連線的狀態。**Lambda 會隨著時間的推移清除閒置連線。叫用函數時嘗試重複使用閒置連線將導致連線錯誤。若要維護持續連線，請使用與執行階段相關聯的 keep-alive (保持啟用) 指令。如需範例，請參閱[在 Node.js 中重複使用 Keep-Alive 的連線](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html)。

**使用[環境變數](configuration-envvars.md)將操作參數傳遞給您的函數。**例如，如果您正在寫入到 Amazon S3 儲存貯體，而非對您正在寫入的儲存貯體名稱進行硬式編碼，請將儲存貯體名稱設定為環境變數。

**避免在 Lambda 函數中使用遞迴調用**，其中函數會調用自己或啟動可能再次調用函數的程序。這會導致意外的函式呼叫量與升高的成本。若您看到意外的調用數量，當更新程式碼時，請立刻將函數的預留並行設為 `0`，以調節對函數的所有調用。

**請勿在您的 Lambda 函數程式碼中使用未記錄的非公有 API**。對於 AWS Lambda 受管執行時間，Lambda 會定期將安全性和函數更新套用至 Lambda 的內部 API。這些內部 API 更新可能是向後不相容的，這會導致意外結果，例如若您的函數依賴於這些非公有 API，則叫用失敗。請參閱 [API 參考](https://docs.aws.amazon.com/lambda/latest/api/welcome.html)查看公開可用 API 的清單。

**撰寫等冪程式碼。**為函數撰寫等冪程式碼可確保採用相同方式來處理重複事件。程式碼應正確驗證事件並正常處理重複的事件。如需詳細資訊，請參閱 [How do I make my Lambda function idempotent?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/) (如何讓 Lambda 函數等冪？)。

# 使用 Lambda 內容物件擷取 Go 函數資訊
<a name="golang-context"></a>

在 Lambda 中，內容物件提供的方法和各項屬性包含了有關調用、函數以及執行環境的資訊。當 Lambda 執行您的函數時，它會將內容物件傳遞至[處理常式](golang-handler.md)。若要在處理常式中使用內容物件，您可以選擇將其宣告為處理常式的輸入參數。如果您想要在處理常式中執行以下動作，則需要使用內容物件：
+ 您需要存取內容物件提供的任何[全域變數、方法或屬性](#golang-context-library)。這些方法和屬性對於諸如判斷調用函數的實體或測量函數的調用時間等任務很有用，如[存取叫用內容資訊](#golang-context-access)所述。
+ 您需要使用 適用於 Go 的 AWS SDK 來呼叫其他服務。對於大多數這樣的呼叫，內容物件是重要的輸入參數。如需更多詳細資訊，請參閱 [在 AWS SDK 用戶端初始化和呼叫中使用內容](#golang-context-sdk)。

**Topics**
+ [

## 內容物件中支援的變數、方法和屬性
](#golang-context-library)
+ [

## 存取叫用內容資訊
](#golang-context-access)
+ [

## 在 AWS SDK 用戶端初始化和呼叫中使用內容
](#golang-context-sdk)

## 內容物件中支援的變數、方法和屬性
<a name="golang-context-library"></a>

Lambda 內容程式庫提供下列全域變數、方法和屬性。

**全域變數**
+ `FunctionName` – Lambda 函數的名稱。
+ `FunctionVersion` – 函數的[版本](configuration-versions.md)。
+ `MemoryLimitInMB` - 分配給函數的記憶體數量。
+ `LogGroupName` - 函數的日誌群組。
+ `LogStreamName` - 函數執行個體的記錄串流。

**內容方法**
+ `Deadline` - 傳回執行逾時的日期，以 Unix 時間毫秒為單位。

**內容屬性**
+ `InvokedFunctionArn` - 用於叫用此函數的 Amazon Resource Name (ARN)。指出叫用者是否指定版本號或別名。
+ `AwsRequestID` - 叫用請求的識別符。
+ `Identity` - (行動應用程式) 已授權請求的 Amazon Cognito 身分的相關資訊。
+ `ClientContext` - (行動應用程式) 用戶端應用程式提供給 Lambda 的用戶端內容。

## 存取叫用內容資訊
<a name="golang-context-access"></a>

Lambda 函數有權存取有關其環境和叫用請求的中繼資料。這可以在[套件內容](https://golang.org/pkg/context/)進行存取。如果處理常式將 `context.Context` 納為參數，Lambda 即會將函數的相關資訊插入至內容的 `Value` 屬性。請注意，您需要匯入 `lambdacontext` 程式庫以存取 `context.Context` 物件的內容。

```
package main
 
import (
        "context"
        "log"
        "github.com/aws/aws-lambda-go/lambda"
        "github.com/aws/aws-lambda-go/lambdacontext"
)
 
func CognitoHandler(ctx context.Context) {
        lc, _ := lambdacontext.FromContext(ctx)
        log.Print(lc.Identity.CognitoIdentityPoolID)
}
 
func main() {
        lambda.Start(CognitoHandler)
}
```

在上面的範例中，`lc` 是用於取用內容物件擷取之資訊的變數，而 `log.Print(lc.Identity.CognitoIdentityPoolID)` 則會列印該資訊，在此例為 CognitoIdentityPoolID。

以下範例說明如何使用內容物件來監控執行 Lambda 函數的時間長度。這可讓您分析效能期望值，並在必要時據以調整您的函式程式碼。

```
package main

import (
        "context"
        "log"
        "time"
        "github.com/aws/aws-lambda-go/lambda"
)

func LongRunningHandler(ctx context.Context) (string, error) {

        deadline, _ := ctx.Deadline()
        deadline = deadline.Add(-100 * time.Millisecond)
        timeoutChannel := time.After(time.Until(deadline))

        for {

                select {

                case <- timeoutChannel:
                        return "Finished before timing out.", nil

                default:
                        log.Print("hello!")
                        time.Sleep(50 * time.Millisecond)
                }
        }
}

func main() {
        lambda.Start(LongRunningHandler)
}
```

## 在 AWS SDK 用戶端初始化和呼叫中使用內容
<a name="golang-context-sdk"></a>

如果處理常式需要使用 適用於 Go 的 AWS SDK 來呼叫其他服務，請將內容物件做為處理常式的輸入。在 AWS 中，最佳實務是在大多數 AWS SDK 呼叫中傳遞內容物件。例如，Amazon S3 `PutObject` 呼叫接受內容物件 (`ctx`) 做為其第一個引數：

```
// Upload an object to S3
    _, err = s3Client.PutObject(ctx, &s3.PutObjectInput{
        ...
    })
```

若要正確初始化 SDK 用戶端，您也可以使用內容物件載入正確的組態，然後再將該組態物件傳遞給用戶端：

```
// Load AWS SDK configuration using the default credential provider chain
    cfg, err := config.LoadDefaultConfig(ctx)
    ...
    s3Client = s3.NewFromConfig(cfg)
```

如果您想要在主要處理常式之外初始化 SDK 用戶端 (即在初始化階段)，您可以傳遞預留位置內容物件：

```
func init() {
	// Initialize the S3 client outside of the handler, during the init phase
	cfg, err := config.LoadDefaultConfig(context.TODO())
	...
	s3Client = s3.NewFromConfig(cfg)
}
```

如果您以這種方式初始化用戶端，請確保您從主要處理常式在 SDK 呼叫中傳遞正確的內容物件。

# 使用 .zip 封存檔部署 Go Lambda 函數
<a name="golang-package"></a>

 AWS Lambda 函數的程式碼包含指令碼或編譯的程式及其相依性。使用*部署套件*將函數程式碼部署到 Lambda。Lambda 支援兩種類型的部署套件：容器映像和 .zip 封存檔。

此頁面說明如何建立 .zip 檔案做為 Go 執行時間的部署套件，然後使用 .zip 檔案， AWS Lambda 使用 AWS 管理主控台、 AWS Command Line Interface (AWS CLI) 和 AWS Serverless Application Model () 將函數程式碼部署到AWS SAM。

請注意，Lambda 使用 POSIX 檔案許可，因此在建立 .zip 封存檔之前，您可能需要[設定部署套件資料夾的許可](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-deployment-package-errors/)。

**Topics**
+ [

## 在 macOS 和 Linux 上建立 .zip 檔案
](#golang-package-mac-linux)
+ [

## 在 Windows 上建立 .zip 檔案
](#golang-package-windows)
+ [

## 使用 .zip 檔案建立及更新 Go Lambda 函數
](#golang-package-create-function)

## 在 macOS 和 Linux 上建立 .zip 檔案
<a name="golang-package-mac-linux"></a>

下列步驟會說明如何使用 `go build` 命令編譯可執行檔，以及如何為 Lambda 建立 .zip 檔案部署套件。在編譯程式碼之前，請確認已從 GitHub 安裝 [lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) 套件。此模組會讓您實作執行期界面，管理 Lambda 與函數程式碼之間的互動。若要下載此程式庫，請執行下列命令。

```
go get github.com/aws/aws-lambda-go/lambda
```

如果您的函數使用 適用於 Go 的 AWS SDK，請下載標準 SDK 模組集，以及應用程式所需的任何 AWS 服務 API 用戶端。若要了解如何安裝適用於 Go 的 SDK，請參閱 [適用於 Go 的 AWS SDK V2 入門](https://github.com/aws/aws-sdk-go-v2?tab=readme-ov-file#getting-started)。

### 使用提供的執行時期系列
<a name="golang-package-mac-linux-al2"></a>

Go 的實作方式與其他受管執行期不同。由於 Go 程式碼原生編譯至可執行的二進位檔，因此不需要專用語言執行時期。應使用[僅限作業系統的執行時期](runtimes-provided.md) (`provided` 執行時期系列) 將 Go 函數部署至 Lambda。

**建立 .zip 部署套件 (macOS/Linux) 的方式**

1. 在含有應用程式 `main.go` 檔案的專案目錄中編譯可執行檔。注意下列事項：
   + 可執行檔必須命名為 `bootstrap`。如需詳細資訊，請參閱[處理常式命名慣例](golang-handler.md#golang-handler-naming)。
   + 設定您的目標 [指令集架構](foundation-arch.md)。僅限作業系統的執行時期同時支援 arm64 和 x86\$164。
   + 您可以使用選用 `lambda.norpc` 標籤，來排除 [lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) 程式庫的遠端程序呼叫 (RPC) 元件。使用已棄用的 Go 1.x 執行時期時，才需要 RPC 元件。排除 RPC 會縮減部署套件的大小。

   若是 arm64 架構：

   ```
   GOOS=linux GOARCH=arm64 go build -tags lambda.norpc -o bootstrap main.go
   ```

   若是 x86\$164 架構：

   ```
   GOOS=linux GOARCH=amd64 go build -tags lambda.norpc -o bootstrap main.go
   ```

1. (可選) 您可能需要用 Linux 上的 `CGO_ENABLED=0` 設定編譯套件：

   ```
   GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o bootstrap -tags lambda.norpc main.go
   ```

   此命令為標準 C 程式庫 (`libc`) 版本建立了一個穩定的二進位套件，這在 Lambda 和其他設備上可能不同。

1. 透過將可執行檔封裝在 .zip 檔案中建立部署套件。

   ```
   zip myFunction.zip bootstrap
   ```
**注意**  
`bootstrap` 檔案必須位於 .zip 檔案的根層級。

1. 建立函數。注意下列事項：
   + 二進位檔必須命名為 `bootstrap`，但處理常式名稱可以是任何名稱。如需詳細資訊，請參閱[處理常式命名慣例](golang-handler.md#golang-handler-naming)。
   + 如果您使用的是 arm64，才需要選擇 `--architectures` 選項。預設值為 x86\$164。
   + 針對 `--role`，請指定 [執行角色](lambda-intro-execution-role.md) 的 Amazon Resource Name (ARN)。

   ```
   aws lambda create-function --function-name myFunction \
   --runtime provided.al2023 --handler bootstrap \
   --architectures arm64 \
   --role arn:aws:iam::111122223333:role/lambda-ex \
   --zip-file fileb://myFunction.zip
   ```

## 在 Windows 上建立 .zip 檔案
<a name="golang-package-windows"></a>

下列步驟會說明從 GitHub 下載適用於 Windows 的 [build-lambda-zip](https://github.com/aws/aws-lambda-go/tree/main/cmd/build-lambda-zip) 工具、編譯可執行檔，以及建立 .zip 部署套件的方式。

**注意**  
如果尚未這樣做，您必須安裝 [git](https://git-scm.com/)，然後將 `git` 可執行檔新增到 Windows `%PATH%` 環境變數。

在編譯程式碼之前，請確認已從 GitHub 安裝 [lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) 程式庫。若要下載此程式庫，請執行下列命令。

```
go get github.com/aws/aws-lambda-go/lambda
```

如果您的函數使用 適用於 Go 的 AWS SDK，請下載標準 SDK 模組集，以及應用程式所需的任何 AWS 服務 API 用戶端。若要了解如何安裝適用於 Go 的 SDK，請參閱 [適用於 Go 的 AWS SDK V2 入門](https://aws.github.io/aws-sdk-go-v2/docs/getting-started/)。

### 使用提供的執行時期系列
<a name="golang-package-windows-al2"></a>

Go 的實作方式與其他受管執行期不同。由於 Go 程式碼原生編譯至可執行的二進位檔，因此不需要專用語言執行時期。應使用[僅限作業系統的執行時期](runtimes-provided.md) (`provided` 執行時期系列) 將 Go 函數部署至 Lambda。

**建立 .zip 部署套件的方式 (Windows)**

1. 從 GitHub 下載 **build-lambda-zip** 工具。

   ```
   go install github.com/aws/aws-lambda-go/cmd/build-lambda-zip@latest
   ```

1. 使用您的 `GOPATH` 工具來建立 .zip 檔案。如果您已預設安裝 Go，則該工具通常位於 `%USERPROFILE%\Go\bin` 中。否則，導覽至您安裝 Go 執行期之處，然後執行下列其中一個動作：

------
#### [ cmd.exe ]

   在 cmd.exe 中執行下列其中一項 (視您的目標 [指令集架構](foundation-arch.md) 而定)。僅限作業系統的執行時期同時支援 arm64 和 x86\$164。

   您可以使用選用 `lambda.norpc` 標籤，來排除 [lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) 程式庫的遠端程序呼叫 (RPC) 元件。使用已棄用的 Go 1.x 執行時期時，才需要 RPC 元件。排除 RPC 會縮減部署套件的大小。

**Example - 適用 x86\$164 架構**  

   ```
   set GOOS=linux
   set GOARCH=amd64
   set CGO_ENABLED=0
   go build -tags lambda.norpc -o bootstrap main.go
   %USERPROFILE%\Go\bin\build-lambda-zip.exe -o myFunction.zip bootstrap
   ```

**Example - 適用 arm64 架構**  

   ```
   set GOOS=linux
   set GOARCH=arm64
   set CGO_ENABLED=0
   go build -tags lambda.norpc -o bootstrap main.go
   %USERPROFILE%\Go\bin\build-lambda-zip.exe -o myFunction.zip bootstrap
   ```

------
#### [ PowerShell ]

   在 PowerShell 中執行下列其中一項 (視您的目標 [指令集架構](foundation-arch.md) 而定)。僅限作業系統的執行時期同時支援 arm64 和 x86\$164。

   您可以使用選用 `lambda.norpc` 標籤，來排除 [lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) 程式庫的遠端程序呼叫 (RPC) 元件。使用已棄用的 Go 1.x 執行時期時，才需要 RPC 元件。排除 RPC 會縮減部署套件的大小。

   若是 x86\$164 架構：

   ```
   $env:GOOS = "linux"
   $env:GOARCH = "amd64"
   $env:CGO_ENABLED = "0"
   go build -tags lambda.norpc -o bootstrap main.go
   ~\Go\Bin\build-lambda-zip.exe -o myFunction.zip bootstrap
   ```

   若是 arm64 架構：

   ```
   $env:GOOS = "linux"
   $env:GOARCH = "arm64"
   $env:CGO_ENABLED = "0"
   go build -tags lambda.norpc -o bootstrap main.go
   ~\Go\Bin\build-lambda-zip.exe -o myFunction.zip bootstrap
   ```

------

1. 建立函數。注意下列事項：
   + 二進位檔必須命名為 `bootstrap`，但處理常式名稱可以是任何名稱。如需詳細資訊，請參閱[處理常式命名慣例](golang-handler.md#golang-handler-naming)。
   + 如果您使用的是 arm64，才需要選擇 `--architectures` 選項。預設值為 x86\$164。
   + 針對 `--role`，請指定 [執行角色](lambda-intro-execution-role.md) 的 Amazon Resource Name (ARN)。

   ```
   aws lambda create-function --function-name myFunction \
   --runtime provided.al2023 --handler bootstrap \
   --architectures arm64 \
   --role arn:aws:iam::111122223333:role/lambda-ex \
   --zip-file fileb://myFunction.zip
   ```

## 使用 .zip 檔案建立及更新 Go Lambda 函數
<a name="golang-package-create-function"></a>

 建立 .zip 部署套件後，您可以使用該套件建立新的 Lambda 函數或更新現有函數。您可以使用 Lambda 主控台、 AWS Command Line Interface和 Lambda API 部署 .zip 套件。您也可以使用 AWS Serverless Application Model  (AWS SAM) 和  CloudFormation 建立並更新 Lambda 函數。

Lambda 的 .zip 部署套件大小上限為 250 MB (解壓縮)。請注意，此限制適用於您上傳的所有檔案 (包括任何 Lambda 層) 的大小總和。

Lambda 執行時間需有許可才能讀取部署套裝服務中的檔案。在 Linux 許可八進位標記法中，Lambda 需要 644 個許可 (rw-r--r--) 用於非可執行檔，以及 755 個許可 (rwxr-x) 用於目錄和可執行檔。

在 Linux 和 MacOS 中，使用 `chmod` 命令變更部署套件中檔案和目錄的檔案許可。例如，若要為非可執行檔提供正確的許可，請執行下列命令。

```
chmod 644 <filepath>
```

若要在 Windows 中變更檔案許可，請參閱 Microsoft Windows 文件的 [Set, View, Change, or Remove Permissions on an Object](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc731667(v=ws.10))。

**注意**  
如果您未授予 Lambda 存取部署套件中的目錄所需的許可，Lambda 會將這些目錄的許可設定為 755 (rwxr-xr-x)。

### 透過主控台使用 .zip 檔案建立及更新函數
<a name="golang-package-create-console"></a>

 若要建立新函數，您必須先在主控台中建立函數，然後上傳您的 .zip 封存檔。若要更新現有函數，請開啟函數的頁面，然後按照同樣的程序新增更新後的 .zip 檔案。

 如果您的 .zip 檔案小於 50 MB，您可以透過直接從本機電腦上傳檔案來建立或更新函數。若 .zip 檔案大於 50 MB，您必須先將套件上傳至 Amazon S3 儲存貯體。如需如何使用 將檔案上傳至 Amazon S3 儲存貯體的指示 AWS 管理主控台，請參閱 [Amazon S3 入門](https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html)。若要使用 上傳檔案 AWS CLI，請參閱*AWS CLI 《 使用者指南*》中的[移動物件](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。

**注意**  
您無法轉換現有的容器映像函數以使用 .zip 封存檔。您必須建立新的函數。

**若要建立新的函數 (主控台)**

1. 開啟 Lambda 主控台的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)，然後選擇**建立函數**。

1. 選擇 **Author from scratch** (從頭開始撰寫)。

1. 在**基本資訊**下，請執行下列動作：

   1. 在**函數名稱**中輸入函數名稱。

   1. 對於 **Runtime (執行時間)**，選擇 `provided.al2023`。

1. (選用) 在**許可**下，展開**變更預設執行角色**。您可建立新的**執行角色**，或使用現有的角色。

1. 選擇**建立函數**。Lambda 會使用您選擇的執行期建立一個基本的「Hello world」函數。

**若要從本機電腦上傳 .zip 封存檔 (主控台)**

1. 在 Lambda 主控台的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)中選擇要上傳 .zip 檔案的函數。

1. 選取**程式碼**索引標籤。

1. 在**程式碼來源**窗格中選擇**上傳來源**。

1. 選擇 **.zip 檔案**。

1. 若要上傳 .zip 檔案，請執行下列操作：

   1. 選擇**上傳**，然後在檔案選擇器中選取您的 .zip 檔案。

   1. 選擇 **Open** (開啟)。

   1. 選擇**儲存**。

**若要從 Amazon S3 儲存貯體上傳 .zip 封存檔 (控制台)**

1. 在 Lambda 主控台的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)中選擇要上傳新 .zip 檔案的函數。

1. 選取**程式碼**索引標籤。

1. 在**程式碼來源**窗格中選擇**上傳來源**。

1. 選擇 **Amazon S3 位置**。

1. 貼上 .zip 檔案的 Amazon S3 連結 URL，然後選擇**儲存**。

### 使用 建立和更新具有 .zip 檔案的函數 AWS CLI
<a name="golang-package-create-cli"></a>

 您可以使用 [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) 建立新函數，或使用 .zip 檔案更新現有函數。使用 [create-function](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) 和 [update-function-code](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) 命令來部署您的 .zip 套件。如果您的 .zip 檔案小於 50 MB，則可以從本機建置電腦的檔案位置上傳 .zip 套件。若檔案較大，則必須先從 Amazon S3 儲存貯體上傳 .zip 套件。如需如何使用 將檔案上傳至 Amazon S3 儲存貯體的指示 AWS CLI，請參閱*AWS CLI 《 使用者指南*》中的[移動物件](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。

**注意**  
如果您使用 從 Amazon S3 儲存貯體上傳 .zip 檔案 AWS CLI，儲存貯體必須與 AWS 區域 函數位於相同的 中。

 若要搭配 使用 .zip 檔案建立新的函數 AWS CLI，您必須指定下列項目：
+ 函數名稱 (`--function-name`)
+ 函數的執行期 (`--runtime`)
+ 函數[執行角色](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)的 Amazon Resource Name (ARN) (`--role`)
+ 函數程式碼中處理常式方法的名稱 (`--handler`)

 您也必須指定 .zip 檔案的位置。如果您的 .zip 檔案位於本機建置電腦上的資料夾中，請使用 `--zip-file` 選項來指定檔案路徑，如下列範例命令所示。

```
aws lambda create-function --function-name myFunction \
--runtime provided.al2023 --handler bootstrap \
--role arn:aws:iam::111122223333:role/service-role/my-lambda-role \
--zip-file fileb://myFunction.zip
```

 若要在 Amazon S3 儲存貯體中指定 .zip 檔案的位置，請使用如下列範例命令所示的 `--code` 選項。您只需針對版本控制的物件使用 `S3ObjectVersion` 參數。

```
aws lambda create-function --function-name myFunction \
--runtime provided.al2023 --handler bootstrap \
--role arn:aws:iam::111122223333:role/service-role/my-lambda-role \
--code S3Bucket=amzn-s3-demo-bucket,S3Key=myFileName.zip,S3ObjectVersion=myObjectVersion
```

 若要使用 CLI 更新現有函數，您可以使用 `--function-name` 參數指定函數的名稱。您也必須指定要用來更新函數程式碼的 .zip 檔案的位置。如果您的 .zip 檔案位於本機建置電腦上的資料夾中，請使用 `--zip-file` 選項來指定檔案路徑，如下列範例命令所示。

```
aws lambda update-function-code --function-name myFunction \
--zip-file fileb://myFunction.zip
```

 若要在 Amazon S3 儲存貯體中指定 .zip 檔案的位置，請使用如下列範例命令所示的 `--s3-bucket` 和 `--s3-key` 選項。您只需針對版本控制的物件使用 `--s3-object-version` 參數。

```
aws lambda update-function-code --function-name myFunction \
--s3-bucket amzn-s3-demo-bucket --s3-key myFileName.zip --s3-object-version myObject Version
```

### 透過 Lambda API 使用 .zip 檔案建立及更新函數
<a name="golang-package-create-api"></a>

 若要使用 .zip 封存檔建立及更新函數，請使用下列 API 操作：
+ [CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html)
+ [UpdateFunctionCode](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionCode.html)

### 使用 建立和更新具有 .zip 檔案的函數 AWS SAM
<a name="golang-package-create-sam"></a>

 AWS Serverless Application Model (AWS SAM) 是一種工具組，可協助簡化建置和執行無伺服器應用程式的程序 AWS。您可以在 YAML 或 JSON 範本中定義應用程式的資源，並使用 AWS SAM 命令列界面 (AWS SAM CLI) 來建置、封裝和部署應用程式。當您從 AWS SAM 範本建置 Lambda 函數時， AWS SAM 會自動使用函數程式碼和您指定的任何相依性建立 .zip 部署套件或容器映像。若要進一步了解如何使用 AWS SAM 來建置和部署 Lambda 函數，請參閱《 *AWS Serverless Application Model 開發人員指南*》中的 [入門 AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started.html)。

您也可以使用 AWS SAM 來建立使用現有 .zip 檔案封存的 Lambda 函數。若要使用 建立 Lambda 函數 AWS SAM，您可以將 .zip 檔案儲存在 Amazon S3 儲存貯體或建置機器的本機資料夾中。如需如何使用 將檔案上傳至 Amazon S3 儲存貯體的指示 AWS CLI，請參閱*AWS CLI 《 使用者指南*》中的[移動物件](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。

 在您的 AWS SAM 範本中，`AWS::Serverless::Function`資源會指定您的 Lambda 函數。在本資源中設定下列屬性，以使用 .zip 封存檔建立函數：
+ `PackageType`：設定為 `Zip`
+ `CodeUri`：設定為函數程式碼的 Amazon S3 URI、本機資料夾的路徑或 [FunctionCode](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-functioncode.html) 物件
+ `Runtime`：設定為所選執行期

 如果您的 AWS SAM.zip 檔案大於 50MB，則不需要先將其上傳至 Amazon S3 儲存貯體。 AWS SAM 可以從本機建置機器的位置上傳最大允許大小為 250MB （解壓縮） 的 .zip 套件。

 若要進一步了解如何在 中使用 .zip 檔案部署函數 AWS SAM，請參閱《 *AWS SAM 開發人員指南*》中的 [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)。

**範例：使用 搭配 provided.al2023 AWS SAM 建置 Go 函數**

1. 建立具有下列屬性的 AWS SAM 範本：
   + **BuildMethod**：指定應用程式的編譯器。請使用 `go1.x`。
   + **Runtime**：使用 `provided.al2023`。
   + **CodeUri**：輸入程式碼的路徑。
   + **Architectures**：為 arm64 架構使用 `[arm64]`。若是 x86\$164 指令集架構，請使用 `[amd64]` 或移除 `Architectures` 屬性。  
**Example template.yaml**  

   ```
   AWSTemplateFormatVersion: '2010-09-09'
   Transform: 'AWS::Serverless-2016-10-31'
   Resources:
     HelloWorldFunction:
       Type: AWS::Serverless::Function
       Metadata:
         BuildMethod: go1.x
       Properties:
         CodeUri: hello-world/ # folder where your main program resides
         Handler: bootstrap
         Runtime: provided.al2023
         Architectures: [arm64]
   ```

1. 使用 [sam build](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-build.html) 命令來編譯可執行檔。

   ```
   sam build
   ```

1. 使用 [sam deploy](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-deploy.html) 命令將函數部署到 Lambda。

   ```
   sam deploy --guided
   ```

### 使用 建立和更新具有 .zip 檔案的函數 CloudFormation
<a name="golang-package-create-cfn"></a>

 您可以使用 CloudFormation 建立使用 .zip 檔案封存的 Lambda 函數。若要使用 .zip 檔案建立 Lambda 函數，您必須先將檔案上傳至 Amazon S3 儲存貯體。如需如何使用 將檔案上傳至 Amazon S3 儲存貯體的指示 AWS CLI，請參閱《 使用者指南》中的[移動物件](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。 *AWS CLI *

在您的 CloudFormation 範本中，`AWS::Lambda::Function`資源會指定您的 Lambda 函數。在本資源中設定下列屬性，以使用 .zip 封存檔建立函數：
+ `PackageType`：設定為 `Zip`
+ `Code`：在 `S3Bucket` 和 `S3Key` 欄位中輸入 Amazon S3 儲存貯體名稱和 .zip 檔案名稱。
+ `Runtime`：設定為所選執行期

 CloudFormation 產生的 .zip 檔案不能超過 4MB。若要進一步了解如何在 中使用 .zip 檔案部署函數 CloudFormation，請參閱*CloudFormation 《 使用者指南*》中的 [AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)。

# 使用容器映像來部署 Go Lambda 函數
<a name="go-image"></a>

您可以透過兩種方式為 Go Lambda 函數建置容器映像：
+ [使用僅限 AWS 作業系統的基礎映像](#go-image-provided)

  Go 的實作方式與其他受管執行期不同。由於 Go 程式碼原生編譯至可執行的二進位檔，因此不需要專用語言執行時期。使用[僅限作業系統的基礎映像](images-create.md#runtimes-images-provided)來建置 Lambda 的 Go 映像。若要使映像檔與 Lambda 相容，您必須在映像中加入 `aws-lambda-go/lambda` 套件。
+ [使用非AWS 基礎映像](#go-image-other)

  您可以使用其他容器登錄檔中的替代基礎映像 (例如 Alpine Linux 或 Debian)。您也可以使用組織建立的自訂映像。若要使映像檔與 Lambda 相容，您必須在映像中加入 `aws-lambda-go/lambda` 套件。

**提示**  
若要縮短 Lambda 容器函數變成作用中狀態所需的時間，請參閱 Docker 文件中的[使用多階段建置](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#use-multi-stage-builds)。若要建置有效率的容器映像，請遵循[撰寫 Dockerfiles 的最佳實務](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)。

本頁面會說明如何為 Lambda 建置、測試和部署容器映像。

## AWS 部署 Go 函數的基礎映像
<a name="go-image-base"></a>

Go 的實作方式與其他受管執行期不同。由於 Go 程式碼原生編譯至可執行的二進位檔，因此不需要專用語言執行時期。使用[僅限作業系統的基礎映像](images-create.md#runtimes-images-provided)，將 Go 函數部署至 Lambda。


| Name | 識別符 | 作業系統 | 取代日期 | 封鎖函數建立 | 封鎖函數更新 | 
| --- | --- | --- | --- | --- | --- | 
|  僅限作業系統的執行期  |  `provided.al2023`  |  Amazon Linux 2023  |   2029 年 6 月 30 日   |   2029 年 7 月 31 日   |   2029 年 8 月 31 日   | 
|  僅限作業系統的執行期  |  `provided.al2`  |  Amazon Linux 2  |   2026 年 7 月 31 日   |   2026 年 8 月 31 日   |   2026 年 9 月 30 日   | 

Amazon Elastic Container Registry 公有資源庫：[gallery.ecr.aws/lambda/provided](https://gallery.ecr.aws/lambda/provided)

## Go 執行期介面用戶端
<a name="go-image-clients"></a>

此 `aws-lambda-go/lambda` 套件包含執行期介面實作。如需在映像中使用 `aws-lambda-go/lambda` 的範例，請參閱 [使用僅限 AWS 作業系統的基礎映像](#go-image-provided) 或 [使用非AWS 基礎映像](#go-image-other)。

## 使用僅限 AWS 作業系統的基礎映像
<a name="go-image-provided"></a>

Go 的實作方式與其他受管執行期不同。由於 Go 程式碼原生編譯至可執行的二進位檔，因此不需要專用語言執行時期。使用[僅限作業系統的基礎映像](images-create.md#runtimes-images-provided)來建置 Go 函數的容器映像。


| Tags (標籤) | 執行期 | 作業系統 | Dockerfile | 棄用 | 
| --- | --- | --- | --- | --- | 
| al2023 | 僅限作業系統的執行期 | Amazon Linux 2023 | [GitHub 上僅限作業系統之執行期的 Dockerfile](https://github.com/aws/aws-lambda-base-images/blob/provided.al2023/Dockerfile.provided.al2023) |   2029 年 6 月 30 日   | 
| al2 | 僅限作業系統的執行期 | Amazon Linux 2 | [GitHub 上僅限作業系統之執行期的 Dockerfile](https://github.com/aws/aws-lambda-base-images/blob/provided.al2/Dockerfile.provided.al2) |   2026 年 7 月 31 日   | 

如需有關這類基礎映像的詳細資訊，請參閱 Amazon ECR 公有庫中 [提供的內容](https://gallery.ecr.aws/lambda/provided)。

您必須將 [aws-lambda-go/lambda](https://github.com/aws/aws-lambda-go) 套件加入 Go 處理常式。此套件會實作 Go 的程式設計模型 (包括執行期介面)。

### 先決條件
<a name="go-custom-prerequisites"></a>

若要完成本節中的步驟，您必須執行下列各項：
+ [AWS CLI 第 2 版](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker) (最低版本 25.0.0)
+ Docker [buildx 外掛程式](https://github.com/docker/buildx/blob/master/README.md)。
+ Go

### 從 provided.al2023 基礎映像建立映像
<a name="go-custom-create"></a>

**使用 `provided.al2023` 基礎映像建置和部署 Go 函數**

1. 建立專案的目錄，然後切換至該目錄。

   ```
   mkdir hello
   cd hello
   ```

1. 初始化新的 Go 模組。

   ```
   go mod init example.com/hello-world
   ```

1. 將 **lambda** 程式庫新增為新模組的相依項。

   ```
   go get github.com/aws/aws-lambda-go/lambda
   ```

1. 建立名為 `main.go` 的檔案，然後在文字編輯器中開啟。這是 Lambda 函數的程式碼。可以使用以下範本程式碼進行測試，也可以將其替換為您自己的程式碼。

   ```
   package main
   
   import (
   	"context"
   	"github.com/aws/aws-lambda-go/events"
   	"github.com/aws/aws-lambda-go/lambda"
   )
   
   func handler(ctx context.Context, event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
   	response := events.APIGatewayProxyResponse{
   		StatusCode: 200,
   		Body:       "\"Hello from Lambda!\"",
   	}
   	return response, nil
   }
   
   func main() {
   	lambda.Start(handler)
   }
   ```

1. 使用文字編輯器在專案目錄中建立 Dockerfile。
   + 下列範例 Dockerfile 使用[多階段建置](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#use-multi-stage-builds)。這可讓您在每個步驟中使用不同的基礎映像。您可以使用一個映像 (例如 [Go 基礎映像](https://hub.docker.com/_/golang)檔) 來編譯程式碼並建置可執行二進位檔案。然後，可以在最終的 `FROM` 陳述式中使用不同的映像 (例如 `provided.al2023`) 來定義您部署到 Lambda 的映像。建置程序與最終部署映像是分開的，因此最終映像僅包含執行應用程式所需的檔案。
   + 您可以使用選用 `lambda.norpc` 標籤，來排除 [lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) 程式庫的遠端程序呼叫 (RPC) 元件。使用已棄用的 Go 1.x 執行時期時，才需要 RPC 元件。排除 RPC 會縮減部署套件的大小。
   + 請注意，範例 Dockerfile 不包含 [USER 指令](https://docs.docker.com/reference/dockerfile/#user)。當您將容器映像部署到 Lambda 時，Lambda 會自動定義一個具有最低權限許可的預設 Linux 使用者。這與標準 Docker 行為不同，後者會在未提供 `USER` 指令時預設為 `root` 使用者。  
**Example – 多階段建置 Dockerfile**  
**注意**  
確保您在 Dockerfile 中指定的 Go 版本 (例如，`golang:1.20`) 與用於建立應用程式的 Go 版本相同。

   ```
   FROM golang:1.20 as build
   WORKDIR /helloworld
   # Copy dependencies list
   COPY go.mod go.sum ./
   # Build with optional lambda.norpc tag
   COPY main.go .
   RUN go build -tags lambda.norpc -o main main.go
   # Copy artifacts to a clean image
   FROM public.ecr.aws/lambda/provided:al2023
   COPY --from=build /helloworld/main ./main
   ENTRYPOINT [ "./main" ]
   ```

1. 使用 [docker build](https://docs.docker.com/engine/reference/commandline/build/) 命令建立 Docker 映像檔。以下範例將映像命名為 `docker-image` 並為其提供 `test` [標籤](https://docs.docker.com/engine/reference/commandline/build/#tag)。若要使映像與 Lambda 相容，必須使用 `--provenance=false` 選項。

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**注意**  
此命令會指定 `--platform linux/amd64` 選項，確保無論建置機器的架構為何，您的容器都與 Lambda 執行環境相容。如果您打算使用 ARM64 指令集架構建立 Lambda 函數，務必將命令變更為改用 `--platform linux/arm64` 選項。

### (選用) 在本機測試映像
<a name="go-custom-test"></a>

使用 [執行期界面模擬器](https://github.com/aws/aws-lambda-runtime-interface-emulator/) 以在本機測試映像。執行期界面模擬器包含在 `provided.al2023` 基礎映像中。

**若要在本機電腦上執行執行期界面模擬器**

1. 使用 **docker run** 命令啟動 Docker 影像。注意下列事項：
   + `docker-image` 是映像名稱，而 `test` 是標籤。
   + `./main` 是來自 Dockerfile 的 `ENTRYPOINT`。

   ```
   docker run -d -p 9000:8080 \
   --entrypoint /usr/local/bin/aws-lambda-rie \
   docker-image:test ./main
   ```

   此命令將映像作為容器執行，並在 `localhost:9000/2015-03-31/functions/function/invocations` 建立本機端點。

1. 從新的終端機視窗，使用 **curl** 命令將事件張貼至下列端點：

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
   ```

   此命令會透過空白事件調用函數，並傳回一個回應。部分函數可能需要使用 JSON 承載。範例：

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
   ```

1. 取得容器 ID。

   ```
   docker ps
   ```

1. 使用 [docker kill](https://docs.docker.com/engine/reference/commandline/kill/) 命令停止容器。在此命令中，將 `3766c4ab331c` 替換為上一步驟中的容器 ID。

   ```
   docker kill 3766c4ab331c
   ```

### 部署映像
<a name="go-custom-deploy"></a>

**若要將映像上傳至 Amazon ECR 並建立 Lambda 函數**

1. 使用 [get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html) 命令，向 Amazon ECR 登錄檔驗證 Docker CLI。
   + 將 `--region`值設定為您要在 AWS 區域 其中建立 Amazon ECR 儲存庫的 。
   + `111122223333` 以您的 AWS 帳戶 ID 取代 。

   ```
   aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
   ```

1. 使用 [create-repository](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/create-repository.html) 命令在 Amazon ECR 中建立儲存庫。

   ```
   aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
   ```
**注意**  
Amazon ECR 儲存庫必須與 Lambda 函數 AWS 區域 位於相同的 中。

   如果成功，您將會看到以下回應：

   ```
   {
       "repository": {
           "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world",
           "registryId": "111122223333",
           "repositoryName": "hello-world",
           "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world",
           "createdAt": "2023-03-09T10:39:01+00:00",
           "imageTagMutability": "MUTABLE",
           "imageScanningConfiguration": {
               "scanOnPush": true
           },
           "encryptionConfiguration": {
               "encryptionType": "AES256"
           }
       }
   }
   ```

1. 從上一步驟的輸出中複製 `repositoryUri`。

1. 執行 [docker tag](https://docs.docker.com/engine/reference/commandline/tag/) 命令，將 Amazon ECR 儲存庫中的本機映像標記為最新版本。在此命令中：
   + `docker-image:test` 為 Docker 映像檔的名稱和[標籤](https://docs.docker.com/engine/reference/commandline/build/#tag)。這是您在 `docker build` 命令中指定的映像名稱和標籤。
   + 將 `<ECRrepositoryUri>` 替換為複製的 `repositoryUri`。確保在 URI 的末尾包含 `:latest`。

   ```
   docker tag docker-image:test <ECRrepositoryUri>:latest
   ```

   範例：

   ```
   docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. 執行 [docker push](https://docs.docker.com/engine/reference/commandline/push/) 命令，將本機映像部署至 Amazon ECR 儲存庫。確保在儲存庫 URI 的末尾包含 `:latest`。

   ```
   docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. [建立函數的執行角色](lambda-intro-execution-role.md#permissions-executionrole-api) (若您還沒有的話)。在下一個步驟中您需要角色的 Amazon Resource Name (ARN)。

1. 建立 Lambda 函數。對於 `ImageUri`，從之前的設定中指定儲存庫 URI。確保在 URI 的末尾包含 `:latest`。

   ```
   aws lambda create-function \
     --function-name hello-world \
     --package-type Image \
     --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
     --role arn:aws:iam::111122223333:role/lambda-ex
   ```
**注意**  
您可以使用不同帳戶中的映像來建立函數 AWS ，只要映像與 Lambda 函數位於相同的區域即可。如需詳細資訊，請參閱[Amazon ECR 跨帳戶許可](images-create.md#configuration-images-xaccount-permissions)。

1. 調用函數。

   ```
   aws lambda invoke --function-name hello-world response.json
   ```

   您應該看到如下回應：

   ```
   {
     "ExecutedVersion": "$LATEST", 
     "StatusCode": 200
   }
   ```

1. 若要查看函數的輸出，請檢查 `response.json` 檔案。

若要更新函數程式碼，您必須再次建置映像、將新映像上傳到 Amazon ECR 存放庫，然後使用 [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) 命令將映像部署到 Lambda 函數。

Lambda 會將映像標籤解析為特定映像摘要。這表示如果您將用來部署函數的映像標籤指向 Amazon ECR 中的新映像，Lambda 不會自動更新函數以使用新映像。

若要將新映像部署至相同的 Lambda 函數，必須使用 [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) 命令，即使 Amazon ECR 中的映像標籤保持不變亦如此。在以下範例中，`--publish` 選項會使用更新的容器映像來建立新的函數版本。

```
aws lambda update-function-code \
  --function-name hello-world \
  --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
  --publish
```

## 使用非AWS 基礎映像
<a name="go-image-other"></a>

您可以從非AWS 基礎映像建置 Go 的容器映像。下列步驟中的 Dockerfile 範例使用 [Alpine 基礎映像](https://hub.docker.com/_/golang/)。

您必須將 [aws-lambda-go/lambda](https://github.com/aws/aws-lambda-go) 套件加入 Go 處理常式。此套件會實作 Go 的程式設計模型 (包括執行期介面)。

### 先決條件
<a name="go-alt-prerequisites"></a>

若要完成本節中的步驟，您必須執行下列各項：
+ [AWS CLI 第 2 版](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker) (最低版本 25.0.0)
+ Docker [buildx 外掛程式](https://github.com/docker/buildx/blob/master/README.md)。
+ Go

### 使用替代基礎映像建立映像
<a name="go-alt-create"></a>

**使用 Alpine 基礎映像建置和部署 Go 函數**

1. 建立專案的目錄，然後切換至該目錄。

   ```
   mkdir hello
   cd hello
   ```

1. 初始化新的 Go 模組。

   ```
   go mod init example.com/hello-world
   ```

1. 將 **lambda** 程式庫新增為新模組的相依項。

   ```
   go get github.com/aws/aws-lambda-go/lambda
   ```

1. 建立名為 `main.go` 的檔案，然後在文字編輯器中開啟。這是 Lambda 函數的程式碼。可以使用以下範本程式碼進行測試，也可以將其替換為您自己的程式碼。

   ```
   package main
   
   import (
   	"context"
   	"github.com/aws/aws-lambda-go/events"
   	"github.com/aws/aws-lambda-go/lambda"
   )
   
   func handler(ctx context.Context, event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
   	response := events.APIGatewayProxyResponse{
   		StatusCode: 200,
   		Body:       "\"Hello from Lambda!\"",
   	}
   	return response, nil
   }
   
   func main() {
   	lambda.Start(handler)
   }
   ```

1. 使用文字編輯器在專案目錄中建立 Dockerfile。下列 Dockerfile 範例使用 [Alpine 基礎映像](https://hub.docker.com/_/golang/)。請注意，範例 Dockerfile 不包含 [USER 指令](https://docs.docker.com/reference/dockerfile/#user)。當您將容器映像部署到 Lambda 時，Lambda 會自動定義一個具有最低權限許可的預設 Linux 使用者。這與標準 Docker 行為不同，後者會在未提供 `USER` 指令時預設為 `root` 使用者。  
**Example Dockerfile**  
**注意**  
確保您在 Dockerfile 中指定的 Go 版本 (例如，`golang:1.20`) 與用於建立應用程式的 Go 版本相同。

   ```
   FROM golang:1.20.2-alpine3.16 as build
   WORKDIR /helloworld
   # Copy dependencies list
   COPY go.mod go.sum ./
   # Build
   COPY main.go .
   RUN go build -o main main.go
   # Copy artifacts to a clean image
   FROM alpine:3.16
   COPY --from=build /helloworld/main /main
   ENTRYPOINT [ "/main" ]
   ```

1. 使用 [docker build](https://docs.docker.com/engine/reference/commandline/build/) 命令建立 Docker 映像檔。以下範例將映像命名為 `docker-image` 並為其提供 `test` [標籤](https://docs.docker.com/engine/reference/commandline/build/#tag)。若要使映像與 Lambda 相容，必須使用 `--provenance=false` 選項。

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**注意**  
此命令會指定 `--platform linux/amd64` 選項，確保無論建置機器的架構為何，您的容器都與 Lambda 執行環境相容。如果您打算使用 ARM64 指令集架構建立 Lambda 函數，務必將命令變更為改用 `--platform linux/arm64` 選項。

### (選用) 在本機測試映像
<a name="go-alt-test"></a>

使用 [執行期界面模擬器](https://github.com/aws/aws-lambda-runtime-interface-emulator/) 以在本機測試映像。您可以[將模擬器建置到映像中](https://github.com/aws/aws-lambda-runtime-interface-emulator/?tab=readme-ov-file#build-rie-into-your-base-image)，也可以使用以下步驟，將其安裝在本機電腦。

**若要在本機電腦上安裝並執行執行期介面模擬器**

1. 在您的專案目錄中執行以下命令，從 GitHub 下載執行期介面模擬器 (x86-64 架構)，並安裝在本機電腦上。

------
#### [ Linux/macOS ]

   ```
   mkdir -p ~/.aws-lambda-rie && \
       curl -Lo ~/.aws-lambda-rie/aws-lambda-rie https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie && \
       chmod +x ~/.aws-lambda-rie/aws-lambda-rie
   ```

   若要安裝 arm64 模擬器，請將上一個命令中的 GitHub 儲存庫 URL 替換為以下內容：

   ```
   https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
   ```

------
#### [ PowerShell ]

   ```
   $dirPath = "$HOME\.aws-lambda-rie"
   if (-not (Test-Path $dirPath)) {
       New-Item -Path $dirPath -ItemType Directory
   }
         
   $downloadLink = "https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie"
   $destinationPath = "$HOME\.aws-lambda-rie\aws-lambda-rie"
   Invoke-WebRequest -Uri $downloadLink -OutFile $destinationPath
   ```

   若要安裝 arm64 模擬器，請將 `$downloadLink` 更換為下列項目：

   ```
   https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
   ```

------

1. 使用 **docker run** 命令啟動 Docker 影像。注意下列事項：
   + `docker-image` 是映像名稱，而 `test` 是標籤。
   + `/main` 是來自 Dockerfile 的 `ENTRYPOINT`。

------
#### [ Linux/macOS ]

   ```
   docker run --platform linux/amd64 -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 \
       --entrypoint /aws-lambda/aws-lambda-rie \
       docker-image:test \
           /main
   ```

------
#### [ PowerShell ]

   ```
   docker run --platform linux/amd64 -d -v "$HOME\.aws-lambda-rie:/aws-lambda" -p 9000:8080 `
   --entrypoint /aws-lambda/aws-lambda-rie `
   docker-image:test `
       /main
   ```

------

   此命令將映像作為容器執行，並在 `localhost:9000/2015-03-31/functions/function/invocations` 建立本機端點。
**注意**  
如果您為 ARM64 指令集架構建立 Docker 映像檔，請務必將`--platform linux/arm64`選項改用選項。`--platform linux/amd64`

1. 將事件張貼至本機端點。

------
#### [ Linux/macOS ]

   在 Linux 或 macOS 中，執行下列 `curl` 命令：

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
   ```

   此命令會透過空白事件調用函數，並傳回一個回應。如果您使用自己的函數程式碼而不是範例函數程式碼，則可能需要使用 JSON 承載調用該函數。範例：

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
   ```

------
#### [ PowerShell ]

   在 PowerShell 中，執行下列 `Invoke-WebRequest` 命令：

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"
   ```

   此命令會透過空白事件調用函數，並傳回一個回應。如果您使用自己的函數程式碼而不是範例函數程式碼，則可能需要使用 JSON 承載調用該函數。範例：

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}' -ContentType "application/json"
   ```

------

1. 取得容器 ID。

   ```
   docker ps
   ```

1. 使用 [docker kill](https://docs.docker.com/engine/reference/commandline/kill/) 命令停止容器。在此命令中，將 `3766c4ab331c` 替換為上一步驟中的容器 ID。

   ```
   docker kill 3766c4ab331c
   ```

### 部署映像
<a name="go-alt-deploy"></a>

**若要將映像上傳至 Amazon ECR 並建立 Lambda 函數**

1. 使用 [get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html) 命令，向 Amazon ECR 登錄檔驗證 Docker CLI。
   + 將 `--region`值設定為您要在 AWS 區域 其中建立 Amazon ECR 儲存庫的 。
   + `111122223333` 以您的 AWS 帳戶 ID 取代 。

   ```
   aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
   ```

1. 使用 [create-repository](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/create-repository.html) 命令在 Amazon ECR 中建立儲存庫。

   ```
   aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
   ```
**注意**  
Amazon ECR 儲存庫必須與 Lambda 函數 AWS 區域 位於相同的 中。

   如果成功，您將會看到以下回應：

   ```
   {
       "repository": {
           "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world",
           "registryId": "111122223333",
           "repositoryName": "hello-world",
           "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world",
           "createdAt": "2023-03-09T10:39:01+00:00",
           "imageTagMutability": "MUTABLE",
           "imageScanningConfiguration": {
               "scanOnPush": true
           },
           "encryptionConfiguration": {
               "encryptionType": "AES256"
           }
       }
   }
   ```

1. 從上一步驟的輸出中複製 `repositoryUri`。

1. 執行 [docker tag](https://docs.docker.com/engine/reference/commandline/tag/) 命令，將 Amazon ECR 儲存庫中的本機映像標記為最新版本。在此命令中：
   + `docker-image:test` 為 Docker 映像檔的名稱和[標籤](https://docs.docker.com/engine/reference/commandline/build/#tag)。這是您在 `docker build` 命令中指定的映像名稱和標籤。
   + 將 `<ECRrepositoryUri>` 替換為複製的 `repositoryUri`。確保在 URI 的末尾包含 `:latest`。

   ```
   docker tag docker-image:test <ECRrepositoryUri>:latest
   ```

   範例：

   ```
   docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. 執行 [docker push](https://docs.docker.com/engine/reference/commandline/push/) 命令，將本機映像部署至 Amazon ECR 儲存庫。確保在儲存庫 URI 的末尾包含 `:latest`。

   ```
   docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. [建立函數的執行角色](lambda-intro-execution-role.md#permissions-executionrole-api) (若您還沒有的話)。在下一個步驟中您需要角色的 Amazon Resource Name (ARN)。

1. 建立 Lambda 函數。對於 `ImageUri`，從之前的設定中指定儲存庫 URI。確保在 URI 的末尾包含 `:latest`。

   ```
   aws lambda create-function \
     --function-name hello-world \
     --package-type Image \
     --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
     --role arn:aws:iam::111122223333:role/lambda-ex
   ```
**注意**  
您可以使用不同帳戶中的映像來建立函數 AWS ，只要映像與 Lambda 函數位於相同的區域即可。如需詳細資訊，請參閱[Amazon ECR 跨帳戶許可](images-create.md#configuration-images-xaccount-permissions)。

1. 調用函數。

   ```
   aws lambda invoke --function-name hello-world response.json
   ```

   您應該看到如下回應：

   ```
   {
     "ExecutedVersion": "$LATEST", 
     "StatusCode": 200
   }
   ```

1. 若要查看函數的輸出，請檢查 `response.json` 檔案。

若要更新函數程式碼，您必須再次建置映像、將新映像上傳到 Amazon ECR 存放庫，然後使用 [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) 命令將映像部署到 Lambda 函數。

Lambda 會將映像標籤解析為特定映像摘要。這表示如果您將用來部署函數的映像標籤指向 Amazon ECR 中的新映像，Lambda 不會自動更新函數以使用新映像。

若要將新映像部署至相同的 Lambda 函數，必須使用 [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) 命令，即使 Amazon ECR 中的映像標籤保持不變亦如此。在以下範例中，`--publish` 選項會使用更新的容器映像來建立新的函數版本。

```
aws lambda update-function-code \
  --function-name hello-world \
  --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
  --publish
```

# 使用 Go Lambda 函數的層
<a name="golang-layers"></a>

不建議使用[層](chapter-layers.md)來管理以 Go 編寫的 Lambda 函式相依項。這是因為以 Go 編寫的 Lambda 函數會編譯為單一可執行檔，您在部署函數時該檔會提供給 Lambda。此可執行檔包含經過編譯的函數程式碼及其所有相依項。使用層不僅會使程序複雜化，還會導致冷啟動時間增加，因為函數需要在初始化階段期間將額外的組件載入記憶體。

若要在 Go 處理常式中使用外部相依項，請直接將其包含在部署套件中。如此一來，您既能簡化部署程序，又能利用內建的 Go 編譯器最佳化。如需如何在函數中匯入和使用適用於 Go 的 AWS SDK 等相依項的範例，請參閱[定義 Go 格式的 Lambda 函數處理常式](golang-handler.md)。

# 記錄和監控 Go Lambda 函數
<a name="golang-logging"></a>

AWS Lambda 會自動代表您監控 Lambda 函數，並將日誌傳送至 Amazon CloudWatch。您的 Lambda 函數隨附有 CloudWatch Logs 日誌群組，且函數的每一執行個體各有一個日誌串流。Lambda 執行期環境會將每次調用的詳細資訊傳送至日誌串流，並且轉傳來自函數程式碼的日誌及其他輸出。如需詳細資訊，請參閱[將 Lambda 函式日誌傳送至 CloudWatch Logs](monitoring-cloudwatchlogs.md)。

此頁面說明如何從 Lambda 函數的程式碼產生日誌輸出，並使用 AWS Command Line Interface、Lambda 主控台或 CloudWatch 主控台存取日誌。

**Topics**
+ [

## 建立傳回日誌的函數
](#golang-logging-output)
+ [

## 在 Lambda 主控台檢視日誌
](#golang-logging-console)
+ [

## 在 CloudWatch 主控台中檢視 記錄
](#golang-logging-cwconsole)
+ [

## 使用 AWS Command Line Interface (AWS CLI) 檢視日誌
](#golang-logging-cli)
+ [

## 刪除日誌
](#golang-logging-delete)

## 建立傳回日誌的函數
<a name="golang-logging-output"></a>

若要從您的函數程式碼輸出日誌，您可以使用 [fmt 套件](https://golang.org/pkg/fmt/)上的方法，或任何能寫入 `stdout` 或 `stderr` 的記錄程式庫。下列範例使用[日誌套件](https://golang.org/pkg/log/)。

**Example [main.go](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-go/function/main.go) - 記錄**  

```
func handleRequest(ctx context.Context, event events.SQSEvent) (string, error) {
  // event
  eventJson, _ := json.MarshalIndent(event, "", "  ")
  log.Printf("EVENT: %s", eventJson)
  // environment variables
  log.Printf("REGION: %s", os.Getenv("AWS_REGION"))
  log.Println("ALL ENV VARS:")
  for _, element := range os.Environ() {
    log.Println(element)
  }
```

**Example 記錄格式**  

```
START RequestId: dbda340c-xmpl-4031-8810-11bb609b4c71 Version: $LATEST
2020/03/27 03:40:05 EVENT: {
  "Records": [
    {
      "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78",
      "receiptHandle": "MessageReceiptHandle",
      "body": "Hello from SQS!",
      "md5OfBody": "7b27xmplb47ff90a553787216d55d91d",
      "md5OfMessageAttributes": "",
      "attributes": {
        "ApproximateFirstReceiveTimestamp": "1523232000001",
        "ApproximateReceiveCount": "1",
        "SenderId": "123456789012",
        "SentTimestamp": "1523232000000"
      },
      ...
2020/03/27 03:40:05 AWS_LAMBDA_LOG_STREAM_NAME=2020/03/27/[$LATEST]569cxmplc3c34c7489e6a97ad08b4419
2020/03/27 03:40:05 AWS_LAMBDA_FUNCTION_NAME=blank-go-function-9DV3XMPL6XBC
2020/03/27 03:40:05 AWS_LAMBDA_FUNCTION_MEMORY_SIZE=128
2020/03/27 03:40:05 AWS_LAMBDA_FUNCTION_VERSION=$LATEST
2020/03/27 03:40:05 AWS_EXECUTION_ENV=AWS_Lambda_go1.x
END RequestId: dbda340c-xmpl-4031-8810-11bb609b4c71
REPORT RequestId: dbda340c-xmpl-4031-8810-11bb609b4c71	Duration: 38.66 ms	Billed Duration: 243 ms	Memory Size: 128 MB	Max Memory Used: 54 MB	Init Duration: 203.69 ms	
XRAY TraceId: 1-5e7d7595-212fxmpl9ee07c4884191322	SegmentId: 42ffxmpl0645f474	Sampled: true
```

Go 執行時間會記錄每次調用的 `START`、`END` 和 `REPORT` 行。報告明細行提供下列詳細資訊。

**REPORT 行資料欄位**
+ **RequestId** - 進行調用的唯一請求 ID。
+ **持續時間** - 函數的處理常式方法處理事件所花費的時間量。
+ **計費持續時間** - 調用的計費時間量。
+ **記憶體大小** - 分配給函數的記憶體數量。
+ **使用的記憶體上限** - 函數所使用的記憶體數量。當調用共用執行環境時，Lambda 會報告所有調用使用的記憶體上限。此行為可能會導致報告值高於預期值。
+ **初始化持續時間** - 對於第一個提供的請求，這是執行期載入函數並在處理常式方法之外執行程式碼所花費的時間量。
+ **XRAY TraceId** - 對於追蹤的請求，這是 [AWS X-Ray 追蹤 ID](services-xray.md)。
+ **SegmentId** - 對於追蹤的請求，這是 X-Ray 區段 ID。
+ **已取樣** - 對於追蹤的請求，這是取樣結果。

## 在 Lambda 主控台檢視日誌
<a name="golang-logging-console"></a>

您可以在調用 Lambda 函數之後，使用 Lambda 主控台來檢視日誌輸出。

如果可以從內嵌**程式碼**編輯器測試您的程式碼，您會在**執行結果**中找到日誌。使用主控台測試功能以調用函數時，您會在**詳細資訊**區段找到**日誌輸出**。

## 在 CloudWatch 主控台中檢視 記錄
<a name="golang-logging-cwconsole"></a>

您可以使用 Amazon CloudWatch 主控台來檢視所有 Lambda 函數調用的日誌。

**若要在 CloudWatch 主控台上檢視日誌**

1. 在 CloudWatch 主控台上開啟[日誌群組頁面](https://console.aws.amazon.com/cloudwatch/home?#logs:)。

1. 選擇您的函數的日誌群組 (**/aws/lambda/*your-function-name***)。

1. 選擇日誌串流

每個日誌串流都會對應至[函式的執行個體](lambda-runtime-environment.md)。當您更新 Lambda 函數，以及建立其他執行個體以處理並行調用時，就會顯示日誌串流。若要尋找特定調用的日誌，建議您使用 檢測函數 AWS X-Ray。X-Ray 會在追蹤內記錄有關請求和日誌串流的詳細資訊。

## 使用 AWS Command Line Interface (AWS CLI) 檢視日誌
<a name="golang-logging-cli"></a>

是一種 AWS CLI 開放原始碼工具，可讓您使用命令列 Shell 中的 命令與 AWS 服務互動。若要完成本節中的步驟，您必須擁有 [AWS CLI 版本 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

您可以透過 [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)，使用 `--log-type` 命令選項來擷取要調用的日誌。其回應將包含 `LogResult` 欄位，內含該次調用的 base64 編碼日誌 (最大達 4 KB)。

**Example 擷取日誌 ID**  
下列範例顯示如何從名稱為 `my-function` 的函數的 `LogResult` 欄位來擷取*日誌 ID*。  

```
aws lambda invoke --function-name my-function out --log-type Tail
```
您應該會看到下列輸出：  

```
{
    "StatusCode": 200,
    "LogResult": "U1RBUlQgUmVxdWVzdElkOiA4N2QwNDRiOC1mMTU0LTExZTgtOGNkYS0yOTc0YzVlNGZiMjEgVmVyc2lvb...",
    "ExecutedVersion": "$LATEST"
}
```

**Example 解碼日誌**  
在相同的命令提示中，使用 `base64` 公用程式來解碼日誌。下列範例顯示如何擷取 `my-function` 的 base64 編碼日誌。  

```
aws lambda invoke --function-name my-function out --log-type Tail \
--query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode
```
如果您使用的是第 2 AWS CLI 版，則需要 **cli-binary-format**選項。若要讓此成為預設的設定，請執行 `aws configure set cli-binary-format raw-in-base64-out`。若要取得更多資訊，請參閱*《AWS Command Line Interface 使用者指南第 2 版》*中 [AWS CLI 支援的全域命令列選項](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)。  
您應該會看到下列輸出：  

```
START RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8 Version: $LATEST
"AWS_SESSION_TOKEN": "AgoJb3JpZ2luX2VjELj...", "_X_AMZN_TRACE_ID": "Root=1-5d02e5ca-f5792818b6fe8368e5b51d50;Parent=191db58857df8395;Sampled=0"",ask/lib:/opt/lib",
END RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8
REPORT RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8  Duration: 79.67 ms      Billed Duration: 80 ms         Memory Size: 128 MB     Max Memory Used: 73 MB
```
該 `base64` 公用程式可在 Linux、macOS 和 [Ubuntu on Windows](https://docs.microsoft.com/en-us/windows/wsl/install-win10) 上使用。macOS 使用者可能需要使用 `base64 -D`。

**Example get-logs.sh 指令碼**  
在相同的命令提示中，使用下列指令碼下載最後五個日誌事件。該指令碼使用 `sed` 以從輸出檔案移除引述，並休眠 15 秒以使日誌可供使用。輸出包括來自 Lambda 的回應以及來自 `get-log-events` 命令的輸出。  
複製下列程式碼範例的內容，並將您的 Lambda 專案目錄儲存為 `get-logs.sh`。  
如果您使用的是第 2 AWS CLI 版，則需要 **cli-binary-format**選項。若要讓此成為預設的設定，請執行 `aws configure set cli-binary-format raw-in-base64-out`。若要取得更多資訊，請參閱*《AWS Command Line Interface 使用者指南第 2 版》*中 [AWS CLI 支援的全域命令列選項](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)。  

```
#!/bin/bash
aws lambda invoke --function-name my-function --cli-binary-format raw-in-base64-out --payload '{"key": "value"}' out
sed -i'' -e 's/"//g' out
sleep 15
aws logs get-log-events --log-group-name /aws/lambda/my-function --log-stream-name stream1 --limit 5
```

**Example macOS 和 Linux (僅限)**  
在相同的命令提示中，macOS 和 Linux 使用者可能需要執行下列命令，以確保指令碼可執行。  

```
chmod -R 755 get-logs.sh
```

**Example 擷取最後五個記錄事件**  
在相同的命令提示中，執行下列指令碼以取得最後五個日誌事件。  

```
./get-logs.sh
```
您應該會看到下列輸出：  

```
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}
{
    "events": [
        {
            "timestamp": 1559763003171,
            "message": "START RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf Version: $LATEST\n",
            "ingestionTime": 1559763003309
        },
        {
            "timestamp": 1559763003173,
            "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tENVIRONMENT VARIABLES\r{\r  \"AWS_LAMBDA_FUNCTION_VERSION\": \"$LATEST\",\r ...",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003173,
            "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tEVENT\r{\r  \"key\": \"value\"\r}\n",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003218,
            "message": "END RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\n",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003218,
            "message": "REPORT RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\tDuration: 26.73 ms\tBilled Duration: 27 ms \tMemory Size: 128 MB\tMax Memory Used: 75 MB\t\n",
            "ingestionTime": 1559763018353
        }
    ],
    "nextForwardToken": "f/34783877304859518393868359594929986069206639495374241795",
    "nextBackwardToken": "b/34783877303811383369537420289090800615709599058929582080"
}
```

## 刪除日誌
<a name="golang-logging-delete"></a>

當您刪除函數時，不會自動刪除日誌群組。若要避免無限期地儲存日誌，請刪除日誌群組，或[設定保留期間](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#SettingLogRetention)，系統會在該時間之後自動刪除日誌。

# 在 中檢測 Go 程式碼 AWS Lambda
<a name="golang-tracing"></a>

Lambda 與 整合 AWS X-Ray ，以協助您追蹤、偵錯和最佳化 Lambda 應用程式。您可以使用 X-Ray 來追蹤請求，因為它會周遊您應用程式中的資源，其中可能包含 Lambda 函數和其他 AWS 服務。

若要將追蹤資料傳送至 X-Ray，您可以使用以下兩個 SDK 庫之一：
+ [AWS Distro for OpenTelemetry (ADOT)](https://aws.amazon.com/otel) – OpenTelemetry (OTel) SDK 的安全、生產就緒、 AWS支援的分發。
+ [AWS 適用於 Go 的 X-Ray 開發套件](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-go.html) – 用於產生追蹤資料並將其傳送至 X-Ray 的開發套件。

每個 SDK 均提供將遙測資料傳送至 X-Ray 服務的方法。然後，您可以使用 X-Ray 來檢視、篩選應用程式的效能指標並獲得洞察，從而識別問題和進行最佳化的機會。

**重要**  
X-Ray 和 Powertools AWS Lambda SDKs是 提供的緊密整合檢測解決方案的一部分 AWS。ADOT Lambda Layers 是用於追蹤檢測之業界通用標準的一部分，這類檢測一般會收集更多資料，但可能不適用於所有使用案例。您可以使用任一解決方案在 X-Ray 中實作端對端追蹤。若要深入了解如何在兩者之間做選擇，請參閱[在 AWS Distro for OpenTelemetry 和 X-Ray SDK 之間進行選擇](https://docs.aws.amazon.com/xray/latest/devguide/xray-instrumenting-your-app.html#xray-instrumenting-choosing)。

**Topics**
+ [

## 使用 ADOT 來檢測您的 Go 函數
](#golang-adot)
+ [

## 使用 X-Ray SDK 來檢測 Go 函數
](#golang-xray-sdk)
+ [

## 透過 Lambda 主控台來啟用追蹤
](#golang-tracing-console)
+ [

## 透過 Lambda API 啟用追蹤
](#golang-tracing-api)
+ [

## 使用 啟用追蹤 CloudFormation
](#golang-tracing-cloudformation)
+ [

## 解讀 X-Ray 追蹤
](#golang-tracing-interpretation)

## 使用 ADOT 來檢測您的 Go 函數
<a name="golang-adot"></a>

ADOT 提供全受管 Lambda [層](chapter-layers.md)，包含使用 OTel SDK 收集遙測資料所需的一切內容。透過取用此層，您可以檢測 Lambda 函數，而無需修改任何函數程式碼。您還可以將層設定為對 OTel 進行自訂初始化。如需詳細資訊，請參閱 ADOT 文件中的[針對 Lambda 上的 ADOT 收集器進行自訂組態設定](https://aws-otel.github.io/docs/getting-started/lambda#custom-configuration-for-the-adot-collector-on-lambda)。

針對 Go 執行階段，您可以新增**適用於 ADOT Go 的AWS 受管 Lambda 層**來自動檢測您的函數。如需有關如何新增此層的詳細資訊，請參閱 ADOT 文件中的[適用於 Go 的AWS Distro for OpenTelemetry Lambda 支援](https://aws-otel.github.io/docs/getting-started/lambda/lambda-go)。

## 使用 X-Ray SDK 來檢測 Go 函數
<a name="golang-xray-sdk"></a>

若要記錄 Lambda 函數對應用程式中其他資源進行的呼叫詳細資訊，您也可以使用 AWS X-Ray SDK for Go。如要取得 SDK，使用 `go get` 從 SDK 的 [GitHub 儲存庫](https://github.com/aws/aws-xray-sdk-go)下載即可：

```
go get github.com/aws/aws-xray-sdk-go
```

若要檢測 AWS SDK 用戶端，請將用戶端傳遞至 `xray.AWS()`方法。然後，便可以使用該方法的 `WithContext` 版本來追蹤呼叫。

```
svc := s3.New(session.New())
xray.AWS(svc.Client)
...
svc.ListBucketsWithContext(ctx aws.Context, input *ListBucketsInput)
```

新增正確的相依項並完成必要的程式碼變更後，請透過 Lambda 主控台或 API 在函數組態中啟用追蹤功能。

## 透過 Lambda 主控台來啟用追蹤
<a name="golang-tracing-console"></a>

若要使用控制台在 Lambda 函數上切換主動追蹤，請按照下列步驟操作：

**開啟主動追蹤**

1. 開啟 Lambda 主控台中的 [函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇一個函數。

1. 選擇**組態**，然後選擇**監控和操作工具**。

1. 在**其他監控工具**欄位中，選擇**編輯**。

1. 在 **CloudWatch Application Signals 和 AWS X-Ray** 下，選擇**啟用** **Lambda 服務追蹤**。

1. 選擇**儲存**。

## 透過 Lambda API 啟用追蹤
<a name="golang-tracing-api"></a>

使用 AWS CLI 或 AWS SDK 在 Lambda 函數上設定追蹤，請使用下列 API 操作：
+ [UpdateFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionConfiguration.html)
+ [GetFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html)
+ [CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html)

下列範例 AWS CLI 命令會在名為 **my-function** 的函數上啟用主動追蹤。

```
aws lambda update-function-configuration --function-name my-function \
--tracing-config Mode=Active
```

追蹤模式是您發布函數版本時版本特定組態的一部分。您無法變更已發佈版本上的追蹤模式。

## 使用 啟用追蹤 CloudFormation
<a name="golang-tracing-cloudformation"></a>

若要在 CloudFormation 範本中的 `AWS::Lambda::Function` 資源上啟用追蹤，請使用 `TracingConfig` 屬性。

**Example [function-inline.yml](https://github.com/awsdocs/aws-lambda-developer-guide/blob/master/templates/function-inline.yml) - 追蹤組態**  

```
Resources:
  function:
    Type: [AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)
    Properties:
      TracingConfig:
        Mode: Active
      ...
```

對於 AWS Serverless Application Model (AWS SAM) `AWS::Serverless::Function` 資源，請使用 `Tracing` 屬性。

**Example [template.yml](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-nodejs/template.yml) - 追蹤組態**  

```
Resources:
  function:
    Type: [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
    Properties:
      Tracing: Active
      ...
```

## 解讀 X-Ray 追蹤
<a name="golang-tracing-interpretation"></a>

您的函數需要將追蹤資料上傳至 X-Ray 的許可。當您在 Lambda 主控台中啟用追蹤時，Lambda 會將必要的許可新增至函數的[執行角色](lambda-intro-execution-role.md)。否則，請將 [AWSXRayDaemonWriteAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess) 政策新增至執行角色。

設定主動追蹤之後，您可以透過應用程式來觀察特定請求。[X-Ray 服務圖](https://docs.aws.amazon.com/xray/latest/devguide/aws-xray.html#xray-concepts-servicegraph)顯示了有關應用程式及其所有元件的資訊。下列範例顯示了一個具有兩個函數的應用程式。主要函式會處理事件，有時會傳回錯誤。頂端的第二個函數會處理出現在第一個日誌群組中的錯誤，並使用 AWS SDK 呼叫 X-Ray、Amazon Simple Storage Service (Amazon S3) 和 Amazon CloudWatch Logs。

![\[\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/images/sample-errorprocessor-servicemap.png)


X-Ray 無法追蹤應用程式的所有請求。X-Ray 會套用取樣演算法以確保追蹤的效率，同時仍提供所有請求的代表範本。取樣率為每秒 1 次請求和 5% 的額外請求。不能針對函數設定 X-Ray 取樣率。

在 X-Ray 中，*追蹤*會記錄一或多個*服務*所處理之要求的相關資訊。Lambda 會在每個追蹤上記錄 2 個區段，這會在服務圖表上建立兩個節點。下圖反白顯示了這兩個節點：

![\[\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/images/xray-servicemap-function.png)


左側第一個節點代表接收調用請求的 Lambda 服務。第二個節點代表您特定的 Lambda 函數。下列範例顯示了具有這 2 個區段的追蹤。兩者都被命名為 **my-function**，但其中之一的來源為 `AWS::Lambda`，而另一個的來源為 `AWS::Lambda::Function`。如果 `AWS::Lambda` 區段顯示錯誤，Lambda 服務就會出現問題。如果 `AWS::Lambda::Function` 區段顯示錯誤，表示您的函數出現了問題。

![\[\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/images/V2_sandbox_images/my-function-2-v1.png)


此範例會展開 `AWS::Lambda::Function` 區段以顯示其三個子區段：

**注意**  
AWS 目前正在對 Lambda 服務實作變更。由於這些變更，您可能會看到系統日誌訊息的結構和內容，與 AWS 帳戶中不同 Lambda 函數發出的追蹤區段之間存在細微差異。  
此處顯示的追蹤範例說明了舊式函數區段。下列段落說明了舊式和新式區段之間的差異。  
這些變化將在未來幾週內實作，除中國和 GovCloud 區域以外，所有 AWS 區域 中的所有函數都會轉換至使用新格式的日誌訊息和追蹤區段。

舊式函數區段包含下列子區段：
+ **初始化** - 表示載入函數和執行[初始化程式碼](foundation-progmodel.md)所花費的時間。只有函數的每個執行個體所處理的第一個事件會顯示此子區段。
+ **調用** – 表示執行處理常式程式碼所花費的時間。
+ **額外負荷** - 表示 Lambda 執行期為做好準備以處理下一個事件所花費的時間。

新式函數區段不包含 `Invocation` 子區段。相反地，客戶子區段會直接連接至函數區段。如需舊式和新式函數區段結構的詳細資訊，請參閱[了解 X-Ray 追蹤](services-xray.md#services-xray-traces)。

您也可以檢測 HTTP 用戶端、記錄 SQL 查詢，以及建立具有註釋和中繼資料的自訂子區段。如需詳細資訊，請參閱*《AWS X-Ray 開發人員指南》*中的[適用於 Go 的AWS X-Ray 開發套件](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-python.html)。

**定價**  
您可以在每月免費使用 X-Ray 追蹤，最高可達特定限制，作為 AWS 免費方案的一部分。達到閾值後，X-Ray 會收取追蹤儲存及擷取的費用。如需詳細資訊，請參閱 [AWS X-Ray 定價](https://aws.amazon.com/xray/pricing/)。