Thực hành tốt nhất không có máy chủ

Trong cộng đồng, chúng tôi đã tranh luận về các thực tiễn tốt nhất trong nhiều năm, nhưng có một số ít được chấp nhận trong hầu hết thời gian đó.

Hầu hết các học viên không có máy chủ đăng ký các thực hành này làm việc ở quy mô. Lời hứa của serverless diễn ra chủ yếu ở cả khối lượng công việc quy mô lớn và bùng nổ thay vì ở mức tương đối thấp, do đó, rất nhiều trong số các thực tiễn tốt nhất này đến từ góc độ quy mô, ví dụ: Nordstrom trong bán lẻ và iRobot trong IoT. Nếu bạn không nhắm đến quy mô xa như vậy, thì có lẽ bạn có thể thoát khỏi mà không cần tuân theo những thực hành tốt nhất này.

Và hãy nhớ rằng những cách thực hành tốt nhất không phải là những cách thực hành duy nhất. Thực tiễn tốt nhất dựa trên một loạt các giả định cơ bản. Nếu những giả định đó không phù hợp với trường hợp sử dụng của bạn, thì những thực tiễn tốt nhất đó có thể không phù hợp.

Giả định chính của tôi là mọi người đang xây dựng ứng dụng của họ để có thể chạy ở quy mô (ngay cả khi nó không bao giờ kết thúc được chạy ở quy mô).

Vì vậy, đây là những thực hành tốt nhất của tôi khi tôi nhìn thấy chúng.

Mỗi chức năng chỉ nên làm một việc

Nó nói về lỗi chức năng và cách ly tỷ lệ.

Đặt nó theo một cách khác, nếu bạn sử dụng một câu lệnh chuyển đổi trong chức năng của mình, bạn có thể đã làm sai.

Rất nhiều hướng dẫn và khung làm việc trên cơ sở chức năng nguyên khối lớn đằng sau một tuyến proxy duy nhất và sử dụng các câu lệnh chuyển đổi. Tôi không thích mẫu này. Nó không quy mô tốt, và có xu hướng làm cho các chức năng lớn và phức tạp.

Vấn đề với một / một vài chức năng chạy toàn bộ ứng dụng của bạn, là khi bạn mở rộng quy mô, bạn sẽ mở rộng toàn bộ ứng dụng của mình, thay vì mở rộng thành phần cụ thể.

Nếu bạn có một phần trong ứng dụng web của mình nhận được 1 triệu cuộc gọi và phần khác nhận được 1 nghìn cuộc gọi, bạn phải tối ưu hóa chức năng của mình cho hàng triệu, trong khi bao gồm tất cả mã cho hàng nghìn. Điều đó thật lãng phí, và bạn có thể dễ dàng tối ưu hóa hàng ngàn thứ. Tách chúng ra Có rất nhiều giá trị trong đó.

Chức năng don lồng gọi các chức năng khác

Các chức năng gọi các chức năng khác là một mô hình chống.

Có rất ít trường hợp cạnh mà đây là một mẫu hợp lệ, nhưng chúng không dễ bị phá vỡ.

Về cơ bản, don lồng làm điều đó. Bạn chỉ cần tăng gấp đôi chi phí của mình và làm cho việc gỡ lỗi trở nên phức tạp hơn và loại bỏ giá trị của sự cô lập các chức năng của bạn.

Các chức năng nên đẩy dữ liệu đến một kho lưu trữ dữ liệu hoặc hàng đợi, điều này sẽ kích hoạt chức năng khác nếu cần thêm công việc.

Sử dụng càng ít thư viện trong các chức năng của bạn càng tốt (tốt nhất là không)

Điều này có vẻ rõ ràng với tôi.

Các chức năng có khởi động nguội (khi một chức năng được khởi động lần đầu tiên) và khởi động ấm (nó đã được khởi động và sẵn sàng để được thực hiện từ bể ấm). Khởi động nguội bị ảnh hưởng bởi một số thứ, nhưng kích thước của tệp zip (hoặc tuy nhiên mã được tải lên) là một phần của nó. Ngoài ra, số lượng thư viện cần phải được khởi tạo.

Bạn càng có nhiều mã, càng chậm để bắt đầu lạnh.

Càng nhiều thư viện cần khởi tạo, càng chậm để bắt đầu lạnh.

Ví dụ, Java là một ngôn ngữ hoạt động xuất sắc trong một khởi đầu ấm áp trên một số nền tảng. Nhưng nếu bạn sử dụng nhiều thư viện, bạn có thể thấy phải mất nhiều giây để bắt đầu lạnh. Bạn gần như chắc chắn don don cần chúng và hiệu suất khởi động lạnh sẽ cản trở không chỉ khi khởi động mà cả về quy mô.

