Một shell tương tác qua đường hầm đóng băng vài giây trong lúc bản sao tệp đang chạy, rồi tiếp tục như thể không có gì xảy ra. Chỉ bản tải xuống gặp vấn đề, vậy mà shell cũng phải chờ, và cả hai hồi phục cùng một lúc. Mẫu hình đó là dấu hiệu của một luồng tin cậy duy nhất chở nhiều cuộc trò chuyện, và nó sống sót qua gần như mọi thay đổi tinh chỉnh mà người ta thử trước tiên.

Triệu chứng đáng được đọc kỹ vì nó chỉ vào một cơ chế chứ không phải một thiết lập: khoảng dừng là chung, nên nguyên nhân là chung, và đối tượng chung là kết nối bên ngoài. Mọi thứ khác trong nhật ký trông bình thường trong lúc đó.

Triệu chứng: mọi thứ dừng cùng lúc

Hai kết nối bên trong cùng kẹt là manh mối. Một bản tải xuống chậm và một shell chậm là những cuộc trò chuyện TCP riêng biệt với số thứ tự riêng và trạng thái tắc nghẽn riêng, nên lỗi ở cái này không nên chạm tới cái kia. Khi chúng dừng cùng nhịp, có thứ gì đó bên trên đang sắp xếp các byte của chúng.

Thứ đó là tầng vận chuyển của đường hầm. Ở chế độ TCP, OpenVPN ghi các gói đã đóng gói vào một kết nối TCP duy nhất tới đầu kia, và hợp đồng của TCP là giao một luồng byte duy nhất theo thứ tự. Các byte về sau không được giao cho ứng dụng trước các byte còn thiếu, bất kể chúng thuộc cuộc trò chuyện bên trong nào.

Hãy để ý điều mà triệu chứng không nói. Nó không nói rằng đường đi bị hỏng, máy chủ quá tải hay mã hóa chậm. Những thứ đó tạo ra hình dạng khác: thông lượng thấp đều đặn, hết thời gian chờ, hoặc lỗi chỉ ảnh hưởng một chiều. Một khoảng dừng chung kết thúc khi một phân đoạn bị mất được gửi lại chính là hiệu ứng sắp xếp.

Một luồng byte bên ngoài, nhiều cuộc trò chuyện bên trong

Hãy hình dung đường hầm chở đồng thời một bản tải xuống và một shell. Một phân đoạn của kết nối bên ngoài bị mất. Các phân đoạn tiếp theo có thể tới máy nhận, và ngăn xếp TCP phía nhận sẽ xác nhận chúng, nhưng nó không thể giao chúng lên trên cho tới khi khoảng trống được lấp. Vì vậy OpenVPN không có gì để đọc cho shell, dù các byte của chính shell đã tới từ lâu.

Đây là tắc nghẽn ở đầu hàng đợi trong một kết nối, và nó không đòi hỏi hai ứng dụng phải chia sẻ một kết nối bên trong. Chúng chia sẻ kết nối bên ngoài, và thế là đủ.

Hiệu ứng bậc hai làm nó tệ hơn. Một bên gửi bên trong không thấy xác nhận có thể gửi lại dữ liệu mà tầng ngoài đang cố giao. Việc gửi lại đó trở thành lưu lượng đường hầm thêm trên một đường vừa chứng minh rằng nó có thể làm mất phân đoạn, nên công việc phục hồi tranh chấp với việc phục hồi quan trọng.

Không điều nào trong số này bảo đảm một sự sụp đổ. Trên một đường sạch với thời gian khứ hồi ngắn và hàng đợi rộng rãi, cách bố trí này có thể dùng tốt trong nhiều năm. Sự cố xuất hiện khi mất mát, độ trễ và độ sâu hàng đợi cùng hội tụ, và đó là lý do các báo cáo tập trung quanh đường lên tắc nghẽn và liên kết di động chứ không phải quanh văn phòng được trang bị tốt.

Vì sao bộ hẹn giờ bên trong dài hơn không thể giúp

Nâng thời gian chờ gửi lại tối thiểu trên một tuyến bằng rto_min sẽ hoãn việc gửi lại dựa trên bộ hẹn giờ cho lưu lượng TCP sinh ra tại chỗ dùng tuyến đó. Đó là một nút thật với tác động thật, và nó xử lý vấn đề bậc hai chứ không phải bậc một.

