CyStack logo
  • Sản phẩm & Dịch vụ
  • Giải pháp
  • Bảng giá
  • Công ty
  • Tài liệu
Vi

vi

Trang chủHướng dẫnHướng dẫn triển khai ứng dụng Serverless: Kiến trúc, ví dụ và best practices

Hướng dẫn triển khai ứng dụng Serverless: Kiến trúc, ví dụ và best practices

CyStack blog 8 phút để đọc
CyStack blog08/09/2025
Locker Avatar

Chris Pham

Technical Writer

Locker logo social
Reading Time: 8 minutes

Kiến trúc serverless cho phép triển khai các dịch vụ web backend theo nhu cầu. Thay vì phải duy trì cấu hình máy chủ của riêng bạn, việc thiết kế ứng dụng cho các nhà cung cấp serverless có thể giảm thiểu gánh nặng xử lý liên quan. Các ứng dụng serverless thường được triển khai từ một repository Git vào môi trường có thể mở rộng hoặc thu hẹp tùy theo nhu cầu.

 triển khai ứng dụng Serverless

Điều này có nghĩa là các hàm serverless có thể “scale to zero”, một hàm hoặc endpoint sẽ không tiêu tốn bất kỳ tài nguyên nào miễn là nó không bị truy cập. Tuy nhiên, điều đó cũng đồng nghĩa các hàm serverless phải hoạt động ổn định, và cần sẵn sàng từ trạng thái nhàn rỗi chỉ để cung cấp phản hồi riêng lẻ cho các yêu cầu đầu vào. Những phản hồi này có thể phức tạp về tính toán nếu cần, nhưng phải được gọi và kết thúc theo cách có thể dự đoán.

Hướng dẫn này sẽ đề cập đến một số giải pháp tốt nhất khi viết ví dụ về một hàm serverless.

Điều kiện tiên quyết

Để theo dõi hướng dẫn này, bạn sẽ cần:

  • Một môi trường shell cục bộ đã cài đặt công cụ triển khai serverless. Một số nền tảng serverless sử dụng lệnh serverless, còn trong hướng dẫn này, chúng ta sẽ dựa trên công cụ sandbox doctl của DigitalOcean. Cả hai đều cung cấp chức năng tương tự. Để cài đặt và cấu hình doctl, bạn có thể tham khảo tài liệu chính thức.
  • Đã có sẵn công cụ quản lý phiên bản Git trong môi trường phát triển của bạn. Nếu bạn đang làm việc trên Ubuntu, bạn có thể tham khảo hướng dẫn Cài đặt Git trên Ubuntu 20.04.

Bước 1: Tạo khung (Scaffolding) cho một Serverless App Repository

Một ứng dụng serverless hoàn chỉnh có thể chỉ cần chứa tối thiểu 2 tệp:

  • Tệp cấu hình, thường dùng cú pháp .yml, để khai báo siêu dữ liệu cần thiết cho ứng dụng của bạn tới nhà cung cấp serverless.
  • Tệp chứa chính mã nguồn, ví dụ my_app.py, my_app.js hoặc my_app.go.

Nếu ứng dụng của bạn có các phụ thuộc ngôn ngữ, thông thường chúng cũng sẽ được khai báo theo chuẩn của ngôn ngữ đó, chẳng hạn tệp package.json trong Node.js.

Để khởi tạo một ứng dụng serverless, bạn có thể dùng lệnh doctl sandbox init với tên thư mục mới:

doctl sandbox init myServerlessProject

Output

A local sandbox area 'myServerlessProject' was created for you.
You may deploy it by running the command shown on the next line:
  doctl sandbox deploy myServerlessProject

Theo mặc định, lệnh này sẽ tạo một dự án với cấu trúc thư mục như sau:

myServerlessProject/
├── packages
│   └── sample
│       └── hello
│           └── hello.js
└── project.yml

