Runtime Java untuk Instans Terkelola Lambda - AWS Lambda

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Runtime Java untuk Instans Terkelola Lambda

Untuk runtime Java, Instans Terkelola Lambda menggunakan thread OS untuk konkurensi. Lambda memuat objek handler Anda sekali per lingkungan eksekusi selama inisialisasi dan kemudian membuat beberapa utas. Thread ini dijalankan secara paralel dan memerlukan penanganan status dan sumber daya bersama yang aman untuk thread-safe. Setiap thread berbagi objek handler yang sama dan bidang statis apa pun.

Konfigurasi konkurensi

Jumlah maksimum permintaan bersamaan yang dikirim Lambda ke setiap lingkungan eksekusi dikendalikan oleh pengaturan PerExecutionEnvironmentMaxConcurrency dalam konfigurasi fungsi. Ini adalah pengaturan opsional, dan nilai default bervariasi tergantung pada runtime. Untuk runtime Java, defaultnya adalah 32 permintaan bersamaan per vCPU, atau Anda dapat mengonfigurasi nilai Anda sendiri. Nilai ini juga menentukan jumlah thread yang digunakan oleh runtime Java. Lambda secara otomatis menyesuaikan jumlah permintaan bersamaan hingga maksimum yang dikonfigurasi berdasarkan kapasitas setiap lingkungan eksekusi untuk menyerap permintaan tersebut.

Membangun fungsi untuk multi-konkurensi

Anda harus menerapkan praktik keamanan utas yang sama saat menggunakan Instans Terkelola Lambda seperti yang Anda lakukan di lingkungan multi-utas lainnya. Karena objek handler dibagikan di semua utas pekerja runtime, status apa pun yang bisa berubah harus aman untuk utas. Ini termasuk koleksi, koneksi database, dan objek statis apa pun yang dimodifikasi selama pemrosesan permintaan.

AWS Klien SDK aman untuk utas dan tidak memerlukan penanganan khusus.

Contoh: Kolam koneksi database

Kode berikut menggunakan objek koneksi database statis yang dibagi antara thread. Bergantung pada pustaka koneksi yang digunakan, ini mungkin tidak aman untuk utas.

