Chuyển đổi nền tảng các ứng dụng Java bằng cách sử dụng Container Java Serverless cập nhật từ AWS.

Được viết bởi Dennis Kieselhorst, Principal Solutions Architect

Sự kết hợp giữa tính di động, sự hiệu quả, cộng đồng và phạm vi tính năng đã khiến Java trở thành 1 sự lựa chọn phổ biến cho doanh nghiệp để xây dựng lên những ứng dụng của họ trong hơn 25 năm qua. Sự ra đời của các serverless function, được tiên phong bởi AWS Lambda, đã thay đổi thứ mà bạn cần trong ngôn ngữ lập trình và môi trường runtime. Các function thường tồn tại trong thời gian ngắn, chỉ có 1 mục đích và không yêu cầu cấu hình cơ sở hạ tầng lớn.

Blog này sẽ cho bạn thấy bạn có thể hiện đại hóa ứng dụng Java cũ để chạy trên Lambda với ít sự thay đổi code khi sử dụng AWS Serverless Java Container. đã được cập nhật

So sánh mô hình triển khai

Các ứng dụng doanh nghiệp Java cổ điển thường chạy trên application servers như là JBoss/WildFly, Oracle WebLogic và IBM WebSphere, hoặc servlet containers như Apache Tomcat. Java Virtual Machine thường chạy 24/7 và phục vụ nhiều yêu cầu bằng khả năng đa luồng của nó 

Java application server chạy thường xuyên

Khi xây dựng Lambda function với Java, bạn không cần sử dụng đến 1 máy chủ HTTP nữa, và có thêm những lưu ý khác khi chạy code trong môi trường Lambda. Code chạy trên môi trường thực thi xử lý từng yêu cầu riêng lẻ tại mỗi thời điểm. Chức năng có thể chạy mất tới 15 phút với tối đa 10Gb bộ nhớ được cấp phát.

Các chức năng sẽ được kích hoạt bởi events như yêu cầu HTTP với đính kèm payload tương ứng. Yêu cầu HTTP từ  Amazon API Gateway kích hoạt chức năng với JSON payload sau:

Amazon API Gateway HTTP request payload

Code xử lý với những sự kiện khác với cách bạn thực hiện nó trên ứng dụng truyền thống.

AWS Serverless Java Container

AWS Serverless Java Container giúp chạy các ứng dụng Java được viết với frameworks như Spring, Spring Boot, or JAX-RS/Jersey dễ dàng hơn trong Lambda.

Container cung cấp logic adapter để giảm thiểu thay đổi code. Những sự kiện đến được dịch sang Servlet specification để các framework hoạt động như trước.

AWS Serverless Java Container adapter

Bản đầu của thư viện này được phát hành vào 2018. Hôm nay, AWS chính thức phát hành của phiên bản 2, hỗ trợ các đặc tả Jakarta EE mới nhất, cùng với Spring Framework 6.x, Spring Boot 3.x vàJersey 3.x.

Ví dụ: Sửa đổi 1 ứng dụng Spring Boot

Dưới đây là các bước mô tả cách chuyển đổi Spring Boot 3 application. Bạn có thể tìm đầy đủ ví dụ cho Spring và các frameworks khác ở GitHub repository.

1.Thêm AWS Serverless Java dependency vào tệp Maven POM (hoặc gradle):

<dependency>

    <groupId>com.amazonaws.serverless</groupId>

    <artifactId>aws-serverless-java-container-springboot3</artifactId>

    <version>2.0.0</version>

</dependency>



2. Spring Boot, được mặc định nhúng Apache tomcat để giải quyết các yêu cầu HTTP. Các ví dụ sử dụng Amazon API Gateway để xử lý yêu cầu inbound HTTP, vì vậy bạn có thể loại trừ dependency này.

<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 API Gateway proxy yêu cầu và chuyển đổi chúng vào 1 đối tượng Java đơn giản. Thư viện cũng chuyển đổi output vào 1 đối tượng phản hồi API Gateway phù hợp.

Ngay khi chạy các quy trình của bạn, Maven’s Shade-plugin sẽ tạo ra 1 Uber-JAR đóng gói tất cả dependencies, bạn có thể tải lên Lambda.

3. Lambda runtime phải biết phương thức xử lý nào cần được gọi. Vì vậy,  bạn có thể cấu hình và sử dụng triển khai SpringDelegatingLambdaContainerHandler hoặc  triển khai Java class của riêng bạn để ủy quyền 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.

4. Cấu hình tên xử lý trong cài đặt runtime của chức năng của bạn

Configure the handler name

5. Cấu hình environment variable có tên MAIN_CLASS để thông báo cho trình xử lý chung về vị trí của main class của ứng dụng thường được đánh dấu bằng @SpringBootApplication

Cấu hình MAIN_CLASS environment variable

Bạn có thể để cấu hình các cài đặt này sử dụng các công cụ infrastructure as code (IaC) như  AWS CloudFormationAWS Cloud Development Kit (AWS CDK), hoặc AWS Serverless Application Model (AWS SAM).

