DevOps & giám sát

Lỗi im lặng: cách một kiểm tra metadata chặn mọi tác vụ suy luận

Một bài kiểm tra red-team đã tiết lộ rằng một token hết hạn trong endpoint metadata khiến mọi tác vụ thất bại, trong khi các kiểm tra sức khỏe (health checks) vẫn báo cáo hệ thống hoạt động bình thường.

Các giá đỡ máy chủ dưới mái vòm kính với đèn cảnh báo màu hổ phách chỉ ra một sự cố hệ thống âm thầm.
Ảnh minh họa tạo riêng cho bài viết

Bài được dịch tự động từ bản gốc tiếng Anh.

Một nghiên cứu tình huống kỹ thuật gần đây được công bố vào ngày 3 tháng 11 năm 2026, chi tiết hóa một chế độ lỗi tinh vi nhưng nghiêm trọng trong dịch vụ suy luận AI tự lưu trữ (self-hosted). Tác giả, Manh Liem, phát hiện ra rằng mặc dù giao diện người dùng và các endpoint API có vẻ hoạt động tốt, mọi tác vụ nền đều thất bại âm thầm do cấu hình sai của kiểm tra sức khỏe. Sự cố này nhấn mạnh nguy hiểm của việc phụ thuộc vào các chỉ số gián tiếp để xác định trạng thái sống của hệ thống thay vì kiểm tra đường dẫn thực thi thực tế.

Chuyện gì đã xảy ra

Sự cố bắt đầu khi tác giả chạy một đánh giá red-team trả phí chống lại một endpoint được lưu trữ. Từ bên ngoài, dịch vụ trông như đang hoạt động. Trang mua hàng tải đúng cách, các biểu mẫu gửi đi trả về trạng thái 202 Accepted, và endpoint thăm dò tác vụ phản hồi dữ liệu. Tuy nhiên, từng tác vụ cuối cùng đều trả về trạng thái lỗi với thông báo "model endpoint unreachable" (không thể truy cập endpoint mô hình). Lỗi chỉ ra một địa chỉ cục bộ, gợi ý vấn đề kết nối nằm trong chính hạ tầng.

Khi điều tra, nguyên nhân gốc rễ không phải là sự cố mạng hay máy chủ mô hình bị sập. Quá trình worker chịu trách nhiệm thực thi các tác vụ đã thực hiện một kiểm tra tính sẵn sàng (liveness check) trước khi bắt đầu bất kỳ công việc nào. Kiểm tra này truy vấn route GET /v1/models, một phần của proxy cục bộ chịu trách nhiệm quản lý danh sách các nhà cung cấp được lưu trữ. Việc xây dựng danh sách này yêu cầu một refresh token cho tài khoản của bên thứ ba. Token đó đã hết hạn, khiến endpoint danh sách trả về lỗi 500 Internal Server Error. Logic kiểm tra tính sẵn sàng diễn giải bất kỳ phản hồi nào không phải 200 là bằng chứng cho thấy mô hình không thể truy cập, vì vậy nó hủy bỏ tác vụ ngay lập tức mà không bao giờ thử chạy suy luận thực tế.

Route suy luận thực tế, POST /v1/chat/completions, hoàn toàn hoạt động trong suốt thời gian gián đoạn. Nó được phục vụ bởi một thành phần khác, một router nhà cung cấp, không phụ thuộc vào token đã hết hạn. Tác giả xác nhận điều này bằng cách gửi một yêu cầu tối thiểu với max_tokens đặt thành 1, trả về một kết quả hợp lệ. Hệ thống có một đường dẫn sản xuất hoạt động và một đường dẫn metadata bị hỏng, nhưng cổng bảo vệ (gatekeeper) lại kiểm tra cái sai.

Chi tiết chính

  • Lỗi diễn ra âm thầm vì mỗi phản hồi HTTP riêng lẻ đều đúng về mặt kỹ thuật: trang trả về 200, biểu mẫu gửi trả về 202, và kiểm tra tính sẵn sàng trả về 500.
  • Probe kiểm tra tính sẵn sàng nhắm vào GET /v1/models, một endpoint metadata, thay vì endpoint suy luận thực tế POST /v1/chat/completions.
  • Một refresh token hết hạn cho nhà cung cấp bên thứ ba khiến endpoint metadata thất bại với lỗi 500.
  • Worker coi lỗi metadata là sự cố toàn bộ hệ thống, ngăn cản bất kỳ tác vụ thực tế nào được thực thi.
  • Log không hiển thị mâu thuẫn nào, khiến lỗi khó phát hiện qua các phương pháp phát hiện bất thường tiêu chuẩn.
  • Giải pháp liên quan đến việc thay đổi probe để kiểm tra route suy luận thực tế với payload tối thiểu.

Bối cảnh