Như một điểm khác, tôi là một người tin tưởng lớn vào các nhà phát triển chỉ sử dụng các thư viện khi cần thiết và điều đó có nghĩa là bắt đầu từ không, và kết thúc bằng không trừ khi tôi có thể xây dựng những gì mà Need cần mà không cần.

Những thứ như express được xây dựng cho máy chủ và các ứng dụng không có máy chủ không cần tất cả các yếu tố trong đó. Vậy tại sao lại giới thiệu tất cả các mã và phụ thuộc? Tại sao mang lại mã thừa? Nó không chỉ là thứ sẽ không bao giờ được chạy, mà còn có thể gây ra rủi ro bảo mật.

Có rất nhiều lý do cho việc này là một thực hành tốt nhất. Tất nhiên, nếu có một thư viện mà bạn đã kiểm tra, biết và tin tưởng, thì hoàn toàn mang nó vào, nhưng yếu tố chính là kiểm tra, biết và tin tưởng mã. Theo một hướng dẫn, không phải là điều tương tự.

Tránh sử dụng các dịch vụ dựa trên kết nối, ví dụ: RDBMS

Chỉ cần don Patrick trừ khi bạn phải.

Điều này sẽ khiến tôi gặp rắc rối nhất. Rất nhiều ứng dụng web mọi người sẽ nhảy vào trên nhưng RDBMS là những gì chúng ta biết về bandwagon.

Nó không phải là về RDBMS. Nó nói về các kết nối.

Serverless hoạt động tốt nhất với các dịch vụ hơn là kết nối.

Các dịch vụ nhằm trả lại phản hồi cho các yêu cầu thực sự nhanh chóng và để xử lý sự phức tạp của lớp dữ liệu đằng sau dịch vụ. Điều này có giá trị rất lớn trong không gian máy chủ và tại sao một cái gì đó như DynamoDB lại rất phù hợp với mô hình không có máy chủ.

Thành thật mà nói, những người không có máy chủ không chống lại RDBMS, họ chống lại các kết nối. Các kết nối cần có thời gian và nếu bạn tưởng tượng ra một chức năng mở rộng, mỗi môi trường chức năng cần có một kết nối và bạn có thể giới thiệu cả nút cổ chai và I / O chờ vào khởi động nguội của chức năng. Nó là không cần thiết.

Vì vậy, nếu bạn phải sử dụng RDBMS, nhưng đặt một dịch vụ xử lý nhóm kết nối ở giữa, có thể một thùng chứa tự động mở rộng của một số mô tả chỉ để xử lý điều đó sẽ rất tuyệt.

Điểm lớn nhất để thực hiện ở đây là kiến ​​trúc không có máy chủ có thể yêu cầu bạn phải suy nghĩ lại về lớp dữ liệu của mình. Đó không phải là lỗi của serverless. Nếu bạn cố gắng sử dụng lại suy nghĩ lớp dữ liệu hiện tại của mình và nó không hoạt động, thì đó có lẽ là một sự thiếu hiểu biết về kiến ​​trúc máy chủ.

Một chức năng trên mỗi tuyến đường (nếu sử dụng HTTP)

Tránh sử dụng proxy chức năng duy nhất nếu có thể. Nó không quy mô tốt và không giúp cách ly các vấn đề. Có những dịp bạn có thể tránh điều này, ví dụ: trong đó chức năng của một loạt các tuyến được gắn chặt vào một bảng duy nhất và nó rất tách rời khỏi phần còn lại của ứng dụng, nhưng đó là trường hợp cạnh trong hầu hết các ứng dụng mà tôi đã làm việc.

Điều này thêm sự phức tạp về mặt quản lý, nhưng nó thực sự giúp ích trong việc cô lập các lỗi và các vấn đề khi ứng dụng của bạn mở rộng quy mô. Bắt đầu như bạn có nghĩa là để đi vào.

Nhưng sau đó, bạn có đang sử dụng một số loại công cụ quản lý cấu hình nào để chạy mọi thứ không? Và bạn đã sử dụng công cụ CI và CD của một số loại phải không? Bạn vẫn phải DevOps với serverless.

Tìm hiểu cách sử dụng tin nhắn và hàng đợi (async FTW)

Các ứng dụng không có máy chủ có xu hướng hoạt động tốt nhất khi ứng dụng không đồng bộ. Đây không phải là hướng thẳng cho các ứng dụng web trong đó xu hướng là thực hiện phản hồi yêu cầu và nhiều truy vấn.

