Khi kích thước tối đa mà một chặng giữa đường nhận được bị giảm đi nhưng thông báo “quá lớn” (ICMP) lại bị chặn, gói lớn gửi lại bao nhiêu lần cũng tiếp tục biến mất.
Vì sao Kích thước tối đa giảm ở chặng VPN hoặc tunnel, còn thông báo vượt kích thước bị tường lửa chặn → Dẫn đến Bên gửi không biết lý do nên cứ truyền lại cùng một gói lớn, RTO tăng gấp đôi sau mỗi lần → Trên màn hình Bình thường không sao, nhưng vào lúc có dữ liệu lớn đi qua (mở túi đồ, đến chỗ đông người, loading khi vào khu vực mới) thì cả các gói nhỏ phía sau cũng bị kẹt theo và game đứng hình, cuối cùng mất kết nối hoặc kẹt loading
Khi làm một thao tác nhất định, Ngay sau đăng nhập hoặc bảo trì
Phụ trách
Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Hạ tầng server (Đội hạ tầng), Phát triển server (Đội phát triển game)
Việc cần làm (Đội phát triển game)
Muốn tự hạ từ phía server thì đặt kích thước segment tối đa của socket (TCP_MAXSEG); chỉ chia nhỏ message trong code game thì không chặn được (TCP gom dữ liệu cần gửi lại theo kích thước MSS).
Việc cần làm (Đội hạ tầng)
Mạng: điều chỉnh MSS (clamping) ở thiết bị biên, cho phép ICMP báo vượt kích thước (type 3 code 4, fragmentation needed) trên tường lửa và network ACL của cloud. Thiết bị server·OS: cấu hình path MTU, kiểm tra tường lửa trên server và security group của cloud cũng không chặn ICMP báo vượt kích thước, dùng tcp_mtu_probing=1 của Linux làm lưới an toàn cuối cùng.
Con số tham khảo
Thường là 1.500 byte, đi qua tunnel thì còn khoảng 1.400. Cùng một gói bị truyền lại 5–6 lần thì thời gian đứng hình vượt quá 10 giây.
Trên đồ thị
Chỉ một phần cao · RTO và backoff theo từng kết nối, số lần mất kết nối theo khu vực hoặc nhà mạng
Chỗ cần xem
Các lần truyền lại của kết nối có vấn đề, qua bản bắt gói phía server hoặc bcc tcpretrans -s (hiển thị số thứ tự); xem mss, pmtu, backoff của kết nối đó bằng ss -ti. Từ server gửi tới địa chỉ người chơi đó một ping nhỏ và một ping 1.500 byte có bật DF (ping -M do -s 1472) rồi so sánh
Đúng nếu
gói đầy đúng kích thước MSS liên tục bị truyền lại với cùng số thứ tự, khoảng cách tăng gấp đôi mỗi lần, còn gói nhỏ hơn vẫn đi lại bình thường. Không có ICMP báo vượt kích thước (filter Wireshark icmp.type == 3 and icmp.code == 4), ping nhỏ có phản hồi nhưng ping lớn có DF thì mất hẳn, không phản hồi
Loại trừ nếu
gói nhỏ cũng biến mất theo → mất gói không liên quan kích thước (“Tràn hàng đợi ở điểm nghẽn”, “Đổi tuyến đường hoặc tuyến ECMP lỗi”). ICMP báo vượt kích thước có đến và pmtu trong ss -ti giảm xuống → cơ chế dò path MTU đang hoạt động đúng
Cách kiểm tra
Kiểm tra bằng công cụ hạ tầng (không cần code game)
Tìm hiểu thêm
tcp_mtu_probing=1 chỉ xác định là black hole và hạ MSS xuống 1.024 byte sau khi timeout truyền lại kéo dài vài giây (tương ứng tcp_retries1=3). Trong khoảng đó game đứng hình, nên chỉ coi đây là lưới an toàn cuối cùng; việc cần làm trước là điều chỉnh MSS để chặn từ đầu.
Nguồn
RFC 1191: Path MTU discoveryIETF Dò path MTU: gói quá lớn được báo bằng ICMP “fragmentation needed and DF set” (type 3 code 4)
IP SysctlLinux kernel tcp_mtu_probing: 0 là tắt, 1 là chỉ khi phát hiện black hole, 2 là luôn luôn (MSS khởi đầu là tcp_base_mss). tcp_retries1 mặc định 3
net/ipv4/tcp_timer.cLinux kernel Khi truyền lại do RTO kéo dài đủ tcp_retries1 lần thì coi là đã phát hiện black hole, bật dò MTU để hạ MSS
tcp(7) — Linux manual pageLinux man-pages TCP_MAXSEG: kích thước segment tối đa của gói đi ra; đặt trước khi kết nối thì MSS báo cho phía bên kia cũng đổi theo
MTU considerations | Cloud VPNGoogle Cloud MTU của Cloud VPN gateway là 1.460 byte, MTU payload của tunnel IPv4 là 1.406 byte (đi qua tunnel thì còn khoảng 1.400)
ss(8) — Linux manual pageiproute2 mss, pmtu (path MTU), backoff (số lần RTO đã tăng gấp đôi) trong ss -i
ping(8) — Linux manual pageiputils -M do bật DF và không gửi gói lớn hơn path MTU mà kernel biết; -s là kích thước dữ liệu (chưa tính 8 byte ICMP header)