Làm thế nào để làm cho bất kỳ máy chủ ứng dụng NodeJS nào

Tôi hy vọng bạn yêu thích Serverless nhiều như tôi vì đây là một bài viết khác về chủ đề đó.

Bây giờ, nếu chúng tôi nói về một API REST không có máy chủ đơn giản, thiết lập của bạn khá rõ ràng trên AWS: Lambda + API Gateway.

Nhưng làm thế nào về các dịch vụ (vi mô) khác mà phụ trợ của bạn có thể có? Bạn biết đấy, nó không phải là ý tưởng tốt nhất để đặt tất cả mã ứng dụng của bạn vào một hàm AWS Lambda nguyên khối duy nhất.

Các thách thức

Chúng tôi muốn dễ dàng triển khai các mô-đun ứng dụng dưới dạng microservice serverless, cũng cần liên lạc với nhau. Tốt hơn là, giao tiếp giữa các dịch vụ nên được quy định bởi một số loại ACL.

Cố gắng 1. Cổng API

Đây là suy nghĩ đầu tiên mà tôi có khi tôi cố gắng giải quyết vấn đề: chỉ cần phơi bày tất cả các dịch vụ siêu nhỏ thông qua API Gateway. Vấn đề là các API được tạo là công khai.

Tại sao điều này là một vấn đề? Ví dụ: chúng tôi không muốn có một dịch vụ thanh toán được tiếp xúc với toàn thế giới, ngay cả khi quyền truy cập bị hạn chế sử dụng một số loại ủy quyền.

Chà, bạn có thể đặt API ở chế độ riêng tư, nhưng các chính sách bảo mật khá hạn chế:

Bạn có thể sử dụng các chính sách tài nguyên của API Gateway để cho phép API của bạn được gọi một cách an toàn bằng cách:
* người dùng từ tài khoản AWS được chỉ định
* phạm vi địa chỉ IP nguồn được chỉ định hoặc khối CIDR
* các đám mây riêng ảo được chỉ định (VPC) hoặc điểm cuối VPC (trong bất kỳ tài khoản nào)

Điều này làm cho khá rắc rối để kiểm soát thông tin liên lạc giữa các dịch vụ như vậy. Cách duy nhất để làm điều đó ở đây là đưa các dịch vụ vào các VPC riêng biệt, quá nhiều công việc.

Cố gắng 2. Lambda

Tại sao don không chúng ta chỉ cần đặt mọi dịch vụ siêu nhỏ vào một AWS Lambda riêng biệt? Điều này sẽ giải quyết vấn đề?

Đúng, trên thực tế, đây sẽ là một dịch vụ siêu nhỏ không có máy chủ và bạn sẽ có thể sử dụng các chính sách IAM để điều chỉnh các truy cập giữa các dịch vụ, nhưng đó không phải là một cách dễ dàng.

Tôi biết điều này là khá bình thường ngày nay để có một chức năng nhỏ như đơn vị triển khai của bạn. Và trong trường hợp khi dịch vụ của bạn có nhiều hơn 1 điểm cuối / phương thức / chức năng, thì nó đã được coi là ok để triển khai nó dưới dạng nhiều Lambdas.

Tôi hiểu những lợi thế của nó, nhưng bạn hy sinh dễ bảo trì và phát triển. Ngoài ra, tôi thực sự không thích một ý tưởng về việc có một dịch vụ được triển khai như một tập hợp các chức năng Lambda. Hãy tưởng tượng, một số chức năng riêng biệt liên quan đến thanh toán? Nó không phải là một bối cảnh bị ràng buộc nữa. Mặc dù có những trường hợp độ chi tiết như vậy có thể hữu ích, nhưng nó lại là một trường hợp hiếm.

Cố gắng 3. Fat Lambda

Chúng ta thực sự có thể triển khai một tập hợp các điểm cuối dưới dạng một Lambda không (dĩ nhiên không sử dụng API Gateway)?

Nếu chúng tôi có thể làm điều này, chúng tôi sẽ nhận được tất cả các lợi ích của tùy chọn trước đó, nhưng chúng tôi cũng có thể chọn mức độ chi tiết của các đơn vị triển khai của chúng tôi.

Cách tôi muốn là như sau: mỗi dịch vụ có thể triển khai phải là một đối tượng JS đơn giản cũ với các phương thức. Điều này khá đơn giản để đạt được bằng cách thêm một vài dòng mã keo giữa đối tượng của bạn và AWS Lambda.

Đây là cách tôi thực hiện: aws-rpc. Mô-đun nodejs này hiển thị chức năng lambdaHandler, nơi bạn vừa truyền một đối tượng và nó tự động hiển thị cho bất kỳ ai có thể truy cập Lambda:

nhập {lambdaHandler} từ 'aws-rpc';
nhập {TestServiceImpl} từ './TestServiceImpl';
// đây là đơn vị triển khai của bạn
// đây là những gì bạn chỉ định là hàm xử lý của Lambda
export const handler = lambdaHandler (new TestServiceImpl ());

Bây giờ, bạn chỉ có thể triển khai bộ xử lý của người dùng trò chơi là AWS Lambda. Đây là cách bạn gọi các phương thức của nó:

nhập {TestService} từ './TestService';
const client = await createdClient  ("LambdaName", "test");
console.log (đang chờ client.test ());

Xin lưu ý rằng, để có thể tạo các phương thức cho đối tượng còn sơ khai của máy khách, bạn phải chuyển tất cả các tên phương thức để tạoClient, như chúng ta đã làm trong ví dụ.

Điều này là bắt buộc vì JS không có bất kỳ thông tin thời gian chạy nào về các giao diện TypeScript. Tôi có thể thực hiện nó bằng các lớp trừu tượng, nhưng tôi không thích nó ¯ \ _ (ツ) _ /.

Tiền thưởng! Bạn có thể chạy tất cả tại địa phương!

Tôi tin rằng điều rất quan trọng là có môi trường phát triển địa phương của bạn thoải mái nhất có thể. Đây là lý do tại sao tôi cũng đã thêm khả năng chạy dịch vụ và máy khách cục bộ mà không triển khai bất cứ thứ gì lên AWS (xem các hàm runService và createClient). Ví dụ, xem kho lưu trữ trên GitHub.

Tóm lược

Điều này rất dễ bị lạc trong các dịch vụ mà các nhà cung cấp đám mây cung cấp và áp đảo cơ sở hạ tầng của bạn.

Tôi luôn chọn giải pháp đơn giản và rõ ràng nhất mà tôi có thể nghĩ ra. Ngoài ra, hãy luôn nhớ rằng nhiều kỹ thuật và thực hành có thể được sử dụng lại từ các nền tảng khác (ý ​​tưởng về NodeJS Lambda béo được lấy cảm hứng từ cái gọi là bình béo từ thế giới Java).

Nếu bạn thích chủ đề này, hãy xem những điều này:

  • Bạn phải học cách tạo ra kiến ​​trúc máy chủ tốt nhất
  • Cách tạo đường ống CI / CD không có máy chủ miễn phí: 3 ví dụ dễ dàng
  • Cách dễ dàng tái tạo DynamoDB trên các khu vực
  • Cách tạo Ứng dụng Đa vùng (và Trả bằng 0)
  • Làm cho bất kỳ ứng dụng web Java nào không có máy chủ

Bình luận, thích và chia sẻ được đánh giá cao. Chúc mừng!