Bài viết này được viết bởi Jeff Gebhart, chuyên viên TAM, Serverless vào 14/12/2023. Xem bài gốc ở đây.
AWS Lambda hiện đã hỗ trợ Python 3.12 cả trong môi trường chạy quản lý và trong container base image. Python 3.12 tiếp tục phát triển từ những cải tiến về hiệu suất đã được phát hành lần đầu tiên với Python 3.11, và thêm vào đó là một số tính năng về hiệu suất và tính đọc hiểu ngôn ngữ trong trình thông dịch. Với phiên bản này, các nhà phát triển Python hiện có thể tận dụng những tính năng mới và cải tiến này khi tạo ứng dụng serverless trên AWS Lambda.
Bạn có thể sử dụng Python 3.12 với Powertools cho AWS Lambda (Python), một bộ công cụ phát triển để triển khai các thực hành tốt nhất về Serverless như tính quan sát, xử lý hàng loạt, Parameter Store integration, tính idempotency, feature flags, CloudWatch Metrics, và ghi log có cấu trúc trong số các tính năng khác.
Bạn cũng có thể sử dụng Python 3.12 với Lambda@Edge, cho phép bạn tùy chỉnh nội dung với độ thấp trễ được gửi qua Amazon CloudFront.
Python là một ngôn ngữ phổ biến để xây dựng các ứng dụng serverless. Phiên bản Python 3.12 có một số cải tiến về trình thông dịch và cú pháp.
Khi ra mắt, các môi trường chạy Lambda mới nhận được ít sự sử dụng hơn so với các môi trường chạy đã có, ổn định. Điều này có thể dẫn đến thời gian khởi động(cold start) kéo dài hơn do sự giảm sút của bộ nhớ cache trong các Lambda sub-system. Thời gian khởi động (cold start) thường được cải thiện trong vài tuần sau khi ra mắt khi lượng sử dụng tăng lên. Do đó, AWS khuyến nghị không rút ra kết luận từ các so sánh hiệu suất với các môi trường chạy Lambda khác cho đến khi hiệu suất đã ổn định. Khi hiệu suất phụ thuộc rất nhiều vào công việc, khách hàng có công việc nhạy cảm về hiệu suất nên thực hiện thử nghiệm của riêng mình, thay vì dựa vào các bài kiểm tra thử nghiệm chung (test benchmarks).
Sự thay đổi của Lambda runtime
Amazon Linux 2023
Runtime Python 3.12 dựa trên provided.al2023 runtime, dựa trên Amazon Linux 2023 minimal container image. Bản cập nhật hệ điều hành này mang lại một số cải tiến so với hệ điều hành dựa trên Amazon Linux 2 (AL2) được sử dụng cho runtime Python của Lambda từ Python 3.8 đến Python 3.11.
provided.al2023 chỉ chứa các thành phần cần thiết để cài đặt các gói khác và cung cấp một lượng triển khai nhỏ hơn 40MB so với hơn 100MB cho Lambda’s AL2-based images.
Với phiên bản glibc 2.34, khách hàng có quyền truy cập vào một phiên bản hiện đại của glibc, được cập nhật từ phiên bản 2.26 trong AL2-based images.
Amazon Linux 2023 minimal image sử dụng microdnf làm package manager, symlinked như dnf. Điều này thay thế yum package manager được sử dụng trong các AL2-based images trước đây. Nếu bạn triển khai các Lambda function của mình dưới dạng container images, bạn phải cập nhật Dockerfiles của mình để sử dụng dnf thay vì yum khi nâng cấp lên Python 3.12 base image.
Ngoài ra, curl và gnupg2 cũng được bao gồm dưới dạng các phiên bản minimal của chúng là curl-minimal và gnupg2-minimal.
Tìm hiểu thêm về provided.al2023 runtime trong bài đăng trên blog Giới thiệu runtime Amazon Linux 2023 cho AWS Lambda và bài đăng trên blog ra mắt Amazon Linux 2023.
Thay đổi định dạng trả về
Bắt đầu với runtime Python 3.12, các hàm trả về ký tự Unicode như một phần của phản hồi JSON của chúng. Các phiên bản trước đó trả về escaped sequences cho các ký tự Unicode trong các phản hồi.
Ví dụ, trong Python 3.11, nếu bạn trả về một chuỗi Unicode như “こんにちは”, nó sẽ thay các ký tự Unicode và trả về “\u3053\u3093\u306b\u3061\u306f”. Runtime Python 3.12 trả về chuỗi ban đầu “こんにちは”.
Thay đổi này giảm kích thước của dữ liệu trả về bởi Lambda. Trong ví dụ trước đó, phiên bản thay thế là 32 byte so với 17 byte với chuỗi Unicode. Sử dụng phản hồi Unicode giảm kích thước của các phản hồi Lambda, làm cho việc ghép các phản hồi lớn hơn vào giới hạn phản hồi Lambda 6MB (đồng bộ) dễ dàng hơn.
Khi nâng cấp lên Python 3.12, bạn có thể cần điều chỉnh mã của mình trong các module khác để tính đến hành vi mới này. Nếu người gọi hàm mong đợi các Unicode đã thoát dựa trên hành vi runtime trước đó, bạn phải thêm code vào hàm trả về để thay các kí tự Unicode một cách thủ công hoặc điều chỉnh người gọi để xử lý phản hồi Unicode.
Xử lý tiện ích mở rộng cho shutdown chuẩn
Các Lambda functions với các tiện ích mở rộng bên ngoài bây giờ có thể tận dụng các khả năng tắt máy mượt mà được cải thiện. Khi dịch vụ Lambda chuẩn bị shutdown, nó gửi một tín hiệu SIGTERM đến runtime và sau đó là một event SHUTDOWN đến mỗi tiện ích mở rộng bên ngoài đã đăng ký.
Những sự kiện này được gửi mỗi khi một môi trường thực thi tắt máy. Điều này cho phép bạn bắt tín hiệu SIGTERM trong hàm Lambda của mình và dọn dẹp tài nguyên, như kết nối cơ sở dữ liệu, được tạo ra bởi function.
Để tìm hiểu thêm về vòng đời môi trường thực thi Lambda, hãy xem Lambda execution environment. Thêm chi tiết và ví dụ về cách sử dụng tắt máy mềm mại với các tiện ích mở rộng có sẵn trong AWS Samples GitHub.
Các tính năng mới của Python
Bao quan nội tuyến Lồng ghép inline
Với việc sử dụng PEP 709, dictionary, list, và set hiện đã được inlined. Các phiên bản trước tạo một hàm dùng một lần để thực thi các comprehensions như vậy. Loại bỏ chi phí này dẫn đến việc thực thi comprehension nhanh hơn gấp đôi.
Có một số thay đổi về comprehensions do cập nhật này. Ví dụ, gọi đến hàm ‘locals()’ từ bên trong lồng ghép bây giờ bao gồm các đối tượng từ phạm vi chứa, không chỉ từ comprehension chính nó như trong các phiên bản trước. Bạn nên thử nghiệm các hàm bạn đang di chuyển từ một phiên bản trước của Python sang Python 3.12.
Thay đổi kiểu
Python 3.12 tiếp tục sự tiến triển của việc bao gồm chú thích kiểu vào Python. PEP 695 bao gồm một cú pháp mới, nhỏ gọn hơn cho các lớp và hàm chung, và thêm một câu lệnh “type” mới để cho phép tạo bí danh(alias). Bí danh kiểu được đánh giá khi cần. Điều này cho phép bí danh tham chiếu đến các kiểu khác được định nghĩa sau.
Các tham số kiểu hiển thị trong phạm vi của khai báo và bất kỳ phạm vi lồng nhau nào, nhưng không phải là phạm vi bên ngoài.
Hình thức của f-strings
Một trong những thay đổi lớn nhất trong Python 3.12, hình thức hóa cú pháp f-strings, được bao gồm dưới PEP 701. Bất kỳ biểu thức hợp lệ nào bây giờ có thể được chứa trong một f-string, bao gồm các f-string khác.
Trong các phiên bản trước của Python, việc sử dụng lại dấu ngoặc kép trong một f-string dẫn đến lỗi. Với Python 3.12, việc sử dụng lại dấu ngoặc kép được hỗ trợ hoàn toàn trong các f-string lồng nhau như ví dụ sau:
>>>songs = [‘Take me back to Eden’, ‘Alkaline’, ‘Ascensionism’]
>>>f”This is the playlist: {“, “.join(songs)}”
‘This is the playlist: Take me back to Eden, Alkaline, Ascensionism’
Ngoài ra, bất kỳ biểu thức Python hợp lệ nào cũng có thể được chứa trong một f-string. Điều này bao gồm các biểu thức nhiều dòng và khả năng nhúng ghi chú trong một f-string.
Trước Python 3.12, ký tự “\” không được phép trong một f-string. Điều này đã ngăn việc sử dụng cú pháp “\N” để định nghĩa các ký tự Unicode escaped trong phần thân của một f-string.
Cải thiện asyncio
Có một số cải tiến cho module asyncio. Các cải tiến này bao gồm cải thiện hiệu suất cho việc viết của sockets và một triển khai mới của asyncio.current_task() có thể mang lại cải thiện hiệu suất 4–6 lần. Event loop tối ưu hóa theo dõi môi trường nằm ở dưới.
Sử dụng Python 3.12 trong Lambda
Bảng điều khiển Quản lý AWS
Để sử dụng runtime Python 3.12 để phát triển các Lambda function của bạn, chỉ định một giá trị tham số runtime Python 3.12 khi tạo hoặc cập nhật một hàm. Phiên bản Python 3.12 hiện đã có sẵn trong danh sách thả xuống Runtime trong trang Create Function:
Để cập nhật một Lambda function hiện có lên Python 3.12, hãy điều hướng đến hàm đó trong Lambda console và chọn Edit trong Runtime settings. Phiên bản mới của Python sẵn có trong danh sách thả xuống Runtime:
AWS Lambda container image
Thay đổi phiên bản cơ sở Python bằng cách sửa câu lệnh FROM trong Dockerfile của bạn:
FROM public.ecr.aws/lambda/python:3.12
# Sao chép hàm
COPY lambda_handler.py ${LAMBDA_TASK_ROOT}
Khách hàng chạy các Python 3.12 Docker images ở local, bao gồm cả khách hàng sử dụng AWS SAM, phải nâng cấp cài đặt Docker của họ lên phiên bản 20.10.10 hoặc mới hơn.
AWS Serverless Application Model (AWS SAM)
Trong AWS SAM, đặt thuộc tính Runtime thành python3.12 để sử dụng phiên bản này.
| AWSTemplateFormatVersion: ‘2010-09-09’Transform: AWS::Serverless-2016-10-31Description: Simple Lambda Function MyFunction: Type: AWS::Serverless::Function Properties: Description: My Python Lambda Function CodeUri: my_function/ Handler: lambda_function.lambda_handler Runtime: python3.12 |
AWSTemplateFormatVersion: ‘2010-09-09’
Transform: AWS::Serverless-2016-10-31
Description: Simple Lambda Function
MyFunction:
Type: AWS::Serverless::Function
Properties:
Description: My Python Lambda Function
CodeUri: my_function/
Handler: lambda_function.lambda_handler
Runtime: python3.12
AWS SAM hỗ trợ tạo ra template này với Python 3.12 cho các ứng dụng serverless mới bằng lệnh `sam init`. Tham khảo tài liệu AWS SAM.
AWS Cloud Development Kit (AWS CDK)
Trong AWS CDK, đặt thuộc tính runtime thành Runtime.PYTHON_3_12 để sử dụng phiên bản này. Trong Python CDK:
| from constructs import Construct from aws_cdk import ( App, Stack, aws_lambda as _lambda ) class SampleLambdaStack(Stack): def __init__(self, scope: Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) base_lambda = _lambda.Function(self, ‘SampleLambda’, handler=’lambda_handler.handler’, runtime=_lambda.Runtime.PYTHON_3_12, code=_lambda.Code.from_asset(‘lambda’)) |
from constructs import Construct
from aws_cdk import ( App, Stack, aws_lambda as _lambda )
class SampleLambdaStack(Stack):
def __init__(self, scope: Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
base_lambda = _lambda.Function(self, ‘SampleLambda’,
handler=’lambda_handler.handler’,
runtime=_lambda.Runtime.PYTHON_3_12,
code=_lambda.Code.from_asset(‘lambda’))
Trong TypeScript CDK:
| import * as cdk from ‘aws-cdk-lib’;import * as lambda from ‘aws-cdk-lib/aws-lambda’import * as path from ‘path’;import { Construct } from ‘constructs’; export class CdkStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // The code that defines your stack goes here // The python3.12 enabled Lambda Function const lambdaFunction = new lambda.Function(this, ‘python311LambdaFunction’, { runtime: lambda.Runtime.PYTHON_3_12, memorySize: 512, code: lambda.Code.fromAsset(path.join(__dirname, ‘/../lambda’)), handler: ‘lambda_handler.handler’ }) }} |
import * as cdk from ‘aws-cdk-lib’;
import * as lambda from ‘aws-cdk-lib/aws-lambda’
import * as path from ‘path’;
import { Construct } from ‘constructs’;
export class CdkStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// The code that defines your stack goes here
// The python3.12 enabled Lambda Function
const lambdaFunction = new lambda.Function(this, ‘python311LambdaFunction’, {
runtime: lambda.Runtime.PYTHON_3_12,
memorySize: 512,
code: lambda.Code.fromAsset(path.join(__dirname, ‘/../lambda’)),
handler: ‘lambda_handler.handler’
})
}
}
Kết luận
Lambda hiện hỗ trợ Python 3.12. Bản phát hành này sử dụng hệ điều hành Amazon Linux 2023, hỗ trợ các phản hồi Unicode và tắt máy mượt mà cho các functions với các tiện ích mở rộng bên ngoài và các tính năng ngôn ngữ Python 3.12.
Bạn có thể xây dựng và triển khai các hàm sử dụng Python 3.12 bằng cách sử dụng AWS Management Console, AWS CLI, AWS SDK, AWS SAM, AWS CDK hoặc công cụ Infrastructure as Code (IaC). Bạn cũng có thể sử dụng Python 3.12 container base image nếu bạn muốn xây dựng và triển khai các hàm của mình bằng container images..
Việc hỗ trợ runtime Python 3.12 giúp các nhà phát triển xây dựng các ứng dụng serverless hiệu quả, mạnh mẽ và có khả năng mở rộng hơn. Hãy thử nghiệm runtime Python 3.12 trong Lambda ngay hôm nay và trải nghiệm các lợi ích của phiên bản ngôn ngữ này đã được cập nhật.
Để biết thêm tài nguyên học serverless, hãy truy cập Serverless Land.