public class DBQueryHandler implements RequestHandler<Object, String> { // Single connection shared across all threads - NOT SAFE private static Connection connection; public DBQueryHandler() { this.connection = DriverManager.getConnection(jdbcUrl, username, password); } @Override public String handleRequest(Object input, Context context) { PreparedStatement stmt = connection.prepareStatement(query); ResultSet rs = stmt.executeQuery(); // Multiple threads using same connection causes issues return result.toString(); } }

Pendekatan thread-safe adalah dengan menggunakan kumpulan koneksi. Dalam contoh berikut, fungsi handler mengambil koneksi dari pool. Koneksi hanya digunakan dalam konteks permintaan tunggal.

public class DBQueryHandler implements RequestHandler<Object, String> { private static HikariDataSource dataSource; public DBQueryHandler() { HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://localhost:3306/your_database"); dataSource = new HikariDataSource(config); // Create pool once per Lambda container } @Override public String handleRequest(Object input, Context context) { String query = "SELECT column_name FROM your_table LIMIT 10"; StringBuilder result = new StringBuilder("Data:\n"); // try-with-resources automatically calls close() on the connection, // which returns it to the HikariCP pool (does NOT close the physical DB connection) try (Connection connection = dataSource.getConnection(); PreparedStatement stmt = connection.prepareStatement(query); ResultSet rs = stmt.executeQuery()) { while (rs.next()) { result.append(rs.getString("column_name")).append("\n"); } } catch (Exception e) { context.getLogger().log("Error: " + e.getMessage()); return "Error"; } return result.toString(); } }

Contoh: Koleksi

Koleksi Java standar tidak aman untuk utas:

public class Handler implements RequestHandler<Object, String> { private static List<String> items = new ArrayList<>(); private static Map<String, Object> cache = new HashMap<>(); @Override public String handleRequest(Object input, Context context) { items.add("list item"); // Not thread-safe cache.put("key", input); // Not thread-safe return "Success"; } }

Sebagai gantinya, gunakan koleksi yang aman untuk utas:

public class Handler implements RequestHandler<Object, String> { private static final List<String> items = Collections.synchronizedList(new ArrayList<>()); private static final ConcurrentHashMap<String, Object> cache = new ConcurrentHashMap<>(); @Override public String handleRequest(Object input, Context context) { items.add("list item"); // Thread-safe cache.put("key", input); // Thread-safe return "Success"; } }

Direktori bersama/tmp

/tmpDirektori dibagikan di semua permintaan bersamaan di lingkungan eksekusi. Menulis bersamaan ke file yang sama dapat menyebabkan kerusakan data, misalnya jika proses lain menimpa file. Untuk mengatasinya, terapkan penguncian file untuk file bersama atau gunakan nama file unik per utas atau per permintaan untuk menghindari konflik. Ingatlah untuk membersihkan file yang tidak dibutuhkan untuk menghindari kehabisan ruang yang tersedia.

Logging

Log interleaving (entri log dari permintaan berbeda yang disisipkan dalam log) adalah normal dalam sistem multi-konkuren.

Fungsi yang menggunakan Instans Terkelola Lambda selalu menggunakan format log JSON terstruktur yang diperkenalkan dengan kontrol logging lanjutan. Format ini mencakuprequestId, memungkinkan entri log dikorelasikan dengan satu permintaan. Bila Anda menggunakan LambdaLogger objek dari context.getLogger() requestId secara otomatis disertakan dalam setiap entri log. Untuk informasi lebih lanjut, lihat Menggunakan kontrol logging lanjutan Lambda dengan Java.

Konteks permintaan

contextObjek terikat ke thread permintaan. Menggunakan context.getAwsRequestId() menyediakan akses thread-safe ke ID permintaan untuk permintaan saat ini.

Gunakan context.getXrayTraceId() untuk mengakses ID jejak X-Ray. Ini menyediakan akses thread-safe ke ID jejak untuk permintaan saat ini. Lambda tidak mendukung variabel _X_AMZN_TRACE_ID lingkungan dengan Instans Terkelola Lambda. ID jejak X-Ray disebarkan secara otomatis saat menggunakan AWS SDK.

Jika Anda menggunakan utas virtual dalam program Anda atau membuat utas selama inisialisasi, Anda harus meneruskan konteks permintaan yang diperlukan ke utas ini.

Inisialisasi dan shutdown

Inisialisasi fungsi terjadi sekali per lingkungan eksekusi. Objek yang dibuat selama inisialisasi dibagikan di seluruh utas.

Untuk fungsi Lambda dengan ekstensi, lingkungan eksekusi memancarkan sinyal SIGTERM saat dimatikan. Sinyal ini digunakan oleh ekstensi untuk memicu tugas pembersihan, seperti pembilasan buffer. Anda dapat berlangganan peristiwa SIGTERM untuk memicu tugas pembersihan fungsi, seperti menutup koneksi database. Untuk mempelajari lebih lanjut tentang siklus hidup lingkungan eksekusi, lihat Memahami siklus hidup lingkungan eksekusi Lambda.

Versi ketergantungan

Instans Terkelola Lambda memerlukan versi paket minimum berikut:

  • AWS SDK for Java 2.0: versi 2.34.0 atau yang lebih baru

  • AWS X-Ray SDK for Java: versi 2.20.0 atau yang lebih baru

  • AWS Distro untuk OpenTelemetry - Instrumentasi untuk Java: versi 2.20.0 atau yang lebih baru

  • Powertools untuk AWS Lambda (Java): versi 2.8.0 atau yang lebih baru

Powertools untuk AWS Lambda (Java)

Powertools untuk AWS Lambda (Java) kompatibel dengan Instans Terkelola Lambda dan menyediakan utilitas untuk logging, tracing, metrik, dan banyak lagi. Untuk informasi selengkapnya, lihat Powertools untuk AWS Lambda (Java).

Langkah selanjutnya