Bởi Julian Wood | vào ngày 06 tháng 02 năm 2024 | trong Amazon API Gateway, AWS Lambda, AWS Serverless Application Model, Java, Serverless
Bài viết này được viết bởi Dennis Kieselhorst, Kiến trúc sư Giải.
Kết hợp giữa tính di động, hiệu suất, cộng đồng và đa dạng tính năng đã khiến cho Java trở thành lựa chọn phổ biến cho các doanh nghiệp xây dựng ứng dụng của họ trong hơn 25 năm qua. Sự ra đời của các serverless, được tiên phong bởi AWS Lambda, đã thay đổi những gì bạn cần trong một ngôn ngữ lập trình và môi trường chạy. Các hàm thường tồn tại ngắn hạn, chỉ phục vụ một mục đích và không đòi hỏi cấu hình cơ sở hạ tầng phức tạp.
Bài đăng blog này cho thấy bạn có thể hiện đại hóa một ứng dụng Java cũ để chạy trên Lambda với ít thay đổi mã bằng cách sử dụng AWS Serverless Java Container đã được cập nhật.
So sánh các mô hình triển khai
Các ứng dụng Java cổ điển thường chạy trên các application servers như JBoss/ WildFly, Oracle WebLogic và IBM WebSphere, hoặc các container servlet như Apache Tomcat. Máy ảo Java cơ bản thường chạy liên tục 24/7 và phục vụ nhiều yêu cầu bằng khả năng đa luồng của nó.
Đặc trưng của máy chủ ứng dụng Java chạy trong thời gian dài
Khi xây dựng các hàm Lambda bằng Java, không còn cần máy chủ HTTP và có những yếu tố khác cần xem xét khi chạy mã trong môi trường Lambda. Mã chạy trong môi trường thực thi, xử lý một lời gọi duy nhất mỗi lần. Các hàm có thể chạy trong khoảng tối đa 15 phút với tối đa 10 GB bộ nhớ được cấp phát.
Chức năng được kích hoạt bởi các sự kiện như yêu cầu HTTP với một tải trọng tương ứng. Một yêu cầu HTTP từ API Gateway Amazon kích hoạt chức năng với tải trọng JSON sau đây:
Dữ liệu từ HTTP request của Amazon API Gateway
Đoạn code để xử lý các sự kiện này khác với cách bạn triển khai nó trong một ứng dụng truyền thống.
AWS Serverless Java Container
AWS Serverless Java Container giúp việc chạy các ứng dụng Java viết bằng các framework như Spring, Spring Boot hoặc JAX-RS/Jersey trở nên dễ dàng hơn trong Lambda.
Container cung cấp logic adapter để giảm thiểu sự thay đổi trong code. Các sự kiện đầu vào được dịch sang đặc tả Servlet để các framework hoạt động như trước đây.
AWS Serverless Java Container adapter
Phiên bản đầu tiên của thư viện này đã được phát hành vào năm 2018. Hôm nay, AWS thông báo về việc phát hành phiên bản 2, hỗ trợ các đặc tả mới nhất của Jakarta EE, cùng với Spring Framework 6.x, Spring Boot 3.x và Jersey 3.x.
Ví dụ: Chuyển đổi một ứng dụng Spring Boot
Dưới đây là ví dụ minh họa cách di dời một ứng dụng Spring Boot 3. Bạn có thể tìm thấy ví dụ đầy đủ cho Spring và các framework khác trong GitHub repository.
- Thêm một dependency AWS Serverless Java vào tệp build POM Maven của bạn (hoặc Gradle tương ứng):
| <dependency> <groupId>com.amazonaws.serverless</groupId> <artifactId>aws-serverless-java-container-springboot3</artifactId> <version>2.0.0</version> </dependency> |
- Spring Boot, theo mặc định, sẽ nhúng Apache Tomcat để xử lý các yêu cầu HTTP. Các ví dụ sử dụng Amazon API Gateway để xử lý các yêu cầu HTTP đến nên bạn có thể loại bỏ phụ thuộc.
| <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <artifactSet> <excludes> <exclude>org.apache.tomcat.embed:*</exclude> </excludes> </artifactSet> </configuration> </execution> </executions> </plugin> </plugins> </build> |
AWS Serverless Java Container chấp nhận các request từ proxy của API Gateway và biến đổi chúng thành một đối tượng Java phẳng. Thư viện cũng biến đổi các outputs thành một object phù hợp với API Gateway.
Một khi bạn chạy quá trình xử lý, Plugin Shade của Maven bây giờ tạo ra một Uber-JAR gói gọn tất cả các dependencies, mà bạn có thể tải lên Lambda.
- Lambda runtime sẽ biết phương thức xử lý nào để gọi. Bạn có thể cấu hình và sử dụng triển khai SpringDelegatingLambdaContainerHandler hoặc triển khai lớp xử lý Java riêng mà chuyển giao cho AWS Serverless Java Container. Điều này hữu ích nếu bạn muốn thêm chức năng bổ sung.
- Cấu hình tên cho bộ xử lý trong quá trình thực thi cho chức năng của bạn.
Cấu hình tên trình xử lý
- Cấu hình một biến môi trường có tên MAIN_CLASS để cho phép trình xử lý chung biết nơi tìm kiếm các main class trong ứng dụng gốc của bạn, thường được chú thích bằng @SpringBootApplication.
Cấu hình biến môi trường MAIN_CLASS
Bạn cũng có thể cấu hình các thiết lập này bằng cách sử dụng các công cụ infrastructure as code (IaC) như AWS CloudFormation,, AWS Cloud Development Kit (AWS CDK), hoặc AWS Serverless Application Model (AWS SAM).
Trong một mẫu AWS SAM, các thay đổi liên quan như sau. Các mẫu đầy đủ là một phần của GitHub repository.
| Handler: com.amazonaws.serverless.proxy.spring.SpringDelegatingLambdaContainerHandler Environment: Variables: MAIN_CLASS: com.amazonaws.serverless.sample.springboot3.Application |
Cấu hình tối ưu hóa bộ nhớ
Khi chạy các chức năng Lambda, thời gian khởi động và bộ nhớ đệm là những yếu tố quan trọng cần xem xét. Số lượng bộ nhớ bạn cấu hình cho chức năng Lambda của mình cũng xác định số lượng CPU ảo có sẵn. Thêm bộ nhớ hơn tăng tỷ lệ số lượng CPU, và do đó tăng cường công suất tính toán tổng thể có sẵn. Nếu một chức năng bị ràng buộc bởi CPU, mạng hoặc bộ nhớ, việc thêm bộ nhớ có thể cải thiện hiệu suất.
Lambda tính phí cho tổng số gigabyte-giây tiêu thụ bởi một hàm. Gigabyte-seconds là sự kết hợp của tổng bộ nhớ (theo đơn vị gigabyte) và thời lượng (theo đơn vị giây). Tăng bộ nhớ gây ra chi phí bổ sung. Tuy nhiên, trong nhiều trường hợp, việc tăng bộ nhớ có thể làm giảm thời lượng của hàm do sự sẵn có thêm CPU. Kết quả là, tăng chi phí tổng thể có thể không đáng kể cho hiệu suất bổ sung, hoặc thậm chí có thể giảm đi.
Chọn bộ nhớ được cấp cho các hàm Lambda của bạn là một quá trình tối ưu hóa cân bằng giữa tốc độ (thời gian thực thi) và chi phí. Bạn có thể thử nghiệm thủ công các hàm bằng cách chọn các phân bổ bộ nhớ khác nhau và đo thời gian hoàn thành. AWS Lambda Power Tuning là một công cụ để đơn giản hóa và tự động hóa quá trình, mà bạn có thể sử dụng để tối ưu hóa cấu hình của mình.
Power Tuning sử dụng AWS Step Functions để chạy nhiều phiên bản song song của một hàm Lambda ở các phân bổ bộ nhớ khác nhau và đo lường hiệu suất. Hàm chạy trong tài khoản AWS của bạn, thực hiện cuộc gọi HTTP trực tiếp và tương tác SDK, để đo lường hiệu suất trong một kịch bản sản xuất
Cải thiện thời gian khởi động với AWS Lambda SnapStart.
Ứng dụng truyền thống thường có một lượng lớn các dependencies. Lambda tải code và khởi tạo các dependencies trong giai đoạn khởi tạo vòng đời Lambda. Với nhiều dependencies, thời gian khởi tạo này có thể quá lâu đối với yêu cầu của bạn. AWS Lambda SnapStart cho các chức năng dựa trên Java có thể cung cấp hiệu suất khởi động nhanh gấp đến 10 lần.
Thay vì chạy giai đoạn khởi tạo hàm mỗi lần cold-start, Lambda SnapStart chạy quá trình khởi tạo hàm vào thời điểm triển khai. Lambda tạo một bản snapshot của môi trường thực thi đã khởi tạo. Bản snapshot này được mã hóa và lưu trữ trong một bộ nhớ cache phân tầng để truy cập với độ trễ thấp. Khi hàm được gọi và mở rộng, Lambda tiếp tục môi trường thực thi từ bản chụp đã lưu thay vì chạy quá trình khởi tạo đầy đủ. Điều này dẫn đến thời gian khởi động thấp hơn.
Để kích hoạt Lambda SnapStart, bạn phải trước tiên kích hoạt cài đặt cấu hình, và cũng phải xuất bản một phiên bản chức năng.
Enabling SnapStart
Đảm bảo bạn chỉ định API Gateway đến phiên bản đã xuất bản hoặc một alias để đảm bảo bạn đang sử dụng chức năng SnapStart được kích hoạt.
Các thiết lập tương ứng trong mẫu AWS SAM chứa các thông tin sau:
| SnapStart: ApplyOn: PublishedVersions AutoPublishAlias: my-function-alias |
Hãy đọc các yếu tố tương thích Lambda SnapStart trong tài liệu vì ứng dụng của bạn có thể chứa mã cụ thể cần chú ý.
Kết luận
Khi xây dựng ứng dụng serverless với Lambda, bạn có thể triển khai tính năng nhanh hơn, nhưng ngôn ngữ và runtime của bạn phải hoạt động trong mô hình kiến trúc serverless. AWS Serverless Java Container giúp kết nối giữa các ứng dụng Java Enterprise truyền thống và các chức năng serverless hiện đại trên đám mây.
Bạn có thể cấu hình tối ưu hóa bộ nhớ của chức năng Lambda Java của bạn bằng công cụ AWS Lambda Power Tuning và kích hoạt SnapStart để tối ưu hóa thời gian khởi động lạnh ban đầu.
Java on AWS Lambda cho thấy cách xây dựng ứng dụng Java cloud-native và chuyển đổi ứng dụng Java hiện có sang Lambda.
Khám phá repo GitHub AWS Serverless Java Container nơi bạn có thể báo cáo các vấn đề liên quan và yêu cầu tính năng.
Để biết thêm tài nguyên học tập không máy chủ, truy cập Serverless Land.