Kiểm soát chủ động
Kiểm soát chủ động
“Everything fails, all the time.”, Werner Vogels, CTO của Amazon Mọi thứ đều sẽ hỏng, vào một lúc nào đó.
Tôi đã từng chia sẻ về topic Assume Failure. Chúng ta không thể đảm bảo 100% những gì mình làm sẽ không phát sinh lỗi. Vậy thay vì cố ngăn chặn mọi sự cố, hệ thống và cả cách làm việc của chúng ta nên được thiết kế theo hướng phát hiện sớm, xử lý và phục hồi nhanh, sao cho khách hàng và người dùng cuối không bị gián đoạn.
Bài viết này nói về bước tiếp theo của tinh thần đó: cụ thể thì chúng ta phải làm gì.
Kiểm soát chủ động là gì
Gói lại trong một câu:
Một công việc chỉ được coi là hoàn thành khi nó đi kèm phương án kiểm soát của chính nó.
Nghĩa là khi chúng ta làm một tính năng, chạy một job, cập nhật một cấu hình, hay gửi một dữ liệu ra ngoài, thì ngoài việc làm cho nó chạy đúng, chúng ta chuẩn bị sẵn ba thứ:
- Cách để biết khi nó chạy sai, không chờ khách hàng phát hiện.
- Cách để giới hạn thiệt hại, sai thì sai trong phạm vi nhỏ, không lan ra cả hệ thống.
- Cách để dừng lại và quay về trạng thái an toàn, nhanh, và ai cũng biết phải làm gì.
Điểm quan trọng nhất là ở chỗ này: những việc trên phải là thứ nhìn thấy được, kiểm tra được và giao lại cho người khác được. Nó là một phần công việc phải làm, chứ không phải chuyện tùy vào ý thức của từng người.
Ý này không mới, và người Nhật đã làm nó từ rất lâu
Ở Toyota có nguyên tắc jidoka (自働化): máy móc được thiết kế để tự phát hiện bất thường, tự dừng lại và bật đèn gọi người, chứ không chạy tiếp để lỗi trôi xuống cuối dây chuyền, nơi mà việc sửa trở nên đắt gấp nhiều lần. Cùng tinh thần đó là poka-yoke: thiết kế sao cho làm sai trở nên khó, thay vì dặn nhau đừng làm sai.
Điều Tôi muốn các bạn nhớ từ đây:
Một cái máy biết tự dừng thì đáng tin hơn một cái máy chưa bao giờ hỏng.
Chúng ta không bán cho khách hàng lời hứa “không bao giờ sai”. Không ai tin lời hứa đó, và họ có lý. Chúng ta bán năng lực luôn nằm trong tầm kiểm soát. Đó là hai thứ hoàn toàn khác nhau, và thứ thứ hai mới là thứ giữ được khách hàng lâu dài.
Bốn câu hỏi, hỏi ngay từ lúc thiết kế
Không phải lúc sắp release, mà lúc bắt đầu.
1. Cái gì có thể sai, và ai bị ảnh hưởng? Sai ở đâu: logic, dữ liệu, tích hợp bên ngoài, hiệu năng, phân quyền? Việc mình sắp làm có ai đang phụ thuộc vào không? Người bị ảnh hưởng là hệ thống nội bộ, là khách hàng, hay là người dùng cuối của khách hàng?
2. Làm sao mình biết, và sau bao lâu? Có gì để phát hiện: log, monitor, alert, đối chiếu số liệu? Biết sau 1 phút hay sau 1 tuần? Hay chỉ biết khi khách hàng gửi mail?
3. Ai biết, và bằng cách nào? Cảnh báo đi tới đâu, ai chịu trách nhiệm nhìn thấy nó, ngoài giờ làm việc thì sao?
4. Biết rồi thì làm gì? Có tắt riêng phần đó được không? Rollback thế nào, mất bao lâu? Dữ liệu đã ghi sai thì xử lý ra sao? Ai cần được thông báo, và thông báo cho khách hàng bằng cách nào, ai là người nói?
Một ví dụ cụ thể
Giả sử chúng ta làm một job: mỗi 6h sáng tự động tổng hợp dữ liệu và gửi báo cáo cho khách hàng.
Cách làm cũ, code chạy đúng là xong. Job chạy được, gửi được mail, test thấy ổn, giao hàng. Ba tuần sau job chết lúc 2h sáng vì API bên thứ ba đổi format. Không ai biết. Bốn ngày sau khách hàng hỏi “sao mấy hôm nay không thấy báo cáo?”. Chúng ta xin lỗi, sửa gấp, và mất một phần niềm tin không lấy lại được bằng lời giải thích.
Cách làm với kiểm soát chủ động:
| Câu hỏi | Trả lời |
|---|---|
| Cái gì có thể sai? | Job không chạy. Chạy nhưng dữ liệu thiếu hoặc sai. Gửi đúng nội dung nhưng sai người nhận |
| Làm sao biết? | Job báo “đã hoàn thành” về một kênh cố định. Nếu 6h30 không thấy tín hiệu thì cảnh báo. Thêm một phép kiểm tra đơn giản: số dòng dữ liệu lệch quá 30% so với hôm trước thì cảnh báo và không gửi |
| Ai biết? | Cảnh báo vào kênh chung của dự án. |
| Biết rồi làm gì? | Có công tắc tắt job. Có thể chạy lại bằng tay. Danh sách người nhận nằm ở cấu hình, cần 2 người review trước khi đổi. Nếu đã gửi sai: báo cáo ngay với khách hàng. |
Chi phí thêm khoảng nửa ngày. Cái nó tránh được là bốn ngày khách hàng không có báo cáo mà chúng ta không hay biết. Và trong trường hợp gửi sai người nhận, đó có thể là một sự cố bảo mật thật sự.
Việc không phải code cũng vậy
Chuyện này không chỉ dành cho Development. Ví dụ ở backofffice: gửi một email thông báo hàng loạt kèm file đính kèm.
- Cái gì có thể sai? Sai danh sách người nhận. File còn sót thông tin không nên gửi. Gửi bản chưa được duyệt.
- Làm sao biết? Không có cách nào biết sau khi đã bấm Send. Vậy nên kiểm soát phải nằm ở phía trước: một người thứ hai xem lại danh sách và file.
- Biết rồi làm gì? Có thu hồi được không (thường là không)? Ai thông báo, và nói gì?
Tôi nêu ví dụ này vì nó cho thấy một điều quan trọng: có những việc không có bước phục hồi. Với những việc đó, toàn bộ kiểm soát phải dồn về phía trước. Và chúng ta cần nhận ra mình đang ở tình huống nào trước khi bắt tay vào làm.
Ba nguyên tắc
1. Kiểm soát phải tương xứng với rủi ro. Một màn hình hiển thị nội bộ và một job xử lý dữ liệu thanh toán của khách hàng là hai câu chuyện khác nhau. Hãy hỏi: nếu cái này sai âm thầm trong 3 ngày thì hậu quả tới đâu? Càng nặng thì kiểm soát càng phải chặt. Ngược lại, cũng đừng kiểm soát quá mức ở những việc rủi ro thấp, vì vừa tốn công vừa tạo ra cảnh báo rác khiến mọi người mất dần sự chú ý. Cảnh báo mà không còn ai nhìn thì tệ hơn là không có cảnh báo, vì nó cho ta cảm giác an toàn không có thật.
2. Kiểm soát chưa được thử thì coi như chưa có. Cảnh báo chưa từng bắn thử, rollback chưa từng làm thử, backup chưa từng restore, đó mới chỉ là mong rằng nó sẽ hoạt động, chứ chưa phải là kiểm soát. Hãy tự tạo một lỗi giả và kiểm chứng, ít nhất một lần, trước khi giao hàng. Việc này thường chỉ mất 15 phút, và thường sẽ phát hiện ra là cảnh báo đang cấu hình sai.
3. Sự cố bảo mật là loại lỗi im lặng nhất. Phân quyền cấp rộng quá mức, dữ liệu khách hàng đi ra ngoài phạm vi cho phép, tài khoản của người đã rời công ty, rời team dự án vẫn còn hoạt động. Những thứ này không báo lỗi. Hệ thống vẫn chạy hoàn toàn bình thường. Đó chính là lý do chúng phải được kiểm soát một cách chủ động, vì sẽ không có gì tự động nhắc chúng ta.
Và một lưu ý theo chiều ngược lại, cũng rất quan trọng: log và cảnh báo không được trở thành lỗ hổng. Không đưa dữ liệu khách hàng, thông tin cá nhân, token hay mật khẩu vào log, vào nội dung cảnh báo, hay vào ảnh chụp màn hình gửi qua chat. Chúng ta muốn nhìn rõ hơn vào hệ thống của mình, nhưng không được vì thế mà làm lộ thêm dữ liệu ra ngoài.
Ở cấp độ dự án
- Rà soát những gì đang chạy. Tính năng, job, tích hợp nào mà hiện tại nếu hỏng thì chúng ta chỉ biết khi khách hàng nói? Đó là danh sách việc cần làm ngay, và thường ngắn hơn mọi người tưởng.
- Chuẩn bị sẵn kịch bản cho các tình huống lỗi chính, và thống nhất trước với khách hàng: ai thông báo, trong bao lâu, cách xử lý tạm thời là gì. Nếu cần thì cập nhật SLO tương ứng. Việc chủ động đề xuất chuyện này với khách hàng Nhật tạo niềm tin rất mạnh, vì rất ít đối tác làm.
- Đưa bốn câu hỏi vào bước design review và vào tiêu chí hoàn thành công việc, để nó thành thói quen chứ không phụ thuộc vào việc ai đó có nhớ hay không.
- Khi có sự cố, trả lời thêm một câu: lần sau chúng ta sẽ biết sớm hơn bằng cách nào? Nếu câu trả lời là “sẽ cẩn thận hơn” thì chúng ta chưa học được gì.
Bảng áp dụng, dùng ngay cho công việc tiếp theo của bạn
Trước khi bắt tay vào việc, tự trả lời 4 câu. Cột bên phải là những câu trả lời không được tính:
| Câu hỏi | Câu trả lời KHÔNG hợp lệ |
|---|---|
| 1. Cái gì có thể sai, và ảnh hưởng tới đâu? | “Chắc không sao đâu”, “Cái này đơn giản mà” |
| 2. Làm sao mình biết, sau bao lâu? | “Nếu lỗi thì sẽ thấy thôi”, “Khách hàng sẽ báo”, “Đã có ghi log” (log mà không ai đọc thì không phải là phát hiện) |
| 3. Ai biết, và bằng cách nào? | “Chắc ai đó sẽ để ý”, hoặc cảnh báo gửi vào chat riêng của một người |
| 4. Biết rồi thì làm gì, mất bao lâu? | “Thì sửa”, “Đến lúc đó tính” |
Ba câu tự kiểm tra cuối cùng, trước khi nói “xong”:
- Kiểm soát của tôi đã được thử chưa, dù chỉ một lần?
- Nếu tôi nghỉ phép và việc này hỏng, người khác có đủ thông tin để xử lý không?
- Log và cảnh báo của tôi có chứa dữ liệu không nên có không?
Cuối cùng
Tôi không kỳ vọng chúng ta không bao giờ có lỗi, vì điều đó là không thể.
Tôi kỳ vọng khi lỗi xảy ra, chúng ta biết vì đã chuẩn bị sẵn để biết, chứ không phải vì tình cờ có người nhìn thấy, hay vì được ai đó nhắc. Và biết rồi thì đã có sẵn phương án, không phải đến lúc đó mới bắt đầu suy nghĩ.
Cùng là phát hiện sớm, nhưng nếu sớm nhờ may mắn thì lần sau chưa chắc còn may.
Đó là khác biệt giữa một đội bị động và một đội chuyên nghiệp, và cũng là điều khách hàng Nhật đánh giá cao nhất ở một đối tác offshore.