Trong các hệ thống phân tán, kiểm tra sức khỏe được sử dụng để xác định xem một dịch vụ đã sẵn sàng chấp nhận lưu lượng truy cập hay chưa. Một liveness probe thường kiểm tra xem quá trình có đang chạy hay không, trong khi readiness probe kiểm tra xem nó có thể xử lý yêu cầu hay không. Lý tưởng nhất, các probe này nên mô phỏng công việc thực tế mà dịch vụ thực hiện. Nếu một probe kiểm tra một phụ thuộc không quan trọng đối với chức năng cốt lõi, hoặc nếu nó kiểm tra một tác dụng phụ như tạo metadata, nó có thể tạo ra các cảnh báo sai (false negatives). Điều này tạo ra tình huống hệ thống có khả năng làm việc nhưng từ chối khởi động vì một thành phần ngoại vi không khỏe mạnh.

Trường hợp này cũng minh họa sự khác biệt giữa sức khỏe thành phần và sức khỏe chuỗi quy trình. Kiến trúc microservice có thể có nhiều thành phần độc lập, chẳng hạn như web server, queue, worker và model router. Mỗi thành phần có thể báo cáo "healthy" riêng lẻ, nhưng luồng end-to-end có thể bị hỏng. Ví dụ, web server có thể chấp nhận yêu cầu, và mô hình có thể tạo văn bản, nhưng nếu worker không thể kết nối chúng do lỗi cấu hình, trải nghiệm người dùng sẽ là sự cố toàn bộ. Giám sát các thành phần riêng lẻ là không đủ; các nhóm cần xác minh rằng toàn bộ chuỗi quy trình được thực thi thành công.

Tại sao điều này quan trọng

Đối với các nhóm vận hành phần mềm riêng, sự cố này là lời cảnh báo chống lại việc phụ thuộc quá mức vào các mẫu kiểm tra sức khỏe tiêu chuẩn. Nhiều framework cung cấp các endpoint liveness mặc định kiểm tra kết nối cơ sở dữ liệu hoặc trạng thái quá trình cơ bản. Nếu ứng dụng của bạn có các phụ thuộc phức tạp, chẳng hạn như token API bên ngoài hoặc danh sách cấu hình động, các mặc định này có thể không phản ánh đúng trạng thái thực của hệ thống. Một lỗi âm thầm như thế này có thể kéo dài nhiều ngày, làm cạn kiệt tài nguyên và gây khó chịu cho người dùng, mà không kích hoạt bất kỳ cảnh báo nào vì hệ thống giám sát thấy chính xác những gì nó mong đợi: các lỗi nhất quán khớp với logic đã cấu hình.

Hơn nữa, điều này nhấn mạnh chi phí của việc kiểm tra gián tiếp. Kiểm tra một endpoint metadata rẻ và nhanh hơn so với chạy một tác vụ thực tế, đó là lý do tại sao các nhà phát triển thường chọn nó. Tuy nhiên, như đã thấy ở đây, các đường dẫn metadata có thể lệch khỏi các đường dẫn sản xuất. Chúng có thể có các yêu cầu xác thực, giới hạn tốc độ hoặc đường dẫn mã khác nhau. Khi chúng thất bại, chúng không nhất thiết chỉ ra rằng sản phẩm cốt lõi bị hỏng. Phụ thuộc vào chúng tạo ra một thiết lập giám sát mong manh, cảnh báo về các vấn đề không liên quan trong khi bỏ sót các vấn đề nghiêm trọng. Các nhóm phải cân bằng chi phí của các giao dịch tổng hợp với rủi ro của các sự cố không được phát hiện.

Bạn có thể làm gì

  • Kiểm toán các kiểm tra sức khỏe của bạn để đảm bảo chúng kiểm tra đường dẫn quan trọng của ứng dụng, không chỉ các phụ thuộc ngoại vi.
  • Triển khai giám sát tổng hợp (synthetic monitoring) chạy một giao dịch end-to-end tối thiểu, chẳng hạn như yêu cầu suy luận một token, ở các khoảng thời gian đều đặn.
  • Tách biệt các kiểm tra liveness (quá trình có đang chạy?) khỏi các kiểm tra readiness (có thể làm việc không?) và đảm bảo các kiểm tra readiness mô phỏng hành động thực của người dùng.
  • Giám sát các chỉ số cấp độ kinh doanh, chẳng hạn như tỷ lệ hoàn thành tác vụ hoặc báo cáo trống, thay vì chỉ dựa vào mã trạng thái HTTP.
  • Thiết lập cảnh báo cho các mẫu lỗi cụ thể trong log, ngay cả khi trạng thái tổng thể của hệ thống có vẻ xanh.
  • Thường xuyên xoay vòng và kiểm tra các token và thông tin đăng nhập của bên thứ ba trong môi trường staging để ngăn ngừa các bất ngờ do hết hạn trong production.

Tin khác

DevOps & giám sát

Chọn chính sách bù lịch phù hợp cho các tác vụ cron bị bỏ lỡ

Khi máy chủ khởi động lại trong lúc đang chạy các tác vụ theo lịch, việc bỏ qua âm thầm hoặc tạo ra backlog khổng lồ có thể dẫn đến mất dữ liệu hoặc bị cấm API. Tìm hiểu cách cấu hình systemd, Kubernetes và các script tùy chỉnh để xử lý các lần chạy bị bỏ lỡ m

Tất cả tin