Максимальное количество сокетов в Linux - PullRequest
6 голосов
/ 07 августа 2010

Кажется, что сервер ограничен в ~ 32720 сокетов ... Я пробовал каждое известное изменение переменной, чтобы поднять этот предел. Но сервер остается ограниченным на 32720 открытых сокетов, даже если все еще есть 4Go свободной памяти и 80% простаивающего процессора ...

Вот конфигурация

~# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 63931
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 798621
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 2048
cpu time               (seconds, -t) unlimited
max user processes              (-u) 63931
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

net.netfilter.nf_conntrack_max = 999999
net.ipv4.netfilter.ip_conntrack_max = 999999
net.nf_conntrack_max = 999999

Есть мысли?

Ответы [ 8 ]

5 голосов
/ 10 августа 2010

Если вы имеете дело с openssl и потоками, проверьте ваш / proc / sys / vm / max_map_count и попробуйте поднять его.

2 голосов
/ 08 мая 2014

В IPV4 уровень TCP имеет 16 бит для порта назначения и 16 бит для порта источника.

см. http://en.wikipedia.org/wiki/Transmission_Control_Protocol

Учитывая, что ваш лимит составляет 32 КБ, я ожидаю, что вы на самом деле видите лимит исходящих TCP-соединений, которые вы можете установить. Вы должны быть в состоянии получить максимум 65K сокетов (это будет предел протокола). Это ограничение на общее количество именованных соединений. К счастью, для привязки порта для входящих подключений используется только 1. Но если вы пытаетесь проверить количество подключений с одного компьютера, вы можете иметь только 65K исходящих подключений (для TCP). Чтобы проверить количество входящих подключений, вам потребуется несколько компьютеров.

Примечание: вы можете вызывать сокет (AF_INET, ...) с количеством доступных файловых дескрипторов, но Вы не можете связать их без увеличения количества доступных портов. Чтобы увеличить диапазон, сделайте это:

echo "1024 65535"> / proc / sys / net / ipv4 / ip_local_port_range (посмотрите, что у вас есть - по умолчанию от 32768 до 61000)

Возможно, пришло время для нового протокола, подобного TCP, который позволит использовать 32 бита для портов источника и приемника? Но скольким приложениям действительно нужно более 65 тысяч исходящих соединений?

Следующее разрешит 100 000 входящих подключений на Linux Mint 16 (64 бит) (вы должны запустить его как root, чтобы установить ограничения)

#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>

void ShowLimit()
{
   rlimit lim;
   int err=getrlimit(RLIMIT_NOFILE,&lim);
   printf("%1d limit: %1ld,%1ld\n",err,lim.rlim_cur,lim.rlim_max);
}

main()
{
   ShowLimit();

   rlimit lim;
   lim.rlim_cur=100000;
   lim.rlim_max=100000;
   int err=setrlimit(RLIMIT_NOFILE,&lim);
   printf("set returned %1d\n",err);

   ShowLimit();

   int sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
   sockaddr_in maddr;
   maddr.sin_family=AF_INET;
   maddr.sin_port=htons(80);
   maddr.sin_addr.s_addr=INADDR_ANY;

   err=bind(sock,(sockaddr *) &maddr, sizeof(maddr));

   err=listen(sock,1024);

   int sockets=0;
   while(true)
   {
      sockaddr_in raddr;
      socklen_t rlen=sizeof(raddr);
      err=accept(sock,(sockaddr *) &raddr,&rlen);
      if(err>=0)
      {
        ++sockets;
        printf("%1d sockets accepted\n",sockets);
      }
   }
}
2 голосов
/ 07 августа 2010

О каком сервере вы говорите? Возможно, он имеет максимум в жестком коде или работает в других пределах (максимум потоков / нехватка адресного пространства и т. Д.)

http://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-1 имеет некоторые настройки, необходимые для достижения большого количества соединений, но это не помогает, если серверное приложение так или иначе ограничивает его.

1 голос
/ 09 апреля 2017

Проверьте реальные пределы запущенного процесса с помощью.

cat /proc/{pid}/limits

Максимальное значение для nofiles определяется ядром, следующее как root может увеличить максимальное значение до 100 000 «файлов», т.е. 100k CC

