Nguyên tắc phát triển ứng dụng hiện đại từ NGINX. Phần 1

Xin chào các bạn. Háo hức trước ngày khai giảng khóa học "Nhà phát triển phụ trợ trong PHP", theo truyền thống, chúng tôi chia sẻ với bạn bản dịch của tài liệu hữu ích.

Phần mềm giải quyết ngày càng nhiều vấn đề hàng ngày, đồng thời ngày càng trở nên phức tạp hơn. Như Marc Andreessen đã từng nói, nó đang tiêu thụ cả thế giới.

Nguyên tắc phát triển ứng dụng hiện đại từ NGINX. Phần 1

Do đó, cách phát triển và phân phối ứng dụng đã thay đổi đáng kể trong vài năm qua. Đây là những thay đổi trên quy mô kiến ​​tạo dẫn đến một loạt nguyên tắc. Những nguyên tắc này đã được chứng minh là hữu ích trong việc xây dựng nhóm, thiết kế, phát triển và cung cấp ứng dụng của bạn cho người dùng cuối.

Các nguyên tắc có thể được tóm tắt như sau: ứng dụng phải nhỏ, dựa trên web và có kiến ​​trúc lấy nhà phát triển làm trung tâm. Bằng cách xây dựng dựa trên ba nguyên tắc này, bạn có thể tạo một ứng dụng mạnh mẽ, toàn diện, có thể được phân phối nhanh chóng và an toàn cho người dùng cuối, đồng thời có thể dễ dàng mở rộng và mở rộng.

Nguyên tắc phát triển ứng dụng hiện đại từ NGINX. Phần 1

Mỗi nguyên tắc được đề xuất có một số khía cạnh mà chúng ta sẽ thảo luận để cho thấy mỗi nguyên tắc góp phần như thế nào vào mục tiêu cuối cùng là nhanh chóng cung cấp các ứng dụng đáng tin cậy, dễ bảo trì và sử dụng. Chúng ta sẽ xem xét các nguyên tắc so sánh với các nguyên tắc đối lập của chúng để làm rõ ý nghĩa của câu nói “Hãy chắc chắn rằng bạn sử dụng nguyên lý nhỏ bé'.

Chúng tôi hy vọng bài viết này khuyến khích bạn sử dụng các nguyên tắc được đề xuất để xây dựng các ứng dụng hiện đại sẽ cung cấp phương pháp thiết kế thống nhất trong bối cảnh tập hợp công nghệ ngày càng phát triển.

