12 yếu tố tạo nên 1 web app xịn xò – Lược dịch và giải thích Twelve-Factor

Sau một thời gian lập trình, bạn sẽ dần nhận ra một điều: Build một ứng dụng là một chuyện khá khó.

Thế nhưng, khi ứng dụng đã bắt đầu có người sử dụng (lên production), ta sẽ gặp phải nhiều vấn đề còn … khó hơn nữa:

  • Làm sao thêm tính năng, sửa lỗi mà không ảnh hưởng đến ứng dụng đang chạy
  • Làm sao để những tính năng mới, bug fix có thể được release nhanh chóng đến tay người dùng
  • Khi lượng người dùng tăng gấp 5, gấp 10 lần, làm sao để có thể nhanh chóng scale hệ thống
  • Làm sao để mấy bạn developer mới gia nhập có thể dễ dàng chạy ứng dụng ở local, test và push code

Đây là những vấn đề làm đau đầu nhiều team, vì nó đòi hỏi không chỉ kiến thức lập trình, mà còn là kiến thức về system architecture, operation, qui trình….

Do vậy, trong bài này, mình sẽ chia sẻ về Twelve-Factor App (12factor.net). Đây là 12 yếu tố cần thiết để xây dựng 1 ứng dụng “xịn xò”, ổn định, dễ mở rộng, dễ deploy nhé.

 

Đây là phần 1 trong series 3 phần về Twelve-Factor App:

  1. Lược dịch và giải thích Twelve-Factor. Giải thích Codebase và Dependencies
  2. Giải thích Config, Backing Service, Build -> Release -> Run, Processes, Port Binding
  3. Giải thích Concurrency, Disposability, Dev/Prod Parity, Logs, Admin Processes

Twelve-Factor App này có cái gì hay ho?

Đây là những kinh nghiệm được tổng hợp từ các developer đã tham gia phát triển về deploy, vận hành vài trăm app trên nền tảng Heroku.  Bạn có thể xem 12 yếu tố này là cách để build 1 web app dễ mở rộng, dễ deploy, dễ tiếp cận cho developer mới gia nhập luôn.

Cá nhân mình thấy những kinh nghiệm này khá hữu ích, nó giải quyết được khá nhiều vấn đề chúng ta thực sự gặp phải khi xây dựng, vận hành 1 ứng dụng web.

Bản thân mình khuyên các bạn nên đọc bản gốc tiếng Anh trước (12factor.net). Mình sẽ trình bày lại 12 yếu tố này theo cách hiểu của mình, đưa thêm 1 số ví dụ thực tế nhé!

Đây là những kinh nghiệm mồ hôi, xương máu qua bao đời developer

12 yếu tố này bao gồm:

  1. Codebase: Một codebase nằm trong source control, deploy lên nhiều nơi
  2. Dependencies: Depedencies như library/framework/extension phải được ghi rõ ràng, tách biệt từng app
  3. Config: Lưu trữ thiết lập vào biến môi trường (environment variable)
  4. Backing services: Xem các service đi kèm (database, API, …) như là resource của app
  5. Build, release, run: Tách riêng quá trình release, build và run
  6. Processes: App nên chạy dưới dạng stateless processes
  7. Port binding: Một service có thể được access thông qua 1 port cố định
  8. Concurrency: Một app nên được chia tách thành nhiều process nhỏ để tăng concurrency
  9. Disposability: Process của web app nên sống nhanh, chết vội, để có thể dễ dàng chạy/kill process nhanh chóng
  10. Dev/prod parity: Các môi trường dev/staging/production nên giống nhau hết sức có thể
  11. Logs: Logs nên được viết ra dạng stream ở stdout
  12. Admin Processes: Một số task dạng admin (tạo database, fix dữ liệu) nên được chạy trong cùng môi trường với app đang chạy

 

Nếu các bạn đọc qua thấy không hiểu cũng không sao. Mình sẽ giải thích kĩ hơn và đưa 1 số ví dụ cụ thể cho từng yếu tố nhé.

Có 1 số yếu tố mình không đồng tình, hoặc không phù hợp khi áp dụng vào các ngôn ngữ như C#, Java, nên mình cũng sẽ giải thích và chia sẻ thêm.

1. Codebase: Một source code trong source control, có nhiều deploy

Mỗi app chỉ nên có 1 source code (codebase) duy nhất, nằm trong source control như Git/SVN.

Mỗi khi code được build và chạy trên một môi trường nào đó, ta gọi nó là một bản deploy.

Code chạy trên môi trường Production gọi là Production deploy, chạy trên Staging gọi là Staging deploy. Deploy trên staging có thể có nhiều commit hơn, nằm ở branch khác Production, nhưng 2 code này đều nằm trong 1 source control.

Code trên Product có thể khác code trên Staging, nhưng đều nằm chung 1 repo cả!

Nhờ vậy, khi có developer mới gia nhập, ta có thể dễ dàng lấy và đọc source code từ source control.

Gần đây, khi kiến trúc microservice đang thịnh hành, ta có thể dùng monorepo – 1 repo chứa toàn bộ source code của các service. Hoặc có thể coi mỗi service là 1 app, lưu source code của service đó vào 1 repo riêng.

2. Dependencies: Dependencies rõ ràng, tách biệt

Cho các bạn chưa biết, depedencies tức là các package/thư viện/tool của bên thứ 3, mà app của bạn cần có để chạy được.

Một app cần phải thiết lập rõ ràng những dependency mà nó sử dụng, không lệ thuộc vào các dependency có sẵn của hệ thống. Các dependencies này phải tách biệt trong từng app.

Giả sử thế này, bạn đang viết ứng dụng nhận dạng JAV Idol, sử dụng thư viện IdolRec ver 2.1. Thằng bạn của bạn cũng viết ứng dụng nhận diện EU Idol, sử dụng IdolRec ver 1.3:

  • Cách thức đúng ở đây là: app sẽ ghi rõ mình dùng thư viện IdolRec + version. Thư viện này sẽ bỏ vào thư mục của app, chạy trong app.
  • Nếu ứng dụng phụ thuộc vào dependencies ngầm trong máy, sẽ dễ dẫn đến tình trạng “It works on my machine” => Chạy được trên máy của dev, nhưng lên Production thì tèo…
  • Nếu không ghi rõ, tách biệt dependeices, khi 2 ứng dụng chạy trên 1 máy sẽ bị conflict vì 2 thư viện khác nhau. Hoặc có thể … không chạy được vì máy kia chưa xài IdolRec

Hiện tại, đa phần các ngôn ngữ lập trình đều có cách package manager hỗ trợ chuyện này (NodeJS thì lưu dependencies vào file package.json, Ruby thì có bundler lưu depedencies vào gemfile, C# thì lưu vào Web.config hoặc App.config ….).

Nếu ứng dụng phụ thuộc vào dependencies trong máy, sẽ dễ dẫn đến tình trạng “It works on my machine” => Chạy được trên máy của dev, nhưng lên Production thì tèo…

Nhờ vậy, khi ta deploy ứng dụng lên server, hoặc developer mới gia nhập pull code về, ta chỉ cần chạy npm install hoặc bundle install để tải thư viện về, là ứng dụng có thể chạy bình thường, không cần cài dependencies ngầm.

Tạm kết

Bài này đã dài rồi nên mình tạm kết thúc ở đây! Mình sẽ tiếp tục giải thích các yếu tố còn lại ở những phần sau nhé.

One thought on “12 yếu tố tạo nên 1 web app xịn xò – Lược dịch và giải thích Twelve-Factor”

Leave a Reply to StarVipAS Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s