Hai dải mạng, cần cả hai
Công việc hằng ngày ở đây cần hai dải mạng riêng biệt vào được cùng một lúc: database staging nằm ở một dải, production ở dải kia. Trên laptop thì cả hai đi chung một đường kết nối, và ngày đẹp trời thì cả hai cứ thế mà chạy.
Sau một lần mạng thay đổi — reconnect, máy sleep rồi wake, chuyển từ mạng này sang mạng khác — thì đôi khi không còn thế nữa. Route của một dải, hoặc cả hai, có thể bind nhầm interface. Packet gửi cho dải staging chui ra một cái interface chẳng biết dải đó nằm đâu, và không bao giờ có gì quay về.
Triệu chứng nói dối
Đây là chỗ khiến cái lỗi này đắt: từ chỗ bạn ngồi, nó không phân biệt nổi với ít nhất ba vấn đề khác. Connection treo, hoặc bị refuse. Đó cũng đúng là bộ mặt của sai credentials, của một cái host chết thật, và của DNS đưa cho bạn câu trả lời ôi thiu. Client library thì báo bất cứ thứ gì cái timeout của nó thích báo, và chuỗi lỗi chẳng gọi tên tầng nào bên dưới cả.
Thế nên phản xạ tự nhiên là đoán. Mình từng gõ lại những cái password vốn đã đúng. Mình từng đi hỏi database có sập không trong khi nó vẫn phục vụ mọi người khác bình thường. Đoán thì không loại được gì: sau mỗi lần đoán, bạn biết đúng bằng lúc trước khi đoán, trừ đi thời gian.
Cái thứ tự
Thứ thay đổi hình dạng của những buổi chiều đó không phải một câu lệnh thông minh, mà là một thứ tự cố định — bốn câu hỏi, hỏi từ rẻ nhất trở đi, mỗi câu loại nguyên một tầng:
- Route có nằm trong bảng không, và có bind đúng cái interface bạn nghĩ không? Một cái liếc vào routing table. Nếu dải đó đang route ra nhầm interface thì dừng — bạn tìm ra rồi đấy, mọi thứ phía trên tầng này không đáng động vào nữa.
- Port có trả lời không? Một cú TCP connect trần, không hơn. Nếu không có gì listen hoặc không với tới được, thì credentials vô nghĩa, và mọi thứ khác bạn định thử cũng vậy.
- Handshake có fail không? Bạn đã chạm tới một thứ gì đó — nó có nói đúng protocol bạn chờ không, hay bạn chạm nhầm thứ khác?
- Authentication có fail không? Lỗi auth là tin mừng. Nó chứng minh route, port và handshake trong một dòng, và thu hẹp vấn đề về đúng tầng credentials với permission — tầng duy nhất mà một cái password sửa được.
Mỗi câu trả lời giết một tầng. Những nước đi đắt — đổi credentials, restart service, mở ticket cho ops — nằm sau những nước rẻ, và thường là không bao giờ tới lượt, vì cú check route đã trả lời xong câu hỏi rồi.
Cái đã thay đổi
Cái thứ tự đó thành một câu lệnh. Nó check cả hai dải, báo dải nào đang hỏng — staging, production, hay cả hai — rồi in ra đúng cái fix: những câu lệnh route cần quyền cao, sẵn sàng để paste, rebind dải bị hỏng về đúng interface.
Nó cố tình in ra thay vì tự chạy. Ghi lại route table cần quyền root, mà một tool chẩn đoán tự leo thang thành operator là một loại tool khác hẳn, nguy hiểm hơn hẳn. Nên ranh giới được vạch rõ: tool xác lập sự thật, còn con người tự tay chạy đúng một dòng lệnh cần quyền, bằng sudo của chính mình. Con người vẫn là bên quyết định; họ chỉ không còn phải nhớ nữa thôi.
Mình không nói được kiểu đoán cũ đã tốn bao nhiêu giờ — chẳng ai log lại một phiên ngồi đoán, và mình sẽ không dựng lại một con số từ nỗi bực còn nhớ được. Điều mình nói được là cái lỗi này cứ quay lại, vì nó là thuộc tính của cách mạng được sắp xếp chứ không phải chuyện một lần, và rằng việc chẩn đoán đã đi từ một cuộc tìm kiếm không hồi kết thành một khoản chi phí nhỏ, cố định, trả một lần rồi đi tiếp.
Cái luật
"Tại network" chỉ là giả thuyết, cho tới khi ba câu lệnh biến nó thành sự thật. "Tại credentials", "database sập rồi", "DNS hỏng" cũng vậy — cái nào cũng thấy chắc như đinh khi ngồi trong một cái connection đang treo, và cái nào cũng check được với giá rẻ hơn giá của việc hành động theo nó. Tách các tầng từ rẻ nhất trở đi, để mỗi câu trả lời loại đi một tầng, và khi cái fix cần quyền cao, hãy đưa cho con người đúng câu lệnh — chứ đừng đưa chìa khoá.