Tệp project.yml nằm trong thư mục cấp cao nhất. Nó khai báo siêu dữ liệu cho hello.js, trong đó chứa một hàm duy nhất. Tất cả các ứng dụng serverless sẽ tuân theo cấu trúc cơ bản giống nhau. Bạn có thể tìm thêm ví dụ sử dụng các framework serverless khác tại repository GitHub chính thức của Serverless Framework, hoặc tham khảo tài liệu của DigitalOcean. Bạn cũng có thể tự tạo cấu trúc thư mục này từ đầu mà không cần phụ thuộc vào lệnh init, nhưng lưu ý, yêu cầu của mỗi nhà cung cấp serverless sẽ khác nhau đôi chút.

Trong bước tiếp theo, chúng tã sẽ tìm hiểu chi tiết hơn về dự án mẫu mà bạn vừa khởi tạo.

Bước 2: Thiết kế kiến trúc cho ứng dụng Serverless

Một ứng dụng serverless có thể chỉ là một hàm duy nhất, được viết bằng ngôn ngữ mà nhà cung cấp dịch vụ điện toán serverless hỗ trợ (thường là Go, Python và JavaScript), miễn là nó có thể return đầu ra. Hàm của bạn có thể gọi các hàm khác hoặc tải thư viện ngôn ngữ khác, nhưng trong dự án luôn phải có một hàm chính được định nghĩa trong tệp cấu hình dự án để giao tiếp với chính endpoint đó.

Ở bước trước, khi bạn chạy doctl sandbox init, hệ thống đã tự động tạo một dự án mẫu cho ứng dụng serverless, trong đó có một tệp tên là hello.js. Bạn có thể mở tệp này bằng nano hoặc bất kỳ trình soạn thảo văn bản nào mà bạn muốn:

nano myServerlessProject/packages/sample/hello/hello.js

~/myServerlessProject/packages/sample/hello/hello.js
function main(args) {
    let name = args.name || 'stranger'
    let greeting = 'Hello ' + name + '!'
    console.log(greeting)
    return {"body": greeting}
  }

Tệp này chứa một hàm duy nhất có tên là main(), có thể nhận một tập hợp các đối số. Đây là thiết lập mặc định mà kiến trúc serverless quản lý xử lý đầu vào. Các hàm serverless không nhất thiết phải trực tiếp phân tích JSON hoặc header HTTP để xử lý dữ liệu đầu vào. Trên hầu hết các nền tảng của nhà cung cấp, các hàm serverless sẽ nhận dữ liệu đầu vào từ các yêu cầu HTTP dưới dạng danh sách đối số, có thể giải nén bằng các tính năng ngôn ngữ tiêu chuẩn.

Dòng đầu tiên của hàm sử dụng toán tử || OR của JavaScript để phân tích đối số name nếu nó tồn tại, hoặc sử dụng chuỗi stranger nếu hàm được gọi mà không có đối số. Điều này quan trọng trong trường hợp endpoint của hàm bị gọi sai hoặc thiếu dữ liệu. Các hàm serverless luôn cần có đường dẫn mã cho phép bạn nhanh chóng trả về null, hoặc trả về giá trị tương đương với null trong phản hồi HTTP hợp lệ, với mức xử lý bổ sung tối thiểu. Dòng tiếp theo, let greeting =, thực hiện một số thao tác chuỗi bổ sung.

Tùy vào nhà cung cấp serverless, hàm của bạn có thể không có sẵn các tính năng hệ thống tệp hoặc tính năng cấp hệ điều hành. Ứng dụng serverless cũng không nhất thiết phải luôn phi trạng thái. Tuy nhiên, những tính năng cho phép ứng dụng serverless ghi lại hoặc giữ trạng thái giữa các lần chạy thường là độc quyền của từng nhà cung cấp. Ngoại lệ phổ biến nhất là khả năng ghi log đầu ra từ các hàm của bạn.

