Каждые 60 секунд вы получаете шторм из ~ 5000 сообщений. Вы обрабатываете их последовательно, и это занимает «совсем немного» времени. Очень быстро один из ваших буферов переполняется, и ваша ОС, сетевая карта или маршрутизатор начинают сбрасывать пакеты. (Скорее всего, это буфер, который ваше ядро выделяет для этого конкретного сокета, и ядро отбрасывает пакеты, но возможны и все остальные параметры.)
Вы можете попробовать увеличить эти буферы. Это даст вам гораздо больше «разрешенного времени задержки», так что вы можете отстать еще до того, как ядро начнет отбрасывать пакеты. Если вы хотите пойти по этому пути, первым шагом будет setsockopt
, чтобы поднять значение SO_RCVBUF
, но вам действительно нужно узнать обо всех проблемах, которые могут возникнуть здесь. 1
Если вы управляете клиентским кодом, вы также можете заставить клиентов разбивать свои пакеты (например, просто спать в течение random.random() * 55
перед send
).
Но, вероятно, лучше попытаться на самом деле обслуживать эти пакеты как можно быстрее и выполнять обработку в фоновом режиме. 2
Попытка сделать это в потоке может быть идеальной, но это также может быть очень рискованным, чтобы получить право. Более простое решение - просто фоновый поток или их пул:
def process_msg(d):
# your actual processing code
with concurrent.futures.ThreadPoolExecutor(max_workers=12) as x:
while True:
d = s.recvfrom(1024)
x.submit(process_msg, d)
Это может на самом деле не помочь. Если ваша обработка связана с процессором, а не с вводом / выводом, фоновые потоки будут просто бороться за GIL с основным потоком. Если вы используете Python 2.7 или 3.2 или что-то еще старое, даже потоки, связанные с вводом / выводом, могут вмешиваться в некоторых ситуациях. Но в любом случае, есть простое решение: просто замените это ThreadPoolExecutor
на ProcessPoolExecutor
(и, возможно, уменьшите max_workers
на 1 число ядер, которое у вас есть, чтобы убедиться, что принимающий код может иметь целое ядро для сам по себе).
1. Redhat имеет хороший документ по Настройка производительности сети . Он написан больше с точки зрения системного администратора, чем с точки зрения программиста, и ожидает, что вы либо узнаете, либо узнаете, как искать, много дополнительной информации, но это должно быть полезно, если вы захотите это сделать. Вы также можете попробовать поискать ошибки сервера, а не переполнение стека, если хотите пойти по этому пути.
2. Конечно, если для обработки сообщений каждой минуты требуется больше минуты, очередь будет становиться все длиннее и длиннее, и в конечном итоге все будет катастрофически отказывать, что хуже, чем просто отбрасывать некоторые пакеты, пока вы не догоните ... Но, надеюсь, это здесь не проблема.