Quay trở lại các chức năng không gọi các chức năng khác, điều quan trọng là chỉ ra rằng đây là cách bạn kết hợp các chức năng với nhau. Một hàng đợi hoạt động như một bộ ngắt mạch trong kịch bản chuỗi, do đó, nếu một chức năng bị lỗi, bạn có thể dễ dàng rút hết một hàng đợi đã được sao lưu do lỗi hoặc đẩy các tin nhắn thất bại vào hàng đợi thư chết.

Về cơ bản, tìm hiểu làm thế nào các hệ thống phân phối làm việc.

Với các ứng dụng khách có phần cuối máy chủ, cách tiếp cận tốt nhất là xem xét CQRS. Việc tách ra điểm lấy dữ liệu từ điểm nhập dữ liệu là chìa khóa cho loại mẫu này.

Luồng dữ liệu, không phải hồ dữ liệu

Trong một hệ thống không có máy chủ, dữ liệu của bạn chảy qua hệ thống của bạn. Nó có thể kết thúc trong một hồ dữ liệu, nhưng khả năng là trong khi nó LÊN trong hệ thống không có máy chủ của bạn, nó nằm trong một dòng chảy nào đó. Vì vậy, hãy đối xử với tất cả các dữ liệu giống như nó đang chuyển động, không phải lúc nghỉ ngơi tại bất kỳ điểm nào.

Nó không phải lúc nào cũng có thể, nhưng cố gắng tránh truy vấn từ một hồ dữ liệu trong một môi trường không có máy chủ.

Serverless yêu cầu bạn phải suy nghĩ lại về lớp dữ liệu của bạn một cách đáng kể. Đây là vấn đề lớn nhất với những người mới đến với serverless, những người có xu hướng tìm đến RDBMS và không chỉ thất bại vì quy mô bắt được họ, mà cấu trúc dữ liệu của họ trở nên quá cứng nhắc quá nhanh.

Bạn sẽ thấy rằng các luồng của bạn sẽ thay đổi khi ứng dụng của bạn thay đổi và quy mô sẽ thay đổi tất cả. Nếu tất cả những gì bạn phải làm là chuyển hướng một luồng thì nó dễ dàng. Nó là khó khăn hơn nhiều đập một hồ.

Tôi biết điểm này có nhiều hơn một chút so với những người khác, nhưng đó không phải là một bước tiến thẳng.

Chỉ mã hóa cho quy mô là một sai lầm, bạn phải xem xét nó quy mô như thế nào

Rất dễ dàng để tạo ứng dụng máy chủ đầu tiên của bạn và xem quy mô của nó. Nếu bạn không hiểu những gì bạn đã làm, bạn có thể dễ dàng rơi vào cái bẫy mà bạn có thể làm với mọi giải pháp tự động mở rộng khác.

Nếu bạn không xem xét ứng dụng của mình và nó sẽ mở rộng quy mô như thế nào thì bạn sẽ tự đặt ra vấn đề. Nếu bạn tạo ra thứ gì đó với khởi đầu lạnh chậm (nhiều thư viện và sử dụng RDBMS chẳng hạn) và sau đó tăng đột biến trong sử dụng, bạn có thể sẽ tăng đồng thời đáng kể chức năng của mình, sau đó tối đa hóa các kết nối của bạn và làm chậm ứng dụng của bạn xuống.

Vì vậy, don lồng chỉ cần thả một ứng dụng vào, và sau đó tưởng tượng rằng nó sẽ hoạt động tương tự khi tải. Hiểu ứng dụng của bạn dưới tải vẫn là một phần của công việc.

Phần kết luận

Còn rất nhiều điều nữa tôi có thể đưa vào đây và đây là ý kiến ​​của tôi về những điều mà tôi phải giải thích nhiều nhất với mọi người khi tôi nói chuyện với họ.

Tôi đã đề cập đến những điều như làm thế nào để lập kế hoạch cho ứng dụng của bạn, hoặc làm thế nào để xem xét chi phí cho một ứng dụng hoặc bất cứ điều gì tương tự như điều đó mà hơi hướng ra ngoài phạm vi.

Mong muốn được nghe người khác suy nghĩ. Khá chắc chắn rằng tôi sẽ nhận được một lũ người nói với tôi rằng tôi đã sai về RDBMS. Cũng như với các container, tôi không ghét RDBMS, nhưng tôi thích sử dụng các công cụ phù hợp cho các công việc phù hợp. Biết công cụ của bạn!