На Linux, как я могу сказать, сколько временных портов остается доступным?

17

Есть ли способ в Linux, чтобы проверить, сколько эфемерных портов осталось доступным? Иногда я вижу ошибки «Адрес уже используется» из-за нехватки временных портов. Перезагрузка машины решит эту проблему, но было бы лучше перехватить ее до того, как это произойдет.

JMC
источник
Если вы сталкиваетесь с подобными ошибками, я бы предположил, что либо вы злоупотребляете системой, не используя правильное программное обеспечение или архитектуру для работы, либо ваше программное обеспечение работает неправильно или неправильно настроено. Возможно, ваши тайм-ауты слишком велики для вашего приложения или что-то оставляет соединения открытыми без их использования?
Калеб
1
Есть много допустимых приложений, которым требуются дополнительные временные порты помимо значений по умолчанию ОС.
ГрегБ

Ответы:

26

Диапазон эфермального порта указан в /proc/sys/net/ipv4/ip_local_port_range. Вы, вероятно, можете расширить его для запуска с 16К до 64К.

Вы можете увидеть количество открытых соединений, используя netstat -an. Сокеты могут застрять в состоянии TIME_WAIT, если вы открываете и закрываете множество соединений. В некоторых местах это неизбежно, но вам, возможно, придется подумать, нужен ли вам пул соединений, если это так.

Если проблема связана с TIME_WAIT, вы можете установить net.ipv4.tcp_tw_reuse/, net.ipv4.tcp_tw_recycleчтобы ускорить оборот соединения.

Шон
источник
+1, спасибо, что нашли время, чтобы дать этому парню точные детали.
Калеб
У нас есть диапазон от 32800 до 61000. Мы просто обнаруживаем, что после их использования ОС не будет использовать их снова. Это ожидаемое поведение, но я ожидаю, что операционная система снова запустится в начале, как только достигнет последнего доступного порта. Кажется, этого не происходит. Кроме того, просто чтобы заметить, это не совсем обычное явление. Это периодически, но у нас есть большое количество серверов.
JMc
Обратите внимание, что net.ipv4.tcp_tw_recycleбыл удален в Linux 4.12
Anon
1
Для соответствия RFC 6335 /proc/sys/net/ipv4/ip_local_port_range должно быть подмножество 49152-65535. Таким образом, уменьшение нижнего предела диапазона до значения меньше 49152 сопряжено с определенным риском.
Касперд
никогда не используйте ни пользователя net.ipv4.tcp_tw_recycle, ни net.ipv4.tcp_tw_reuse, за исключением случаев, когда вы в отчаянии и точно знаете, что делаете. Вы подвергаете свой сервис потенциальной проблеме крайностей.
Киви
3

Имейте в виду, что этот лимит применяется для каждого уникального набора (IP-адрес источника, IP-адрес узла, порт одноранговой сети). Поэтому вам необходимо сгруппировать выходные данные netstat/ ssпо каждому из этих кортежей и проверить, насколько близка каждая группа к пределу соединения.

Этот пост объясняет, как вы можете сделать эту группировку более подробно. Чтобы проверить, насколько близка каждая группа к пределу в Ruby, вы можете обработать ssвывод следующим образом:

#!/usr/bin/ruby

first_port, last_port = IO.read('/proc/sys/net/ipv4/ip_local_port_range').split.map(&:to_i)
ephemeral_port_max = last_port - first_port + 1
ephemeral_port_warning = ephemeral_port_max / 3 * 2

conns = `ss --numeric --tcp state connected "( sport >= :#{first_port} and sport <= :#{last_port} )"`

groups = Hash.new(0)
conns.lines.each do |conn|
  state, recvq, sendq, local, peer = conn.split
  local_ip, local_port = local.split(':')
  group = [local_ip, peer]
  groups[group] += 1
end

groups_requiring_warning =
  groups.select { |k, v| v > ephemeral_port_warning }
  .to_a
  .sort_by { |v1, v2| v1[1] <=> v2[1] } # Sort groups in descending order of number of connections

groups_requiring_warning.each do |group, used_port_count|
  puts "Connections from #{group[0]} to #{group[1]} "\
    "have used #{used_port_count} ephemeral ports out of #{ephemeral_port_max} max"\
    "(#{((used_port_count.to_f / ephemeral_port_max) * 100).round(2)}% used)"
end
Уилл Сьюэлл
источник