Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Tentukan penangan fungsi Lambda di Go
Handler fungsi Lambda Anda adalah metode dalam kode fungsi Anda yang memproses peristiwa. Saat fungsi Anda diaktifkan, Lambda menjalankan metode handler. Fungsi Anda berjalan sampai handler mengembalikan respons, keluar, atau batas waktu.
Halaman ini menjelaskan cara bekerja dengan penangan fungsi Lambda di Go, termasuk penyiapan proyek, konvensi penamaan, dan praktik terbaik. Halaman ini juga menyertakan contoh fungsi Go Lambda yang mengambil informasi tentang pesanan, menghasilkan tanda terima file teks, dan menempatkan file ini dalam bucket Amazon Simple Storage Service (Amazon S3). Untuk informasi tentang cara menerapkan fungsi Anda setelah menulisnya, lihat Deploy fungsi Go Lambda dengan arsip file .zip atauDeploy fungsi Lambda Go dengan gambar kontainer.
Topik
Menyiapkan proyek Handler Go Anda
Fungsi Lambda yang ditulis di Gogo mod init
go mod initexample-go
Di sini, example-go adalah nama modul. Anda dapat mengganti ini dengan apa saja. Perintah ini menginisialisasi proyek Anda dan menghasilkan go.mod file yang mencantumkan dependensi proyek Anda.
Gunakan go get perintah untuk menambahkan dependensi eksternal ke proyek Anda. Misalnya, untuk semua fungsi Lambda di Go, Anda harus menyertakan github. com/awsgo/lambdago get perintah berikut:
go get github.com/aws/aws-lambda-go
Kode fungsi Anda harus berada dalam file Go. Dalam contoh berikut, kami menamai file inimain.go. Dalam file ini, Anda mengimplementasikan logika fungsi inti Anda dalam metode handler, serta main() fungsi yang memanggil handler ini.
Contoh kode fungsi Go Lambda
Contoh kode fungsi Go Lambda berikut mengambil informasi tentang pesanan, menghasilkan tanda terima file teks, dan menempatkan file ini dalam bucket Amazon S3.
contoh Fungsi 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.goFile ini berisi bagian kode berikut:
-
package main: Di Go, paket yang berisifunc main()fungsi Anda harus selalu diberi namamain. -
importblok: Gunakan blok ini untuk menyertakan pustaka yang dibutuhkan fungsi Lambda Anda. -
type Order struct {}blok: Tentukan bentuk peristiwa input yang diharapkan dalam struct Go ini. -
var ()blok: Gunakan blok ini untuk menentukan variabel global apa pun yang akan Anda gunakan dalam fungsi Lambda Anda. -
func init() {}: Sertakan kode apa pun yang Anda ingin Lambda jalankan selama fase in isialisasi dalam metode iniinit(). -
func uploadReceiptToS3(...) {}: Ini adalah metode pembantu yang direferensikan oleh metodehandleRequesthandler utama. -
func handleRequest(ctx context.Context, event json.RawMessage) error {}: Ini adalah metode handler utama, yang berisi logika aplikasi utama Anda. -
func main() {}: Ini adalah titik masuk yang diperlukan untuk handler Lambda Anda. Argumen untuklambda.Start()metode ini adalah metode handler utama Anda.
Agar fungsi ini berfungsi dengan baik, peran pelaksanaannya harus memungkinkan s3:PutObject tindakan. Juga, pastikan Anda mendefinisikan variabel RECEIPT_BUCKET lingkungan. Setelah pemanggilan berhasil, bucket Amazon S3 harus berisi file tanda terima.
Konvensi penamaan handler
Untuk fungsi Lambda di Go, Anda dapat menggunakan nama apa pun untuk handler. Dalam contoh ini, nama metode handler adalahhandleRequest. Untuk mereferensikan nilai handler dalam kode Anda, Anda dapat menggunakan variabel _HANDLER lingkungan.
Untuk fungsi Go yang digunakan menggunakan paket pener apan.zip, file yang dapat dieksekusi yang berisi kode fungsi Anda harus diberi bootstrap nama. Selain itu, bootstrap file harus berada di root file.zip. Untuk fungsi Go yang digunakan menggunakan gambar kon tainer, Anda dapat menggunakan nama apa pun untuk file yang dapat dieksekusi.
Mendefinisikan dan mengakses objek peristiwa input
JSON adalah format input yang paling umum dan standar untuk fungsi Lambda. Dalam contoh ini, fungsi mengharapkan input yang mirip dengan berikut ini:
{ "order_id": "12345", "amount": 199.99, "item": "Wireless Headphones" }
Saat bekerja dengan fungsi Lambda di Go, Anda dapat menentukan bentuk peristiwa input yang diharapkan sebagai struct Go. Dalam contoh ini, kita mendefinisikan struct untuk mewakili: Order
type Order struct { OrderID string `json:"order_id"` Amount float64 `json:"amount"` Item string `json:"item"` }
Struct ini cocok dengan bentuk input yang diharapkan. Setelah Anda menentukan struct Anda, Anda dapat menulis tanda tangan handler yang mengambil tipe JSON generik yang kompatibel dengan pustaka encoding/json
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 ... }
Setelah deserialisasi ini, Anda dapat mengakses bidang variabel. order Misalnya, order.OrderID mengambil nilai "order_id" dari input asli.
catatan
encoding/jsonPaket hanya dapat mengakses bidang yang diekspor. Untuk diekspor, nama bidang dalam struktur peristiwa harus dalam huruf kapital.
Mengakses dan menggunakan objek konteks Lambda
Objek konteks Lambda berisi informasi tentang pemanggilan, fungsi, dan lingkungan eksekusi. Dalam contoh ini, kita mendeklarasikan variabel ini seperti ctx pada tanda tangan handler:
func handleRequest(ctx context.Context, event json.RawMessage) error { ... }
In ctx context.Context put adalah argumen opsional dalam handler fungsi Anda. Untuk informasi selengkapnya tentang tanda tangan handler yang diterima, lihatTanda tangan handler yang valid untuk penangan Go.
Jika Anda melakukan panggilan ke layanan lain menggunakan AWS SDK, objek konteks diperlukan di beberapa area utama. Misalnya, untuk menginisialisasi klien SDK dengan benar, Anda dapat memuat konfigurasi AWS SDK yang benar menggunakan objek konteks sebagai berikut:
// Load AWS SDK configuration using the default credential provider chain cfg, err := config.LoadDefaultConfig(ctx)
Panggilan SDK sendiri mungkin memerlukan objek konteks sebagai input. Misalnya, s3Client.PutObject panggilan menerima objek konteks sebagai argumen pertamanya:
// Upload the receipt to S3 _, err = s3Client.PutObject(ctx, &s3.PutObjectInput{ ... })
Di luar permintaan AWS SDK, Anda juga dapat menggunakan objek konteks untuk pemantauan fungsi. Untuk informasi selengkapnya tentang objek konteks, lihatMenggunakan objek konteks Lambda untuk mengambil informasi fungsi Go.
Tanda tangan handler yang valid untuk penangan Go
Anda memiliki beberapa pilihan ketika membangun handler fungsi Lambda di Go, tetapi Anda harus mematuhi aturan berikut:
-
Handler harus berupa fungsi.
-
Handler dapat mengambil antara 0 dan 2 argumen. Jika ada dua argumen, argumen pertama harus menerapkan
context.Context. -
Handler dapat mengembalikan antara 0 dan 2 argumen. Jika ada nilai kembali tunggal, nilai harus menerapkan
error. Jika ada dua nilai kembali, nilai kedua harus menerapkanerror.
Berikut ini mencantumkan tanda tangan handler yang valid. TIndan TOut mewakili tipe yang kompatibel dengan perpustakaan encoding/json standar. Untuk informasi selengkapnya, lihat func 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)
Menggunakan AWS SDK untuk Go v2 di handler Anda
Seringkali, Anda akan menggunakan fungsi Lambda untuk berinteraksi dengan atau membuat pembaruan ke AWS sumber daya lain. Cara paling sederhana untuk berinteraksi dengan sumber daya ini adalah dengan menggunakan AWS SDK untuk Go v2
catatan
AWS SDK untuk Go (v1) dalam mode pemeliharaan, dan akan mencapai akhir dukungan pada 31 Juli 2025. Kami menyarankan Anda hanya menggunakan AWS SDK untuk Go v2 ke depan.
Untuk menambahkan dependensi SDK ke fungsi Anda, gunakan go get perintah untuk klien SDK tertentu yang Anda butuhkan. Dalam contoh kode sebelumnya, kita menggunakan per config pustakaan dan per s3 pustakaan. Tambahkan dependensi ini dengan menjalankan perintah berikut di direktori yang berisi main.go file go.mod dan Anda:
go get github.com/aws/aws-sdk-go-v2/config go get github.com/aws/aws-sdk-go-v2/service/s3
Kemudian, impor dependensi yang sesuai di blok impor fungsi Anda:
import ( ... "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" )
Saat menggunakan SDK di handler Anda, konfigurasikan klien Anda dengan pengaturan yang tepat. Cara paling sederhana untuk melakukan ini adalah dengan menggunakan rantai penyedia kredensia default. Contoh ini menggambarkan satu cara untuk memuat konfigurasi ini:
// 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 }
Setelah memuat konfigurasi ini ke dalam cfg variabel, Anda dapat meneruskan variabel ini ke instansiasi klien. Kode contoh membuat klien Amazon S3 sebagai berikut:
// Create an S3 client s3Client := s3.NewFromConfig(cfg)
Dalam contoh ini, kami menginisialisasi klien Amazon S3 kami dalam init() fungsi untuk menghindari keharusan menginisialisasi setiap kali kami memanggil fungsi kami. Masalahnya adalah bahwa dalam init() fungsi, Lambda tidak memiliki akses ke objek konteks. Sebagai solusinya, Anda dapat memasukkan placeholder seperti context.TODO() selama fase inisialisasi. Kemudian, ketika Anda melakukan panggilan menggunakan klien, berikan objek konteks penuh. Solusi ini juga dijelaskan di. Menggunakan konteks di AWS Inisialisasi dan panggilan klien SDK
Setelah mengonfigurasi dan menginisialisasi klien SDK, Anda kemudian dapat menggunakannya untuk berinteraksi dengan AWS
layanan lain. Kode contoh memanggil PutObject API Amazon S3 sebagai berikut:
_, err = s3Client.PutObject(ctx, &s3.PutObjectInput{ Bucket: &bucketName, Key: &key, Body: strings.NewReader(receiptContent), })
Mengakses variabel lingkungan
Dalam kode handler Anda, Anda dapat mereferensikan variabel lingkungan apa pun dengan menggunakan os.Getenv() metode ini. Dalam contoh ini, kita mereferensi RECEIPT_BUCKET kan variabel lingkungan yang ditentukan menggunakan baris kode berikut:
// 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") }
Menggunakan status global
Untuk menghindari pembuatan sumber daya baru setiap kali Anda memanggil fungsi Anda, Anda dapat mendeklarasikan dan memodifikasi variabel global di luar kode handler fungsi Lambda Anda. Anda mendefinisikan variabel global ini dalam var blok atau pernyataan. Selain itu, handler Anda dapat mendeklarasikan init() fungsi yang dijalankan selama fase in isialisasi. initMetode ini berperilaku sama AWS Lambda seperti dalam program Go standar.
Praktik terbaik kode untuk fungsi Go Lambda
Patuhi pedoman dalam daftar berikut untuk menggunakan praktik pengkodean terbaik saat membangun fungsi Lambda Anda:
-
Pisahkan handler Lambda dari logika inti Anda. Dengan pendekatan ini, Anda dapat membuat fungsi yang lebih dapat diuji unit.
-
Minimalkan kompleksitas dependensi Anda. Utamakan memilih kerangka kerja lebih sederhana yang cepat dimuat dalam memulai lingkungan eksekusi.
-
Minimalkan ukuran paket penerapan Anda sesuai kebutuhan runtime. Ini mengurangi jumlah waktu yang diperlukan untuk paket penerapan Anda untuk diunduh dan dibongkar sebelum pemanggilan.
Manfaatkan penggunaan kembali lingkungan eksekusi untuk meningkatkan kinerja fungsi Anda. Inisialisasi klien SDK dan koneksi basis data di luar fungsi handler, dan lakukan caching aset statis secara lokal di direktori /tmp. Invokasi selanjutnya yang diproses oleh instans yang sama dari fungsi Anda dapat menggunakan kembali sumber daya ini. Ini menghemat biaya dengan mengurangi waktu pengoperasian fungsi.
Untuk menghindari potensi kebocoran data di seluruh invokasi, jangan menggunakan lingkungan eksekusi untuk menyimpan data pengguna, peristiwa, atau informasi lainnya implikasi keamanan. Jika fungsi Anda bergantung pada status yang dapat disenyapkan yang tidak dapat disimpan dalam memori di dalam handler, pertimbangkan untuk membuat fungsi terpisah atau versi terpisah dari fungsi untuk setiap pengguna.
Gunakan direktif keep-alive untuk mempertahankan koneksi yang persisten. Lambda membersihkan koneksi idle dari waktu ke waktu. Mencoba menggunakan ulang koneksi idle saat mengidentifikasi suatu fungsi akan menyebabkan kesalahan koneksi. Untuk mempertahankan koneksi yang persisten, gunakan arahan tetap aktif yang berkaitan dengan runtime Anda. Sebagai contoh, lihat Menggunakan Kem bali Koneksi dengan Keep-Alive in Node.js.
Gunakan variabel lingkungan untuk meneruskan parameter operasional ke fungsi Anda. Misalnya, jika Anda ingin menulis ke bucket Amazon S3 alih-alih melakukan hard-coding nama bucket yang Anda tulis, konfigurasikan nama bucket sebagai variabel lingkungan.
Hindari menggunakan pemanggilan rekursif dalam fungsi Lambda Anda, di mana fungsi memanggil dirinya sendiri atau memulai proses yang dapat memanggil fungsi lagi. Hal ini dapat menyebabkan volume invokasi fungsi yang tidak diinginkan dan peningkatan biaya. Jika Anda melihat volume pemanggilan yang tidak diinginkan, setel fungsi reservasi konkurensi ke 0 segera untuk membatasi semua pemanggilan ke fungsi, saat Anda memperbarui kode.
Jangan gunakan API non-publik yang tidak terdokumentasi dalam kode fungsi Lambda Anda. Untuk runtime AWS Lambda terkelola, Lambda secara berkala menerapkan pembaruan keamanan dan fungsional ke API internal Lambda. Pembaruan API internal ini mungkin tidak kompatibel ke belakang, yang menyebabkan konsekuensi yang tidak diinginkan seperti kegagalan pemanggilan jika fungsi Anda memiliki ketergantungan pada API non-publik ini. Lihat referensi API untuk daftar API yang tersedia untuk umum.
Tulis kode idempotent. Menulis kode idempotent untuk fungsi Anda memastikan bahwa peristiwa duplikat ditangani dengan cara yang sama. Kode Anda harus memvalidasi peristiwa dengan benar dan menangani peristiwa duplikat dengan anggun. Untuk informasi lebih lanjut, lihat Bagaimana cara membuat fungsi Lambda saya idempoten?