Bằng cách áp dụng những nguyên tắc này, bạn sẽ thấy mình tận dụng được những xu hướng mới nhất trong phát triển phần mềm, bao gồm cả DevOps đến phát triển và phân phối ứng dụng, việc sử dụng các thùng chứa (ví dụ: phu bến tàu) và các khung điều phối vùng chứa (ví dụ: Kubernetes), việc sử dụng microservices (bao gồm cả Kiến trúc microservice nginx и kiến trúc truyền thông mạng cho các ứng dụng microservice.

Ứng dụng hiện đại là gì?

Ứng dụng hiện đại? Ngăn xếp hiện đại? Chính xác thì "hiện đại" nghĩa là gì?

Hầu hết các nhà phát triển chỉ có hiểu biết cơ bản về một ứng dụng hiện đại bao gồm những gì, vì vậy cần xác định rõ ràng khái niệm này.

Một ứng dụng hiện đại hỗ trợ nhiều ứng dụng khách, có thể là giao diện người dùng sử dụng thư viện React JavaScript, ứng dụng di động dành cho Android hoặc iOS hoặc ứng dụng kết nối với ứng dụng khác thông qua API. Một ứng dụng hiện đại ngụ ý số lượng khách hàng không xác định mà nó cung cấp dữ liệu hoặc dịch vụ.

Một ứng dụng hiện đại cung cấp API để truy cập dữ liệu và dịch vụ được yêu cầu. API phải bất biến và không đổi và không được viết riêng cho một yêu cầu cụ thể từ một khách hàng cụ thể. API khả dụng qua HTTP(S) và cung cấp quyền truy cập vào tất cả chức năng có trong GUI hoặc CLI.

Dữ liệu phải có sẵn ở định dạng phổ biến, có thể tương tác, chẳng hạn như JSON. API hiển thị các đối tượng và dịch vụ ở dạng rõ ràng, có tổ chức; ví dụ: API RESTful hoặc GraphQL cung cấp giao diện hợp lý.

Các ứng dụng hiện đại được xây dựng trên ngăn xếp hiện đại và ngăn xếp hiện đại tương ứng là ngăn xếp hỗ trợ các ứng dụng đó. Ngăn xếp này cho phép nhà phát triển dễ dàng tạo một ứng dụng có giao diện HTTP và các điểm cuối API rõ ràng. Cách tiếp cận bạn chọn sẽ cho phép ứng dụng của bạn dễ dàng chấp nhận và gửi dữ liệu ở định dạng JSON. Nói cách khác, ngăn xếp hiện đại tương ứng với các thành phần của Ứng dụng Mười hai yếu tố cho vi dịch vụ.

Các phiên bản phổ biến của loại ngăn xếp này dựa trên Java, Python, Node, hồng ngọc, PHP и Go. Kiến trúc vi dịch vụ nginx đại diện cho một ví dụ về ngăn xếp hiện đại được triển khai trong từng ngôn ngữ được đề cập.

Xin lưu ý rằng chúng tôi không ủng hộ cách tiếp cận thuần túy vi dịch vụ. Nhiều người trong số các bạn đang làm việc với các khối nguyên khối cần phát triển, trong khi những người khác đang xử lý các ứng dụng SOA đang mở rộng và phát triển để trở thành các ứng dụng vi dịch vụ. Vẫn còn những người khác đang hướng tới các ứng dụng không có máy chủ và một số đang triển khai kết hợp những điều trên. Các nguyên tắc được nêu trong bài viết này áp dụng cho từng hệ thống này chỉ với một vài sửa đổi nhỏ.

Nguyên tắc

Bây giờ chúng ta đã hiểu cơ bản về ứng dụng hiện đại và ngăn xếp hiện đại, đã đến lúc đi sâu vào kiến ​​trúc và nguyên tắc thiết kế sẽ phục vụ tốt cho bạn trong việc thiết kế, triển khai và duy trì một ứng dụng hiện đại.

Một trong những nguyên tắc là “xây dựng các ứng dụng nhỏ”, hãy gọi nó là nguyên lý nhỏ bé. Có những ứng dụng cực kỳ phức tạp có rất nhiều bộ phận chuyển động. Đổi lại, việc xây dựng một ứng dụng từ các thành phần nhỏ, riêng biệt giúp thiết kế, bảo trì và sử dụng tổng thể dễ dàng hơn. (Lưu ý rằng chúng tôi đã nói “làm cho nó đơn giản” chứ không phải “làm cho nó đơn giản”).

Nguyên tắc thứ hai là chúng tôi có thể tăng năng suất của nhà phát triển bằng cách giúp họ tập trung vào các tính năng họ đang phát triển, đồng thời giúp họ không phải lo lắng về cơ sở hạ tầng và CI/CD trong quá trình triển khai. Vì vậy, tóm lại, cách tiếp cận của chúng tôi hướng tới nhà phát triển.

Cuối cùng, mọi thứ về ứng dụng của bạn phải được kết nối với mạng. Trong 20 năm qua, chúng ta đã tiến bộ rất nhiều hướng tới một tương lai được kết nối mạng khi mạng trở nên nhanh hơn và các ứng dụng trở nên phức tạp hơn. Như chúng ta đã thấy, một ứng dụng hiện đại phải được sử dụng trên mạng bởi nhiều máy khách khác nhau. Áp dụng tư duy mạng vào kiến ​​trúc có những lợi ích đáng kể phù hợp với nguyên lý nhỏ bé và khái niệm về cách tiếp cận, hướng tới nhà phát triển.

Nếu bạn ghi nhớ những nguyên tắc này khi thiết kế và triển khai một ứng dụng, bạn sẽ có lợi thế rõ rệt trong việc phát triển và phân phối sản phẩm của mình.

Chúng ta hãy xem xét ba nguyên tắc này chi tiết hơn.

Nguyên tắc nhỏ bé

Bộ não con người khó có thể tiếp nhận một lượng lớn thông tin cùng một lúc. Trong tâm lý học, thuật ngữ tải nhận thức đề cập đến tổng nỗ lực tinh thần cần thiết để lưu giữ thông tin trong trí nhớ. Giảm tải nhận thức cho các nhà phát triển là ưu tiên hàng đầu vì sau đó họ có thể tập trung vào giải quyết vấn đề thay vì giữ trong đầu mô hình phức tạp hiện tại của toàn bộ ứng dụng và các tính năng đang được phát triển.

Nguyên tắc phát triển ứng dụng hiện đại từ NGINX. Phần 1

Các ứng dụng bị phân hủy vì những lý do sau:

  • Giảm tải nhận thức cho các nhà phát triển;
  • Tăng tốc và đơn giản hóa việc kiểm tra;
  • Cung cấp nhanh chóng các thay đổi cho ứng dụng.


Có một số cách để giảm tải nhận thức cho các nhà phát triển và đây là lúc nguyên tắc nhỏ phát huy tác dụng.

Vì vậy, có ba cách để giảm tải nhận thức:

  1. Giảm khung thời gian họ phải cân nhắc khi phát triển một tính năng mới – khung thời gian càng ngắn thì tải nhận thức càng thấp.
  2. Giảm số lượng mã đang được xử lý tại một thời điểm - ít mã hơn - ít tải hơn.
  3. Đơn giản hóa quá trình thực hiện các thay đổi gia tăng cho ứng dụng của bạn.

Giảm khung thời gian phát triển

Hãy quay trở lại thời kỳ mà phương pháp luận waterfall là tiêu chuẩn cho quá trình phát triển và khung thời gian từ sáu tháng đến hai năm để phát triển hoặc cập nhật một ứng dụng là thông lệ. Thông thường, trước tiên, các kỹ sư sẽ đọc các tài liệu liên quan như yêu cầu sản phẩm (PRD), tài liệu tham chiếu hệ thống (SRD), kế hoạch kiến ​​trúc và bắt đầu tích hợp tất cả những thứ này lại với nhau thành một mô hình nhận thức mà theo đó họ viết mã. Khi các yêu cầu và do đó là kiến ​​trúc thay đổi, cần phải thực hiện những nỗ lực đáng kể để thông báo cho toàn bộ nhóm về các bản cập nhật cho mô hình nhận thức. Trong trường hợp xấu nhất, cách tiếp cận này có thể làm tê liệt công việc.

Thay đổi lớn nhất trong quá trình phát triển ứng dụng là sự ra đời của phương pháp linh hoạt. Một trong những đặc điểm chính của phương pháp agile - Đây là sự phát triển lặp đi lặp lại. Đổi lại, điều này dẫn đến việc giảm tải nhận thức cho các kỹ sư. Thay vì yêu cầu nhóm phát triển triển khai ứng dụng trong một chu kỳ dài, agile Cách tiếp cận này cho phép bạn tập trung vào một lượng nhỏ mã có thể được kiểm tra và triển khai nhanh chóng, đồng thời nhận được phản hồi. Tải trọng nhận thức của một ứng dụng đã chuyển từ khung thời gian sáu tháng sang hai năm, với số lượng lớn thông số kỹ thuật, sang bổ sung hoặc thay đổi tính năng trong hai tuần, nhằm mục đích hiểu biết rộng rãi hơn về một ứng dụng lớn.

Chuyển trọng tâm từ một ứng dụng lớn sang các tính năng nhỏ cụ thể có thể được hoàn thành trong vòng chạy nước rút kéo dài hai tuần, chú ý đến không quá một tính năng trong lần chạy nước rút tiếp theo là một thay đổi đáng kể. Điều này giúp tăng năng suất phát triển đồng thời giảm tải nhận thức vốn luôn biến động.

Trong phương pháp luận agile ứng dụng cuối cùng dự kiến ​​​​sẽ là một phiên bản sửa đổi một chút của khái niệm ban đầu, vì vậy điểm phát triển cuối cùng nhất thiết phải mơ hồ. Chỉ có kết quả của mỗi lần chạy nước rút cụ thể mới có thể rõ ràng và chính xác.

Cơ sở mã nhỏ

Bước tiếp theo trong việc giảm tải nhận thức là giảm cơ sở mã. Thông thường, các ứng dụng hiện đại rất lớn—một ứng dụng doanh nghiệp mạnh mẽ có thể bao gồm hàng nghìn tệp và hàng trăm nghìn dòng mã. Tùy thuộc vào cách tổ chức các tệp, các kết nối và phụ thuộc giữa mã và tệp có thể rõ ràng hoặc không. Ngay cả việc gỡ lỗi việc thực thi mã cũng có thể gặp vấn đề, tùy thuộc vào thư viện được sử dụng và mức độ phân biệt giữa các thư viện/gói/mô-đun và mã người dùng của các công cụ gỡ lỗi.

Việc xây dựng mô hình tinh thần làm việc về mã của ứng dụng có thể mất một lượng thời gian đáng kể, một lần nữa đặt gánh nặng nhận thức lớn lên nhà phát triển. Điều này đặc biệt đúng đối với các cơ sở mã nguyên khối, nơi có số lượng mã lớn, sự tương tác giữa các thành phần chức năng không được xác định rõ ràng và việc phân tách các đối tượng cần chú ý thường bị mờ do ranh giới chức năng không được tôn trọng.

Một cách hiệu quả để giảm tải nhận thức cho các kỹ sư là chuyển sang kiến ​​trúc microservice. Theo cách tiếp cận microservice, mỗi dịch vụ tập trung vào một bộ chức năng; ý nghĩa của dịch vụ thường được xác định và dễ hiểu. Ranh giới của dịch vụ cũng rất rõ ràng - hãy nhớ rằng việc liên lạc với dịch vụ được thực hiện bằng API, do đó dữ liệu do một dịch vụ tạo ra có thể dễ dàng được chuyển sang dịch vụ khác.

Tương tác với các dịch vụ khác thường bị giới hạn ở một số dịch vụ người dùng và một số dịch vụ của nhà cung cấp sử dụng các lệnh gọi API đơn giản và rõ ràng, chẳng hạn như REST. Điều này có nghĩa là tải nhận thức của kỹ sư giảm đi đáng kể. Thách thức lớn nhất vẫn là hiểu mô hình tương tác dịch vụ và cách mọi thứ như giao dịch diễn ra trên nhiều dịch vụ. Cuối cùng, việc sử dụng vi dịch vụ giúp giảm tải nhận thức bằng cách giảm số lượng mã, xác định ranh giới dịch vụ rõ ràng và cung cấp thông tin chi tiết về mối quan hệ giữa người dùng và nhà cung cấp.

Những thay đổi gia tăng nhỏ

Yếu tố cuối cùng của nguyên tắc một chút là quản lý sự thay đổi. Điều đặc biệt hấp dẫn đối với các nhà phát triển là nhìn vào cơ sở mã (thậm chí có thể là mã cũ hơn của chính họ) và nói, "Thật là tào lao, chúng ta cần phải viết lại toàn bộ thứ này." Đôi khi đó là quyết định đúng đắn, đôi khi lại không. Nó đặt gánh nặng về những thay đổi mô hình toàn cầu lên nhóm phát triển, từ đó dẫn đến tải trọng nhận thức lớn. Tốt hơn hết là các kỹ sư nên tập trung vào những thay đổi mà họ có thể thực hiện trong quá trình chạy nước rút, để sau đó họ có thể triển khai các chức năng cần thiết một cách kịp thời, mặc dù dần dần. Sản phẩm cuối cùng phải giống với sản phẩm đã được lên kế hoạch trước nhưng có một số sửa đổi và thử nghiệm để phù hợp với nhu cầu của khách hàng.

Khi viết lại những phần lớn mã, đôi khi không thể nhanh chóng đưa ra thay đổi vì các phụ thuộc hệ thống khác phát huy tác dụng. Để kiểm soát luồng thay đổi, bạn có thể sử dụng tính năng ẩn. Về cơ bản, điều này có nghĩa là chức năng này đã có trong quá trình sản xuất nhưng không có sẵn thông qua cài đặt biến môi trường (env-var) hoặc bất kỳ cơ chế cấu hình nào khác. Nếu mã đã vượt qua tất cả các quy trình kiểm soát chất lượng, nó có thể sẽ được đưa vào sản xuất ở trạng thái ẩn. Tuy nhiên, chiến lược này chỉ hoạt động nếu tính năng này cuối cùng được bật. Nếu không, nó sẽ chỉ làm lộn xộn mã và thêm tải nhận thức mà nhà phát triển sẽ phải đối phó để làm việc hiệu quả. Bản thân việc quản lý thay đổi và các thay đổi gia tăng giúp duy trì tải trọng nhận thức của nhà phát triển ở mức dễ tiếp cận.

Các kỹ sư phải vượt qua nhiều khó khăn ngay cả khi chỉ thực hiện chức năng bổ sung. Sẽ là khôn ngoan nếu ban quản lý giảm khối lượng công việc không cần thiết trong nhóm để có thể tập trung vào các yếu tố chính của chức năng. Có ba điều bạn có thể làm để giúp nhóm phát triển của mình:

  1. Sử dụng phương pháp agile, để giới hạn khung thời gian mà nhóm phải tập trung vào các tính năng chính.
  2. Triển khai ứng dụng của bạn dưới dạng một số dịch vụ vi mô. Điều này sẽ hạn chế số lượng tính năng được giới thiệu và củng cố ranh giới chứa tải nhận thức khi làm việc.
  3. Thích những thay đổi tăng dần đối với những thay đổi lớn, khó sử dụng, thay đổi những đoạn mã nhỏ. Sử dụng tính năng ẩn để thực hiện các thay đổi ngay cả khi chúng không hiển thị ngay sau khi được thêm.

Nếu bạn áp dụng nguyên tắc nhỏ trong công việc, nhóm của bạn sẽ hạnh phúc hơn nhiều, tập trung tốt hơn vào việc cung cấp các tính năng cần thiết và có nhiều khả năng triển khai các thay đổi về chất lượng nhanh hơn. Nhưng điều này không có nghĩa là công việc không thể trở nên phức tạp hơn; ngược lại, đôi khi, việc giới thiệu chức năng mới đòi hỏi phải sửa đổi một số dịch vụ và quy trình này có thể phức tạp hơn quy trình tương tự trong kiến ​​​​trúc nguyên khối. Trong mọi trường hợp, lợi ích của việc sử dụng phương pháp này hơi đáng giá.

Hết phần thứ nhất.

Chúng tôi sẽ sớm xuất bản phần thứ hai của bản dịch, nhưng bây giờ chúng tôi đang chờ ý kiến ​​đóng góp của các bạn và mời các bạn cùng tham khảo. Ngày khai trương, sẽ diễn ra vào lúc 20.00h hôm nay.

Nguồn: www.habr.com

Thêm một lời nhận xét