Trong AWS SAM template, những thay đổi liên quan như sau. Xem đầy đủ template tại GitHub repository.

YAML

Handler: com.amazonaws.serverless.proxy.spring.SpringDelegatingLambdaContainerHandler 

Environment:

  Variables:

    MAIN_CLASS: com.amazonaws.serverless.sample.springboot3.Application

Cấu hình bộ nhớ tối ưu

Khi chạy Lambda functions, thời gian khởi động và dung lượng bộ nhớ là những yếu tố quan trọng cần cân nhắc. Lượng bộ nhớ mà bạn cấu hình cho Lambda functions cũng xác định lượng máy ảo CPU sẵn có. Thêm nhiều bộ nhớ tăng lượng CPU, và vì thế tăng cường năng lực tính toán tổng thể có sẵn. Nếu 1 chức năng bị hạn chế bởi CPU, network hoặc bộ nhớ, việc thêm nhiều bộ nhớ có thể cải thiện hiệu suất.

Lambda tính phí dựa trên tổng lượng gigabyte-seconds tiêu thụ của 1 chức năng. Gigabyte-seconds là kết hợp của tổng bộ nhớ (tính bằng gigabyte) và thời lượng (tính bằng giây). Việc tăng bộ nhớ sẽ chịu thêm chi phí. Tuy nhiên, trong nhiều trường hợp, việc tăng bộ nhớ có sẵn giúp ra giảm thời gian chạy của hàm vì CPU bổ sung. Kết quả là, tổng chi phí tăng có thể không đáng kể cho hiệu suất bổ sung, hoặc có thể thậm chí giảm đi.

Chọn bộ nhớ cấp phát cho Lambda functions của bạn là quá trình tối ưu xử lý tốc độ cân bằng (khoảng thời gian) và chi phí. Bạn có thể kiểm thử chức năng thủ công bằng cách chọn cấp phát bộ nhớ khác nhau và đo thời gian hoàn thành.  AWS Lambda Power Tuning là 1 công cụ đơn giản và tự động hóa quá trình để bạn có thể sử dụng tối ưu cấu hình của bạn.

Power Tuning sử dụng các AWS Step Functions để chạy nhiều phiên bản đồng thời của Lambda function tại các địa chỉ cấp phát bộ nhớ khác nhau và đo lường hiệu suất. Function chạy ở tài khoản AWS của bạn, thực hiện việc gọi HTTP và tương tác SDK một cách trực tiếp, để đo hiệu suất trong 1 kịch bản sản xuất.

Cải thiện thời gian cold-start với AWS Lambda SnapStart

Các ứng dụng truyền thống thường có cây dependencies phức tạp. Lambda tải các function 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ể rất lâu đối với yêu cầu của bạn. AWS Lambda SnapStart dành cho các function dựa trên Java có thể mang lại hiệu suất khởi động nhanh hơ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 sẽ chạy quy trình khởi tạo function tại thời điểm triển khai. Lambda lấy snapshot của môi trường thực thi đã được khởi tạo. Snapshot này được mã hóa và lưu trữ trong bộ nhớ cache nhiều tầng để truy cập với độ trễ thấp. Khi chức năng được kích hoạt và mở rộng, Lambda tiếp tục môi trường thực thi từ snapshot được lưu trữ thay vì chạy toàn bộ quy trình khởi tạo. Điều này dẫn đến độ trễ khởi động thấp hơn.

Để enable Lambda SnapStart bạn cần bật trước cài đặt cấu hình, và để publish a function version.

Enabling SnapStart

Đảm bảo API Gateway endpoint của bạn trỏ đến phiên bản đã published hoặc alias để đảm bảo bạn đang sử dụng function có SnapStart đã được kích hoạt.

Cài đặt phản hồi trong AWS SAM template chứa những nội dung như sau: 

YAML

SnapStart: 

  ApplyOn: PublishedVersions

AutoPublishAlias: my-function-alias

Đọc Lambda SnapStart compatibility considerations trong tài liệu vì ứng dụng của bạn có thể chứa mã cụ thể cần được chú ý.

Kết luận

khi xây dựng các ứng dụng serverless với Lambda , bạn có thể cung cấp các tính năng nhanh hơn, nhưng ngôn ngữ và môi trường runtime của bạn phải hoạt động trong model kiến trúc serverless. AWS Serverless Java Container giúp kết nối giữa các ứng dụng doanh nghiệp Java truyền thống và các function serverless cloud-native hiện đại.

Bạn có thể tối ưu cấu hình bộ nhớ Java Lambda function của bạn bằng cách sử dụng công cụ  AWS Lambda Power Tuning và bật SnapStart để tối ưu thời gian cold-start.

Java on AWS Lambda workshop cho thấy xây dựng các ứng dụng Java cloud-native và chuyển đổi tồn tại ứng dụng Java sang Lambda

Khám phá  AWS Serverless Java Container GitHub repo nơi bạn có thể báo cáo liên quan issues and feature requests.

Nguồn tài nguyên học serverless  thêm, ghé Serverless Land.

Bài viết được dịch trên AWS Blog, bạn có thể xem bài viết tại đây

Leave a comment