echo 100000 > /proc/sys/fs/file-max

Чтобы сделать его постоянным, отредактируйте /etc/sysctl.conf

fs.file-max = 100000

Затем вам нужно, чтобы сервер запросил больше открытых файлов, это отличается для каждого сервера. Например, в nginx вы устанавливаете

worker_rlimit_nofile 100000;

Перезагрузите nginx и проверьте / proc / {pid} / limit

Чтобы проверить это, вам нужно 100 000 сокетов в вашем клиенте, при тестировании вы ограничены количеством портов в TCP на IP-адрес.

Чтобы увеличить диапазон локальных портов до максимума ...

echo "1024 65535" > /proc/sys/net/ipv4/ip_local_port_range

Это дает вам ~ 64000 портов для тестирования.

Если этого недостаточно, вам нужно больше IP-адресов. При тестировании на localhost вы можете привязать источник / клиент к IP-адресу, отличному от 127.0.0.1 / localhost.

Например, вы можете привязать ваших тестовых клиентов к IP-адресам, случайно выбранным от 127.0.0.1 до 127.0.0.5

Используя apache-bench вы бы установили

-B 127.0.0.x

Для сокетов Nodejs будет использоваться

localAddress

/ etc / security / limit.conf настраивает PAM: это обычно не имеет значения для сервера.

Если сервер перенаправляет запросы с использованием TCP, например, с использованием upstream или mod_proxy, сервер ограничен ip_local_port_range. Это легко может быть предел 32 000.

1 голос
/ 07 августа 2010

Если вы рассматриваете приложение, в котором, по вашему мнению, вам нужно открыть тысячи сокетов, вам наверняка захочется прочитать о Проблема C10k . На этой странице обсуждаются многие проблемы, с которыми вы столкнетесь при увеличении количества клиентских подключений к одному серверу.

0 голосов
/ 03 августа 2012

Как правило, слишком много живых соединений - это плохо. Однако все зависит от приложения и шаблонов, которые оно связывает со своими клиентами.

Я предполагаю, что существует шаблон, когда клиенты должны быть постоянно асинхронно подключены, и это единственный способ, которым может работать распределенное решение.

Предполагается, что в текущей / загруженной памяти нет никаких узких мест в памяти / процессоре / сети, и следует учитывать, что выход из неактивного открытого соединения - единственный способ, с помощью которого распределенные приложения потребляют меньше ресурсов (скажем, время соединения и общая / пиковая память). ), общая производительность сети ОС может быть выше, чем при использовании лучших практик, которые мы все знаем.

Хороший вопрос и его нужно решить. Проблема в том, что никто не может ответить на это. Я бы предложил использовать технику «разделяй и властвуй», и когда узкое место будет найдено, возвращайтесь к нам

Пожалуйста, разберите вашу заявку на испытательном стенде, и вы найдете узкое место.

0 голосов
/ 07 августа 2010

В net / socket.c fd размещается в sock_alloc_fd (), которая вызывает get_unused_fd ().

Глядя на linux / fs / file.c, единственное ограничение на количество fd это sysctl_nr_open, который ограничен

int sysctl_nr_open_max = 1024 * 1024; /* raised later */

/// later...
sysctl_nr_open_max = min((size_t)INT_MAX, ~(size_t)0/sizeof(void *)) &
                         -BITS_PER_LONG;

и может быть прочитан с использованием sysctl fs.nr_open, что дает 1M по умолчанию здесь.Таким образом, fd, вероятно, не ваша проблема.

edit Вы, вероятно, также проверили это, но не хотите ли поделиться с нами выводом

#include <sys/time.h>
#include <sys/resource.h>
int main() {
    struct rlimit limit;
    getrlimit(RLIMIT_NOFILE,&limit);
    printf("cur: %d, max: %d\n",limit.rlim_cur,limit.rlim_max);
}

0 голосов
/ 07 августа 2010

В Gnu + Linux максимум - то, что вы написали. Это число (вероятно) указано где-то в сетевых стандартах. Я сомневаюсь, что тебе действительно нужно так много розеток. Вам следует оптимизировать использование сокетов, а не создавать десятки постоянно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...