7

Это может показаться связанным с программированием, но это вопрос ОС.

Я пишу небольшой высокопроизводительный демон, который принимает тысячи соединений в секунду. Он отлично работает на Linux (в частности, Ubuntu 9.10 на EC2). В Mac OS X, если я добавлю несколько тысяч соединений (примерно 16350) в тест, который просто открывает соединение, делает свое дело и закрывает соединение, то программа тестов зависает на несколько секунд, ожидая, пока сокет станет доступным перед продолжением (или тайм-аут в процессе).

Я использовал как Apache Bench, так и Siege (чтобы убедиться, что это не тестовое приложение).

Так почему / как Mac OS X ограничивает RATE, при котором можно использовать сокеты, и могу ли я помешать ему это сделать?

Или что-то еще происходит?

Я знаю, что есть предел файлового дескриптора, но я не достигаю этого. Нет ошибки при приеме сокета, он просто на некоторое время зависает после первых (примерно) 16000, ожидая - я полагаю - ОС освободит сокет. Этого не должно происходить, так как все до этого сокеты закрыты в этой точке. Предполагается, что они будут доступны по цене, которую они закрывают, и делают это в Ubuntu, но, похоже, что-то вроде мульти (5-10?) вторая задержка в Mac OS X.

Я пытался настроить с ulimit в любом направлении. Нада.

1 ответ1

16

Mac OS X начинает открывать эфемерные порты на 49152. Номера портов представляют собой 16-разрядные целые числа без знака, поэтому существует 65535 возможных портов. 65535 - 49152 = 16383. Я думаю, что у вас есть 16 тысяч портов в TIME_WAIT.

Обновление: вы можете посмотреть на следующие переменные sysctl(8):

net.inet.ip.portrange.lowfirst: 1023  
net.inet.ip.portrange.lowlast: 600  
net.inet.ip.portrange.first: 49152  
net.inet.ip.portrange.last: 65535  
net.inet.ip.portrange.hifirst: 49152  
net.inet.ip.portrange.hilast: 65535  

Я думаю, что если вы установите значение hifirst на что-то меньшее, вы увеличите количество временных портов, доступных в вашей системе.

Возможно, существует опция сокета или что-то, что говорит стеку о том, что он в основном нарушает спецификацию TCP и использует нестандартное значение для TIME_WAIT, но мне не хватает программиста сокетов Mac OS X, чтобы это знать.

Обновление 2: вы, вероятно, хотите использовать setsockopt(2) для установки SO_REUSEADDR.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .