Giải mã lỗi ‘bóng ma’ trong thư viện HTTP hyper: Bài học từ Cloudflare
Cloudflare đã mất 6 tuần để truy vết một lỗi race condition hiếm gặp trong thư viện hyper. Bài viết chia sẻ hành trình kỹ thuật đầy thách thức khi xử lý dữ liệu hình ảnh bị cắt ngắn dù server báo...
Dịch vụ Images của Cloudflare, được xây dựng bằng ngôn ngữ Rust trên nền tảng Workers, là một thành phần quan trọng trong mạng lưới edge của hãng. Để quản lý các kết nối HTTP, Cloudflare sử dụng hyper, một thư viện mã nguồn mở phổ biến trong hệ sinh thái Rust. Gần đây, đội ngũ kỹ thuật đã đối mặt với một bài toán hóc búa: các yêu cầu xử lý hình ảnh lớn đôi khi bị trả về dữ liệu không đầy đủ, dù server vẫn ghi nhận trạng thái 200 OK mà không có bất kỳ thông báo lỗi nào.
Table Of Content
Vấn đề từ những kết nối tưởng chừng hoàn hảo
Sau khi tái cấu trúc lại cách các Workers giao tiếp với dịch vụ Images vào cuối năm 2025, Cloudflare bắt đầu nhận được báo cáo về việc hình ảnh bị cắt ngắn (truncated). Một file ảnh lẽ ra nặng 2MB chỉ nhận được vài trăm KB. Sau 6 tuần điều tra, đội ngũ phát hiện đây là một lỗi race condition nằm sâu trong thư viện hyper, liên quan đến cách thức xử lý bộ đệm (buffer) khi dữ liệu được truyền qua socket.
Về cơ bản, hyper quản lý việc đọc yêu cầu và ghi phản hồi vào socket. Khi dịch vụ Images hoàn tất quá trình tối ưu hóa, nó đẩy toàn bộ dữ liệu vào bộ đệm nội bộ của hyper. Nếu phía nhận (client) xử lý dữ liệu chậm hơn tốc độ ghi của hyper, bộ đệm outbound sẽ bị đầy. Trong trường hợp này, hyper cần phải chờ đợi để tiếp tục ghi dữ liệu. Tuy nhiên, một lỗi logic trong vòng lặp điều phối của hyper đã khiến nó hiểu lầm rằng quá trình truyền tải đã hoàn tất và thực hiện lệnh shutdown kết nối sớm hơn dự kiến.
Hành trình truy vết lỗi
Việc tái hiện lỗi này cực kỳ khó khăn vì nó phụ thuộc vào thời điểm (timing-sensitive). Các kỹ sư đã thử nghiệm nhiều phương án:
- Kiểm tra phiên bản: Thử nghiệm trên nhiều phiên bản hyper từ 0.14.x đến 1.8.x nhưng lỗi vẫn tồn tại.
- Phân tích hệ thống: Sử dụng
straceđể ghi lại các syscall. Kết quả cho thấy hyper đã thực hiện lệnhshutdownngay sau khi ghi được một phần nhỏ dữ liệu vào socket, trong khi phần còn lại vẫn nằm trong bộ đệm nội bộ. - Phát hiện nguyên nhân: Lỗi nằm ở cách xử lý kết quả của hàm
poll_flush. Trong mã nguồn, kết quảPoll::Pending(tín hiệu cho biết việc flush dữ liệu chưa hoàn tất) đã bị bỏ qua bởi lệnhlet _. Điều này khiến vòng lặp tiếp tục tiến trình đóng kết nối dù dữ liệu vẫn còn tồn đọng trong buffer.
Kết luận
Dù việc tái cấu trúc hệ thống không trực tiếp gây ra lỗi, nhưng nó đã thay đổi tốc độ đọc dữ liệu ở phía intermediary, vô tình làm lộ ra một khiếm khuyết đã tồn tại trong hyper suốt nhiều năm. Chỉ với 4 dòng code sửa đổi để xử lý đúng trạng thái Poll::Pending, đội ngũ kỹ thuật đã giải quyết triệt để vấn đề, đảm bảo tính toàn vẹn cho dữ liệu hình ảnh truyền tải qua mạng lưới của Cloudflare.
Nguồn tham khảo: Cloudflare Blog



No Comment! Be the first one.