Ứng dụng mẫu hello.js chứa hàm console.log(), sử dụng tính năng có sẵn của JavaScript để xuất thêm dữ liệu ra console của trình duyệt hoặc stdout của terminal cục bộ mà không trả về cho người dùng. Hầu hết các nhà cung cấp serverless đều cho phép bạn lưu giữ và xem lại log theo cách này.

Dòng cuối cùng của hàm được dùng để return kết quả. Vì hầu hết các hàm serverless được triển khai dưới dạng endpoint HTTP nên thông thường bạn sẽ cần trả về một phản hồi HTTP. Trong nhiều môi trường serverless, phản hồi này sẽ được tự động tạo sẵn. Trong trường hợp này, bạn chỉ cần trả về phần request body trong một mảng, phần còn lại sẽ do cấu hình endpoint xử lý.

Hàm này có thể thực hiện nhiều bước hơn nữa, miễn là vẫn duy trì các nguyên tắc cơ bản liên quan đến đầu vào và đầu ra. Ngoài ra, ứng dụng của bạn có thể chạy nhiều hàm serverless theo chuỗi, và chúng có thể được thay thế khi cần. Các hàm serverless có thể được coi là tương tự với kiến trúc hướng microservice: cả hai đều cho phép bạn xây dựng ứng dụng từ nhiều dịch vụ rời rạc, không nhất thiết phải phụ thuộc lẫn nhau, và giao tiếp qua các giao thức chuẩn như HTTP. Không phải tất cả kiến trúc microservice đều là serverless, nhưng hầu hết các kiến trúc serverless đều triển khai microservices.

Sau khi đã nắm rõ kiến trúc ứng dụng, ở bước tiếp theo chúng ta sẽ tìm hiểu một số phương pháp tối ưu trong việc chuẩn bị và triển khai các hàm serverless.

Bước 3: Triển khai một hàm Serverless

Công cụ dòng lệnh doctl sandbox cho phép bạn triển khai và kiểm thử ứng dụng mà không cần đưa chúng vào môi trường production, và các nền tảng serverless khác cũng cung cấp chức năng tương tự. Tuy nhiên, gần như tất cả quy trình triển khai serverless cuối cùng đều sẽ yêu cầu bạn commit ứng dụng của mình vào một repository quản lý mã nguồn như GitHub, và kết nối repository GitHub đó với nhà cung cấp serverless.

Khi bạn đã sẵn sàng triển khai lên môi trường production, bạn sẽ có thể truy cập vào console của nhà cung cấp serverless và liên kết repository mã nguồn với ứng dụng. Ứng dụng của bạn cũng có thể có các thành phần khác, chẳng hạn một website tĩnh, hoặc có thể chỉ cung cấp một endpoint duy nhất.

Hiện tại, bạn có thể triển khai trực tiếp vào sandbox thử nghiệm bằng doctl sandbox:

doctl sandbox deploy myServerlessProject

Lệnh này sẽ trả về thông tin về lần triển khai, bao gồm một lệnh khác mà bạn có thể chạy để lấy URL kiểm thử trực tiếp:

Output

Deployed '~/Desktop/myServerlessProject'
  to namespace 'f8572f2a-swev6f2t3bs'
  on host '<https://faas-nyc1-78edc.doserverless.io>'
Deployment status recorded in 'myServerlessProject\\.nimbella'

Deployed functions ('doctl sbx fn get <funcName> --url' for URL):
  - sample/hello

Chạy lệnh này sẽ trả về endpoint hiện tại của hàm serverless:

doctl sbx fn get sample/hello --url

Output

<https://faas-nyc1-78edc.doserverless.io/api/v1/web/f8572f2a-swev6f2t3bs/sample/hello>

Các đường dẫn trả về sẽ được tạo tự động, nhưng sẽ kết thúc bằng /sample/hello, dựa trên tên hàm của bạn.

