Bỏ qua tới nội dung
Kiên

"Ôm" một release train thật ra là làm những gì

· 4 phút đọc

Tám gateway service, một nhánh tích hợp chung, và một cú đẩy lên production luôn là hành động có chủ đích, gom theo đợt, với một con người đứng ở nút bấm. "Đơn vị release là cả cụm, không phải từng repo" trông như thế nào khi nó phải chạy hàng tuần, thay vì nằm yên trong danh sách nguyên tắc.

  • release engineering
  • multi-repo
  • quy trình
  • CI/CD
Mục lục
  1. Đoàn tàu là một cái nhánh
  2. Đơn vị release là cả cụm, không phải từng repo
  3. Một con người bấm nút production
  4. "Go-live" đã thành một lời khẳng định có kiểm chứng
  5. Con số mình không có

"Release train" thường chỉ là chữ trang trí — một cụm từ làm cho cái lịch deploy nghe giống hạ tầng. Mình muốn viết ra nó nghĩa là gì khi nó là nghĩa đen, vì mình đang ôm đúng một chuyến như thế, trải trên tám gateway service, và phần lớn những thứ khiến nó chạy được thì đứng ngoài nhìn vào không thấy.

Đoàn tàu là một cái nhánh

Việc làm xong thì merge vào một nhánh tích hợp chung. Cái nhánh đó gom dần: một bản fix chỗ này, một tích hợp supplier chỗ kia, một thay đổi mapping, một cú refactor. Merge vào đó chưa release cái gì cả — nó là sân ga, nơi các toa gom lại.

Đẩy nhánh đó lên production là một hành động riêng, và nó được gom theo đợt một cách có chủ đích. Thứ được đưa ra ngoài không phải là "hôm nay lỡ merge gì thì đi nấy"; nó là một tập thay đổi có người đã nhìn vào, nhìn như một tập, rồi quyết định cho đi. Câu hỏi lúc promote không phải "commit này ổn chưa?" — câu đó đã trả lời lúc merge rồi. Câu hỏi là "cái tổ hợp này ổn chưa, trên cả tám service, theo đúng thứ tự này?"

Mỗi lần push là một lần bump version. Nghe như thủ tục giấy tờ, cho tới đúng cái ngày bạn cần nó: "production đang chạy cái gì" luôn trả lời được bằng một con số chính xác cho từng service, và "bản fix đã ra thật chưa" thôi không còn là chuyện ai nói nấy nghe.

Đơn vị release là cả cụm, không phải từng repo

Câu đó nằm trong mục Cách tôi làm việc trên site này, và nó là toàn bộ thiết kế gói trong một dòng. Một đợt go-live có thể trải trên mười một repository. Khi đã trải như thế, thứ tự merge là một phần của thiết kế, không phải chuyện tính sau: contract phía backend phải vào trước những consumer đọc nó. Chạy ngược thứ tự là mở ra một khoảng thời gian mà consumer đi hỏi một cái contract chưa tồn tại — và trong domain này, thất bại kiểu đó hiếm khi là một cú crash. Nó là một con số sai, được tính ra một cách rất tự tin.

Nên thứ tự merge được viết ra cùng với tính năng, giống như một bản migration schema được viết ra cùng đoạn code cần nó. Để đến ngày go-live mới quyết, bằng trí nhớ, chính là cách cái khoảng hở kia bị mở ra.

Một con người bấm nút production

Deploy đi qua pipeline CI chạy tay. Một con người bấm nút, và bước production còn đòi xác nhận tường minh một lần nữa rồi mới chạy.

Mình biết trọng tâm của ngành đang nằm ở đâu, và nó không nằm ở đây. Continuous deployment là câu trả lời đúng cho rất nhiều hệ thống. Nhưng hệ này đứng giữa đối tác và nhà cung cấp, và kiểu hỏng đặc trưng của nó — đã được viết lại ở chỗ khác trên site này — không phải một exception trên dashboard. Nó là tiền bị tính sai mà không có lấy một dòng lỗi. Với hình dạng thất bại như thế, mình muốn khoảnh khắc không-quay-đầu-được phải có một con người đứng trong đó, và muốn cái đợt release đủ nhỏ để người đó giữ được trong đầu. Cái giá là độ trễ, và một con người phải ngồi đó vào một tối thứ Sáu nào đó. Mình trả cái giá đó một cách có chủ đích.

"Go-live" đã thành một lời khẳng định có kiểm chứng

Lý do mình không dám giao mấy chuyện trên cho kỷ luật suông đã được viết lại trong case study go-live đa repo: một tính năng trải trên mười một repository ra khơi với một repo chưa bao giờ có tên trong danh sách, và production đã thu thiếu tiền của khách suốt bốn ngày so với con số UI hiển thị — không một exception nào ném ra ở bất cứ đâu.

Sau vụ đó, bước kiểm tra thành một cái tool: một multi-repo checker dùng lại được, xác minh tính năng đã thật sự vào master ở đủ các repo mà nó động tới, trước khi bất kỳ ai được tuyên bố go-live. Chữ "go-live" đổi hẳn từ loại — từ một lời thông báo ai đó hô lên, thành một khẳng định đã có tool kiểm. Người vẫn là người hô; chỉ là người đó không còn kiêm luôn vai bằng chứng nữa.

Con số mình không có

Đoạn kết trung thực là: mình không đưa ra được con số incident trước/sau. Case study kia ghi lại hai incident của một đợt go-live chạy theo lối cũ; trước đó không ai đếm incident-trên-mỗi-đợt-release, và cũng không có cái máy đếm nào cho những incident không xảy ra kể từ khi có checker. Đăng lên đây dòng "incident giảm N%" sẽ là đúng cái loại số đẹp-mà-chưa-đo mà site này sinh ra để từ chối.

Thứ mình đếm được: tám service trên chuyến tàu, một nhánh tích hợp, mười một repository ở lần trải rộng nhất, một cái checker, một bước xác nhận đứng chắn trước production. Và một cú đổi hạng mục mà mình chỉ thẳng ra được: câu hỏi "mọi thứ vào đủ chưa?" trước đây trả lời bằng trí nhớ, giờ trả lời bằng một cái tool không biết chán ở repo thứ mười một.

Ôm một chuyến release train nghĩa là như thế. Không phải cái lịch chạy tàu — mà là cái đợt, cái thứ tự, cái nút bấm, và cái bằng chứng.

Bài liên quan

· 5 phút đọc

Một danh sách những thứ là contract mà nhìn không giống contract — một định danh client cầm giữa hai lần gọi, một mã lỗi đã ghi thành tài liệu, và ba nghĩa khác nhau của thiếu field, field rỗng và field null. Vì sao thêm thì gần như miễn phí còn bỏ đi là một đợt release phối hợp qua những repo mình không deploy, và giữ cho mọi thứ chạy được thì tốn thật những gì.

  • API design
  • tương thích ngược
  • multi-repo
  • release

· 5 phút đọc

Kỹ thuật review sau một năm review cho sáu người: ba thứ một lượt review thật sự đang kiểm, một thứ nó không dùng để làm, vì sao mỗi comment giờ tự nói ra nó có chặn hay không, và bốn câu hỏi mình hỏi với mọi thay đổi đụng tới tiền hoặc state. Chưa từng đo thời gian review hay tỉ lệ lỗi — thứ đếm được là cái các lượt review để lại.

  • code review
  • nghề
  • quy trình
  • team