Gần đây, chúng tôi đã có một máy chủ apache phản hồi rất chậm do lũ lụt. Cách giải quyết cho vấn đề này là kích hoạt tcp_syncookies ( net.ipv4.tcp_syncookies=1 in /etc/sysctl.conf
).
Tôi đã đăng một câu hỏi về điều này ở đây nếu bạn muốn có thêm nền tảng.
Sau khi kích hoạt đồng bộ hóa, chúng tôi bắt đầu thấy thông báo sau trong / var / log / message sau mỗi 60 giây:
[84440.731929] possible SYN flooding on port 80. Sending cookies.
Vinko Vrsalovic thông báo với tôi rằng điều này có nghĩa là backlog đồng bộ đã đầy, vì vậy tôi đã nâng tcp_max_syn_backlog lên 4096. Tại một số điểm, tôi cũng hạ tcp_synack_retries xuống 3 (giảm từ mức mặc định là 5) bằng cách phát hành sysctl -w net.ipv4.tcp_synack_retries=3
. Sau khi làm điều này, tần số dường như giảm xuống, với khoảng thời gian của các tin nhắn thay đổi trong khoảng 60 đến 180 giây.
Tiếp theo tôi đã ban hành sysctl -w net.ipv4.tcp_max_syn_backlog=65536
, nhưng tôi vẫn nhận được thông báo trong nhật ký.
Trong tất cả điều này, tôi đã xem số lượng kết nối ở trạng thái SYN_RECV (bằng cách chạy watch --interval=5 'netstat -tuna |grep "SYN_RECV"|wc -l'
) và nó không bao giờ cao hơn khoảng 240, thấp hơn nhiều so với kích thước của hồ sơ tồn đọng. Tuy nhiên, tôi có một máy chủ Red Hat dao động trong khoảng 512 (giới hạn trên máy chủ này là mặc định là 1024).
Có bất kỳ cài đặt tcp nào khác sẽ giới hạn kích thước của hồ sơ tồn đọng hoặc tôi đang sủa sai cây? Số lượng kết nối SYN_RECV có netstat -tuna
tương quan với kích thước của hồ sơ tồn đọng không?
Cập nhật
Theo cách tốt nhất tôi có thể nói rằng tôi đang xử lý các kết nối hợp pháp ở đây, netstat -tuna|wc -l
dao động khoảng 5000. Tôi đã nghiên cứu bài này ngày hôm nay và tìm thấy bài đăng này từ một nhân viên của Last.fm, khá hữu ích.
Tôi cũng đã phát hiện ra rằng tcp_max_syn_backlog không có tác dụng khi bật tính năng đồng bộ hóa (theo liên kết này )
Vì vậy, như một bước tiếp theo, tôi đặt như sau trong sysctl.conf:
net.ipv4.tcp_syn_retries = 3
# default=5
net.ipv4.tcp_synack_retries = 3
# default=5
net.ipv4.tcp_max_syn_backlog = 65536
# default=1024
net.core.wmem_max = 8388608
# default=124928
net.core.rmem_max = 8388608
# default=131071
net.core.somaxconn = 512
# default = 128
net.core.optmem_max = 81920
# default = 20480
Sau đó, tôi thiết lập kiểm tra thời gian phản hồi của mình, chạy sysctl -p
và vô hiệu hóa đồng bộ hóa bằng cách sysctl -w net.ipv4.tcp_syncookies=0
.
Sau khi thực hiện điều này, số lượng kết nối ở trạng thái SYN_RECV vẫn còn khoảng 220-250, nhưng các kết nối đã bắt đầu trì hoãn trở lại. Khi tôi nhận thấy những sự chậm trễ này, tôi kích hoạt lại đồng bộ hóa và sự chậm trễ đã dừng lại.
Tôi tin rằng những gì tôi đã thấy vẫn là một sự cải thiện từ trạng thái ban đầu, tuy nhiên một số yêu cầu vẫn bị trì hoãn, điều này còn tệ hơn nhiều so với việc kích hoạt tính năng đồng bộ hóa. Vì vậy, có vẻ như tôi bị mắc kẹt với chúng được kích hoạt cho đến khi chúng tôi có thể có thêm một số máy chủ trực tuyến để đối phó với tải. Ngay cả sau đó, tôi không chắc chắn tôi thấy một lý do hợp lệ để vô hiệu hóa chúng một lần nữa vì chúng chỉ được gửi (dường như) khi bộ đệm của máy chủ đã đầy.
Nhưng tồn đọng đồng bộ hóa dường như không đầy đủ chỉ với ~ 250 kết nối ở trạng thái SYN_RECV! Có thể thông báo tràn ngập SYN là cá trích đỏ và đó là thứ gì đó không phải là syn_backlog đang lấp đầy?
Nếu bất cứ ai có bất kỳ tùy chọn điều chỉnh nào khác mà tôi chưa thử, tôi sẽ rất vui khi dùng thử, nhưng tôi bắt đầu tự hỏi liệu cài đặt syn_backlog không được áp dụng đúng cách vì một số lý do.