The Twelve Factors - SilverSky9/DevToolNo1 GitHub Wiki

The Twelve Factors

1. Codebase

One codebase tracked in revision control, many deploys

คือโค้ดอยู่ที่เดียวกัน version เดียวกัน โดย control version ที่ git, sub version โดย 1 โปรเจคควรมีแค่ที่เดียว ถึงแม้ว่าจะทำ microservice ที่มีหลายๆ service ก็ควรอยู่ที่ repository เดียวกัน การใช้โปรเจ็คร่วมกันเพื่อลดปัญหาการ comunication กันภายใน ก่อนที่จะแยก repo ควรทำแบบที่รวม repo กัน แล้วทำงานให้ได้ก่อน แล้วเมื่อทำงานได้แล้วจะแยกแต่ละ service ออกจากกันที่หลังก็ได้

2. Dependencies

Explicitly declare and isolate dependencies

Dependencies มักจะไม่ประกาศในโปรเจคตรงๆ แต่จะเป็นแค่การประกาศเพียงแค่ว่าเราจะใช้ library ตัวไหน version อะไรบ้าง เช่น package.json

3. Configuration

Store config in the environment

configuration ที่ดีไม่ควรอยู่ใน Application ควรจะต้องถูกแยกออกมาอยู่ใน System environment, configuration server หรือ remote configuration เพื่อที่จะสามารถแก้ไขได้ โดยที่จะไม่กระทบกับ code ใน application ตัวอย่างเช่น การกำหนด Environment Variable ที่ใช้ในระบบ ในไฟล์ .env นอกจากนี้ไม่ควรเก็บ configuration ไว้ที่ Database เพียงเพื่อจะทำให้สามารถแก้ไขได้ โดยการ reload configuration ใหม่

4. Backing services

Treat backing services as attached resources

ระบบการทำงานต้องมีความง่ายต่อการ deploy สามารถเปลี่ยนได้ง่าย ยกตัวอย่าง ถ้าหากต้องการเปลี่ยน Database หรือ File system ของ service ก็สามารถเปลี่ยนได้ โดยมี Downtime ให้น้อยที่สุด

5. Build, release, run

Strictly separate build and run stages

ควรแยก process ในการ Build, Release, Run แยกออกจากกัน การ build คือการเอา source code ทุกอย่างมาทำ software test จากนั้นก็ ค่อย release แล้ว run ให้จบไปเป็น step step ไป จะไม่รวมกันเป็น step เดียว เพราะว่า ถ้ามีการผิดพลาดในแต่ละขั้นตอนแล้ว เราจะสามารถแก้ไขได้ง่าย และรู้ได้ว่าเกิดข้อผิดพลาดจากตรงไหนได้ง่ายขึ้น

6. Processes

Execute the app as one or more stateless processes

ทุกๆ service ควรทำให้เป็น stateless process Service ต่างๆ ไม่ควรจะเป็นข้อมูลอะไรไว้ใน service ของตัวเอง เพราะถ้าหากต้องการจะย้ายข้อมูลจะลำบาก ควรให้ server ทำตามแค่หน้าที่ตาม Business logic เท่านั้น ยกตัวอย่าง พวกไฟล์รูป ควรเก็บอยู่ใน Nas storage ไม่ควรเก็บอยู่ที่ข้อมูล ใน contrainner เพราะถ้าหากต้องการย้าย หรือเปลี่ยนข้อมูล ไฟล์รูปต่างๆ ก็จะต้องถูกขนย้ายออกมาด้วย

7. Port binding

Export services via port binding

เป็นเรื่องของ contrainner ปกติคือ สามารถที่จะรัน port เดียวกันได้ หลายตัวบนเครื่องเดียวกัน โดยหากต้องการใช้ port ก็ expose port ออกมา ก็จะสามารถเรียกใช้งานได้ ทำให้ไม่ต้องแก้ port เพื่อให้ service ต่างๆทำงานได้

8. Concurrency

Scale out via the process model

เป็น model ในการ scale ตามแต่ละ service ถ้า service ไหนที่การใช้งานเยอะ ก็ scale เฉพาะ service นั้นให้มีจำนวนเครื่องที่ใช้ให้เหมาะสมตามการใช้งานของ service

9. Disposability

Maximize robustness with fast startup and graceful shutdown

ระบบงานต้อง start ได้เร็วและจบลงได้สวย เพื่อลด Downtime ยกตัวอย่าง java spring boot ใน contrainner. contrainner start ขึ้นมาเสร็จแล้ว แต่ตัว spring ยัง start ยังไม่เสร็จ หมายความว่า service จะยังไม่พร้อมใช้งานจนกว่า spring boot จะ start เสร็จ ซึ่งจะทำให้เกิด Downtime ของ service นั้นเพิ่มขึ้น

10. Dev / prod parity

Keep development, staging, and production as similar as possible

ควรทำให้ environment ให้เหมือนกันที่สุดเท่าที่จะทำได้ เหมือนกันในที่นี้หมายถึงโครงสร้างของ environment ยกตัวอย่าง หาก production มี load balance ที่ dev ก็ควรจะมี load balance ด้วย เพือทำให้ environment เหมือนกันมากที่สุด หรือ หาก database ที่ production เป็นแบบ multi master ที่ dev ก็ควรจะเป็นเหมือนกัน

11. Logs

Treat logs as event streams

ทำ centralized log พยายามคิดว่า log ต่างๆ เป็น steam โดยที่อยากจะเก็บอะไรก็ค่อยเอา tool ต่างๆมาเก็บข้อมูลที่เราอยากจะเก็บ

12. Admin processes

Run admin/management tasks as one-off processes

พยายามทำให้ทุกๆ เครื่อเหมือนกัน admin task ของแต่ละ service ถ้า admin ต้องการจะทำอะไรควรทำผ่านช่องทางหรือชุดคำสั่งที่กำหนดไว้ให้ ไม่ควรทำเองโดยไม่่ผ่านชุดคำสั่ง ในของแต่ละ service นั้นๆ เพื่อลดปัญหาในการเปลี่ยนแปลงที่จะไม่เหมือนกันในแต่ environment

ตัวอย่างการนำ Twelve Factors ไปใช้ภายในโปรเจค

1. Codebase

  • ใช้ Git Version Control ในการทำงาน

2. Dependencies

  • กำหนด Dependencies ต่างๆที่ต้องการใช้ในไฟล์ package.json

3. Configuration

  • กำหนด Environment Variable ภายในไฟล์ .env

4. Build, release, run

  • ใช้ Dockerfile และ docker-compose.ymal

5. Port binding

  • มีการกำหนด Port ที่ต้องการใข้งานใน docker-compose.ymal