Runtime Node.js 18.x đã có sẵn trên AWS Lambda

Bài viết này được viết bởi Suraj Tripathi, Cloud Consultant, AppDev.

Bạn hiện có thể phát triển các chức năng AWS Lambda bằng Node.js 18 runtime. Phiên bản này đang ở trạng thái active LTS và được xem là đã sẵn sàng cho việc sử dụng chung. Khi tạo hoặc cập nhật các chức năng, chỉ định một giá trị tham số runtime của nodejs18.x hoặc sử dụng hình ảnh base container thích hợp để sử dụng runtime mới này.

Phiên bản runtime này được hỗ trợ bởi các chức năng chạy trên bộ xử lý AWS Graviton2 dựa trên Arm hoặc các bộ xử lý dựa trên x86. Sử dụng tùy chọn kiến ​​trúc bộ xử lý Graviton2 cho phép bạn đạt được hiệu suất giá thành tốt hơn đến 34%.

Bài đăng trên blog này giải thích những thay đổi chính có sẵn với Node.js 18 runtime trên Lambda.

Nâng cấp AWS SDK cho JavaScript lên phiên bản v3

Phiên bản runtime Node.js của Lambda bao gồm AWS SDK cho JavaScript. Điều này cho phép khách hàng sử dụng AWS SDK để kết nối với các dịch vụ AWS khác từ mã chức năng của họ, mà không cần phải bao gồm AWS SDK trong quá trình triển khai chức năng của họ. Điều này đặc biệt hữu ích khi tạo chức năng trong Bảng điều khiển Quản lý AWS. Nó cũng hữu ích cho các chức năng Lambda triển khai là mã nội tuyến trong các mẫu CloudFormation.

Cho đến phiên bản Node.js 16, các runtime Node.js của Lambda đã bao gồm AWS SDK cho JavaScript phiên bản 2. Sau đó, phiên bản này đã được thay thế bởi AWS SDK cho JavaScript phiên bản 3, được phát hành vào tháng 12 năm 2020. Với phiên bản này, Lambda đã nâng cấp phiên bản của AWS SDK cho JavaScript được bao gồm trong runtime từ v2 lên v3.

Nếu các chức năng Lambda hiện có của bạn đang sử dụng SDK v2 được bao gồm, thì bạn phải cập nhật mã chức năng của mình để sử dụng SDK v3 khi nâng cấp lên phiên bản Node.js 18. Đây là phương pháp được khuyến nghị khi nâng cấp các chức năng hiện có lên Node.js 18. Theo cách khác, bạn có thể sử dụng phiên bản runtime Node.js 18 mà không cập nhật mã hiện có nếu bạn triển khai SDK v2 cùng với mã chức năng của bạn.

Phiên bản 3 của SDK cho JavaScript cung cấp nhiều lợi ích hơn so với phiên bản 2. Quan trọng nhất là nó được modular hóa, vì vậy mã của bạn chỉ tải các module mà nó cần. Modular cũng giảm kích thước chức năng của bạn nếu bạn chọn triển khai SDK cùng với mã chức năng của bạn thay vì sử dụng phiên bản được tích hợp trong runtime của Lambda. Tìm hiểu thêm về tối ưu hóa các phụ thuộc Node.js trong Lambda tại đây.

Ví dụ, đối với một chức năng tương tác với Amazon S3 sử dụng SDK v2, bạn nhập toàn bộ SDK, mặc dù bạn không sử dụng hầu hết các module của nó:

JavaScript

const AWS = require(“aws-sdk”);

Với SDK v3, bạn chỉ import các module mà bạn cần, chẳng hạn như ListBucketsCommand và một service client như S3Client.

JavaScript

import { S3Client, ListBucketsCommand } from “@aws-sdk/client-s3”;

Một điểm khác biệt giữa SDK v2 và SDK v3 là các thiết lập mặc định cho việc tái sử dụng kết nối TCP. Trong SDK v2, tái sử dụng kết nối bị vô hiệu hóa theo mặc định. Trong SDK v3, nó được kích hoạt theo mặc định. Trong hầu hết các trường hợp, kích hoạt tái sử dụng kết nối sẽ cải thiện hiệu suất chức năng. Để ngăn chặn tái sử dụng kết nối TCP, hãy thiết lập biến môi trường AWS_NODEJS_CONNECTION_REUSE_ENABLED thành false. Bạn cũng có thể ngừng giữ kết nối hoạt động trên một cơ sở khách hàng dịch vụ.

Để biết thêm thông tin, hãy xem tại sao và làm thế nào bạn nên sử dụng AWS SDK cho JavaScript (v3) trên Node.js 18.

Hỗ trợ giải quyết các module ES bằng NODE_PATH

Một thay đổi khác trong runtime Node.js 18 là việc hỗ trợ giải quyết các module ES thông qua biến môi trường NODE_PATH.

Module ES được hỗ trợ bởi runtime Node.js 14 và Node.js 16 của Lambda. Chúng cho phép top-level await, điều này có thể làm giảm thời gian chờ khi khởi tạo (cold start) khi được sử dụng với Provisioned Concurrency. Tuy nhiên, theo mặc định, Node.js không tìm kiếm các thư mục trong biến môi trường NODE_PATH khi nhập các module ES. Điều này làm cho việc nhập các module ES từ các thư mục bên ngoài thư mục /var/task/ mà mã hàm được triển khai trở nên khó khăn. Ví dụ, để tải AWS SDK được bao gồm trong runtime dưới dạng module ES hoặc để tải các module ES từ các lớp Lambda.

Runtime Node.js 18.x cho Lambda tìm kiếm các thư mục được liệt kê trong NODE_PATH khi tải các module ES. Điều này làm cho việc bao gồm AWS SDK dưới dạng module ES hoặc tải các module ES từ các lớp Lambda dễ dàng hơn.

Cập nhật Node.js 18 

Điều chỉnh cho Node.js 18 runtime cho phép bạn tận dụng các tính năng mới của Node.js 18. Bao gồm cải tiến hiệu suất cho các trường lớp và phương thức lớp riêng tư, khai báo nhập JSON và các tính năng thử nghiệm như Fetch API, Test Runner module và Web Streams API.

Khai báo nhập JSON

Tính năng khai báo nhập cho phép các câu lệnh nhập mô-đun bao gồm thông tin bổ sung kèm theo bên cạnh module specifier. Bây giờ, đoạn code sau là hợp lệ:

JavaScript

// index.mjs

// static import

import fooData from ‘./foo.json’ assert { type: ‘json’ };

// dynamic import

const { default: barData } = await import(‘./bar.json’, { assert: { type: ‘json’ } });

export const handler = async(event) => {

    console.log(fooData)

    // logs data in foo.json file

    console.log(barData)

    // logs data in bar.json file

    const response = {

        statusCode: 200,

        body: JSON.stringify(‘Hello from Lambda!’),

    };

    return response;

};

JavaScript

foo.json

{

  “foo1” : “1234”,

  “foo2” : “4678”

}

JavaScript

bar.json

{

  “bar1” : “0001”,

  “bar2” : “0002”

}

Các tính năng thử nghiệm

Mặc dù vẫn đang trong giai đoạn thử nghiệm, nhưng gói fetch API toàn cầu có sẵn mặc định trong Node.js 18. API bao gồm một hàm fetch, khiến cho việc sử dụng các polyfill fetch và gói HTTP bên thứ ba không còn cần thiết.

JavaScript

// index.mjs 

export const handler = async(event) => {

    const res = await fetch(‘https://nodejs.org/api/documentation.json’);

    if (res.ok) {

      const data = await res.json();

      console.log(data);

    }

    const response = {

        statusCode: 200,

        body: JSON.stringify(‘Hello from Lambda!’),

    };

    return response;

};

Các tính năng thử nghiệm trong Node.js có thể được bật / tắt thông qua biến môi trường NODE_OPTIONS. Ví dụ, để dừng API fetch thử nghiệm, bạn có thể tạo một biến môi trường Lambda NODE_OPTIONS và đặt giá trị là -no-experimental-fetch.

Với thay đổi này, nếu bạn chạy mã trước đó cho API fetch trong hàm Lambda của mình, nó sẽ ném một lỗi tham chiếu vì API fetch thử nghiệm bây giờ đã bị vô hiệu hóa.

Kết luận

Node.js 18 hiện được hỗ trợ bởi Lambda. Khi xây dựng các chức năng Lambda của bạn bằng cách sử dụng kiểu đóng gói lưu trữ zip, sử dụng giá trị tham số thời gian chạy là nodejs18.x để bắt đầu xây dựng với Node.js 18.

Bạn cũng có thể xây dựng các chức năng Lambda trong Node.js 18 bằng cách triển khai mã chức năng của bạn như một hình ảnh container sử dụng hình ảnh cơ sở Node.js 18 AWS cho Lambda. Bạn có thể tìm hiểu thêm về viết chức năng trong Node.js 18 bằng cách đọc về mô hình lập trình Node.js trong tài liệu Lambda.

Đối với các chức năng Node.js hiện có, hãy xem xét mã của bạn để tương thích với Node.js 18, bao gồm các khấu hao, sau đó chuyển đổi sang thời gian chạy mới bằng cách thay đổi cấu hình thời gian chạy của chức năng thành nodejs18.x.

Để tìm hiểu thêm về nguồn tài nguyên học tập về serverless, hãy truy cập Serverless Land.

Leave a comment