ip route show
ip route show cache 2>/dev/null | head
ss -tin dst 10.70.0.1

Điều nó không thể là giải phóng byte bên ngoài ra khỏi thứ tự, phục hồi phân đoạn còn thiếu nhanh hơn, hoặc khiến máy chủ ứng dụng phía xa dùng cùng bộ hẹn giờ. Ngăn xếp phía nhận vẫn giao theo thứ tự, và bên gửi ở đầu xa vẫn dùng phép đo khứ hồi của chính nó.

Nó cũng không tắt mọi cơ chế phục hồi mất mát khác. Ở nơi mất mát thật sự cần phục hồi dựa trên bộ hẹn giờ, một mức tối thiểu lớn hơn khiến ứng dụng chờ lâu hơn trước khi hành động, đúng ngược lại điều một phiên nhạy cảm độ trễ cần.

Một mức sàn cố định mười hai giây xuất hiện trong lời khuyên về chủ đề này như thể sự tồn tại của một đường hầm TCP hàm ý nó. Bộ hẹn giờ gửi lại được mô tả trong RFC 6298 được suy ra từ thời gian khứ hồi đo được với việc lùi theo hàm mũ, nên một mức sàn cố định là lựa chọn chính sách cho một tuyến cụ thể chứ không phải yêu cầu của giao thức. Khi áp dụng rộng rãi, nó che giấu triệu chứng đồng thời thay đổi việc phục hồi cho mọi luồng mà tuyến đó bao phủ.

tcp-nodelay làm gì và không làm gì

Tùy chọn đường hầm tắt đệm kiểu Nagle trên socket vận chuyển có mục đích hẹp: nó ngăn các lần ghi nhỏ chờ thêm dữ liệu trước khi truyền. Điều đó giúp lưu lượng tương tác tránh một độ trễ thêm trên một đường vốn khỏe mạnh.

Nó không biến vận chuyển thành không thứ tự, và không rút ngắn việc phục hồi sau một phân đoạn bị mất. Một shell dừng vì hết thời gian gửi lại sẽ vẫn dừng khi bật tùy chọn đó, vì tùy chọn chưa bao giờ chạm tới quy tắc thứ tự.

Nhầm hai thứ này rất dễ vì cả hai đều được mô tả là cách sửa độ trễ. Một cái loại bỏ sự chờ đợi nhân tạo do đệm tạo ra, cái kia sẽ phải thay đổi điều mà vận chuyển bảo đảm, và không tùy chọn socket nào làm được điều đó.

Cách so sánh các tầng vận chuyển một cách công bằng

Nếu người vận hành cho phép và cả hai dịch vụ đều tồn tại, hãy so sánh một dịch vụ UDP và một dịch vụ TCP chở cùng khối lượng công việc trên cùng đường truy cập tới cùng máy chủ. Đổi quốc gia, nhà cung cấp hoặc thế hệ máy chủ giữa hai lần thử sẽ đưa vào một biến số sẽ chi phối kết quả.

Hãy tìm khoảng dừng chung thay vì một con số thông lượng. Nhiều ứng dụng bên trong cùng kẹt trong lúc mất mát bên ngoài là quan sát nhận diện tắc nghẽn ở đầu hàng đợi; một con số đo tốc độ thấp hơn thì không.

Các bản bắt gói được phép trên giao diện đường hầm và trên giao diện vật lý tách hai tầng một cách rõ ràng, vì việc gửi lại bên trong và bên ngoài thuộc về các kết nối khác nhau với không gian thứ tự khác nhau. Thấy việc gửi lại bên trong trong khi luồng bên ngoài cho thấy một khoảng trống chính là bằng chứng trực tiếp.

Chuyển sang UDP loại bỏ luồng tin cậy thêm và để TCP bên trong tự phục hồi. Nó không hứa hẹn không mất mát hay độ trễ thấp, và một đường lên bão hòa, hàng đợi quá lớn hay vấn đề MTU vẫn sẽ cần sửa. Lưu lượng ngoài đường hầm không bao giờ bị giữ lại sau khoảng trống thứ tự của đường hầm, tuy nó vẫn có thể chịu ảnh hưởng khi cả hai đường chia sẻ một liên kết tắc nghẽn, và nút cổ chai chung đó đáng được điều tra riêng thay vì gộp vào đây.

Bài viết liên quan