Lưu ý: Bạn có thể xem lại chức năng triển khai doctl sandbox tại repository mã nguồn của nó.

Sau khi triển khai ở môi trường thử nghiệm hoặc production, bạn có thể dùng cURL để gửi yêu cầu HTTP tới endpoint của mình. Với ứng dụng sample/hello được phát triển trong hướng dẫn này, bạn có thể gửi một yêu cầu curl tới endpoint /sample/hello:

curl <https://faas-nyc1-78edc.doserverless.io/api/v1/web/f8572f2a-swev6f2t3bs/sample/hello>

Đầu ra sẽ được trả về dưới dạng phần body của một phản hồi HTTP chuẩn:

Output

“Hello stranger!”

Bạn cũng có thể truyền đối số name cho hàm của mình như đã mô tả ở trên, bằng cách mã hóa nó thành một tham số bổ sung trong URL:

curl “<https://faas-nyc1-78edc.doserverless.io/api/v1/web/f8572f2a-swev6f2t3bs/sample/hello?name=sammy”>

Output

“Hello sammy!”

Sau khi bạn đã kiểm thử và xác nhận ứng dụng trả về phản hồi đúng như mong đợi, bước tiếp theo là đảm bảo rằng khi gặp dữ liệu đầu vào bất thường, endpoint sẽ phản hồi lỗi theo cách an toàn. Bạn có thể tham khảo các phương pháp xử lý lỗi chuẩn để đảm bảo đầu vào được phân tích chính xác. Quan trọng hơn hết, ứng dụng cần tránh bị treo đột ngột, vì điều này không chỉ ảnh hưởng đến khả năng sẵn sàng của ứng dụng serverless mà còn có thể làm phát sinh chi phí không mong muốn theo số lần sử dụng.

Cuối cùng, bạn nên commit ứng dụng của mình lên GitHub hoặc một repository mã nguồn khác để đưa vào production. Nếu bạn chọn dùng Git hoặc GitHub, bạn có thể tham khảo hướng dẫn Cách sử dụng Git hiệu quả để làm quen với cách làm việc cùng repository Git.

Sau khi kết nối repository mã nguồn với nhà cung cấp serverless, bạn có thể thực hiện thêm các bước để giới hạn quyền truy cập vào endpoint của hàm, hoặc kết hợp nó với các hàm serverless khác trong một ứng dụng lớn hơn có gắn nhãn.

Kết luận

Trong hướng dẫn này, bạn đã khởi tạo, xem xét và triển khai một hàm serverless mẫu. Mặc dù mỗi nền tảng điện toán serverless về cơ bản là độc quyền, nhưng hầu hết các nhà cung cấp đều tuân theo những nguyên tắc kiến trúc tương tự, và các nguyên tắc trong hướng dẫn này có thể áp dụng rộng rãi. Giống như bất kỳ web stack nào khác, kiến trúc serverless có thể thay đổi đáng kể về quy mô, nhưng việc bảo đảm từng thành phần độc lập sẽ giúp toàn bộ stack của bạn dễ bảo trì hơn.

Tiếp theo, bạn có thể tìm hiểu thêm về cách giám sát hiệu quả kiến trúc microservice để nắm rõ hơn cách tối ưu hóa triển khai serverless. Bạn cũng có thể khám phá một số kiến trúc serverless tiềm năng khác, chẳng hạn môi trường Jamstack.

0 Bình luận

Đăng nhập để thảo luận

Chuyên mục Hướng dẫn

Tổng hợp các bài viết hướng dẫn, nghiên cứu và phân tích chi tiết về kỹ thuật, các xu hướng công nghệ mới nhất dành cho lập trình viên.

Đăng ký nhận bản tin của chúng tôi

Hãy trở thành người nhận được các nội dung hữu ích của CyStack sớm nhất

Xem chính sách của chúng tôi Chính sách bảo mật.

Đăng ký nhận Newsletter

Nhận các nội dung hữu ích mới nhất