Слишком много открытых файлов исключение под" неограниченной " системой


Я вижу слишком много исключений из открытых файлов при выполнении моей программы. Обычно они имеют следующий вид:

org.jboss.netty.channel.ChannelException: Failed to create a selector.

...
Caused by: java.io.IOException: Too many open files
Однако это не единственные исключения. Я наблюдал подобные случаи (вызванные "слишком большим количеством открытых файлов"), но они намного реже.

Как ни странно, я установил лимит открытых файлов сеанса экрана (с которого я запускаю свои программы) как 1M:

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

Более того, как следует из вывода lsof -p Я больше не вижу, что 1111 открывают файлы (сокеты, каналы, файлы) до того, как будут выброшены исключения.

Вопрос: что не так и/или как я могу углубиться в эту проблему.

Дополнительно: в настоящее время я интегрирую Floodlight С BFT-smart. В двух словах процесс floodlight-это сбой с слишком большим количеством исключений открытых файлов при выполнении стресс-теста, запущенного тестовой программой. Эта тестовая программа будет поддерживать 64 tcp соединения с процесс floodlight, который, в свою очередь, должен поддерживать по крайней мере 64 * 3 tcp-соединения с репликами BFT-smart. Обе программы используютnetty для управления этими соединениями.

1 2

1 ответ:

Первое, что нужно проверить-можете ли вы запустить ulimit изнутри вашего процесса Java, чтобы убедиться, что ограничение файла внутри такое же? Такой код должен работать:

InputStream is = Runtime.getRuntime().exec(new String[] {"bash", "-c", "ulimit -a"}).getInputStream();
int c;
while ((c = is.read()) != -1) {
    System.out.write(c);
}

Если лимит все еще показывает 1 миллион, Что ж, вы готовы к жесткой отладке.

Вот пара вещей, которые я бы рассмотрел, если бы мне пришлось отлаживать это -

  1. У вас заканчиваются номера портов tcp? Что показывает netstat -an, Когда вы нажмете эту ошибку?

  2. Используйте strace, чтобы выясните, какой именно системный вызов с какими параметрами вызывает эту ошибку. EMFILE - возвращаемое значение 24.

  3. Ошибка "слишком много открытых файлов" EMFILE на самом деле может быть вызвана рядом различных системных вызовов по ряду различных причин:

    $ cd /usr/share/man/man2
    $ zgrep -A 2 EMFILE *
    accept.2.gz:.B EMFILE
    accept.2.gz:The per-process limit of open file descriptors has been reached.
    accept.2.gz:.TP
    accept.2.gz:--
    accept.2.gz:.\" EAGAIN, EBADF, ECONNABORTED, EINTR, EINVAL, EMFILE,
    accept.2.gz:.\" ENFILE, ENOBUFS, ENOMEM, ENOTSOCK, EOPNOTSUPP, EPROTO, EWOULDBLOCK.
    accept.2.gz:.\" In addition, SUSv2 documents EFAULT and ENOSR.
    dup.2.gz:.B EMFILE
    dup.2.gz:The process already has the maximum number of file
    dup.2.gz:descriptors open and tried to open a new one.
    epoll_create.2.gz:.B EMFILE
    epoll_create.2.gz:The per-user limit on the number of epoll instances imposed by
    epoll_create.2.gz:.I /proc/sys/fs/epoll/max_user_instances
    eventfd.2.gz:.B EMFILE
    eventfd.2.gz:The per-process limit on open file descriptors has been reached.
    eventfd.2.gz:.TP
    execve.2.gz:.B EMFILE
    execve.2.gz:The process has the maximum number of files open.
    execve.2.gz:.TP
    execve.2.gz:--
    execve.2.gz:.\" document ETXTBSY, EPERM, EFAULT, ELOOP, EIO, ENFILE, EMFILE, EINVAL,
    execve.2.gz:.\" EISDIR or ELIBBAD error conditions.
    execve.2.gz:.SH NOTES
    fcntl.2.gz:.B EMFILE
    fcntl.2.gz:For
    fcntl.2.gz:.BR F_DUPFD ,
    getrlimit.2.gz:.BR EMFILE .
    getrlimit.2.gz:(Historically, this limit was named
    getrlimit.2.gz:.B RLIMIT_OFILE
    inotify_init.2.gz:.B EMFILE
    inotify_init.2.gz:The user limit on the total number of inotify instances has been reached.
    inotify_init.2.gz:.TP
    mmap.2.gz:.\" SUSv2 documents additional error codes EMFILE and EOVERFLOW.
    mmap.2.gz:.SH AVAILABILITY
    mmap.2.gz:On POSIX systems on which
    mount.2.gz:.B EMFILE
    mount.2.gz:(In case no block device is required:)
    mount.2.gz:Table of dummy devices is full.
    open.2.gz:.B EMFILE
    open.2.gz:The process already has the maximum number of files open.
    open.2.gz:.TP
    pipe.2.gz:.B EMFILE
    pipe.2.gz:Too many file descriptors are in use by the process.
    pipe.2.gz:.TP
    shmop.2.gz:.\" SVr4 documents an additional error condition EMFILE.
    shmop.2.gz:
    shmop.2.gz:In SVID 3 (or perhaps earlier)
    signalfd.2.gz:.B EMFILE
    signalfd.2.gz:The per-process limit of open file descriptors has been reached.
    signalfd.2.gz:.TP
    socket.2.gz:.B EMFILE
    socket.2.gz:Process file table overflow.
    socket.2.gz:.TP
    socketpair.2.gz:.B EMFILE
    socketpair.2.gz:Too many descriptors are in use by this process.
    socketpair.2.gz:.TP
    spu_create.2.gz:.B EMFILE
    spu_create.2.gz:The process has reached its maximum open files limit.
    spu_create.2.gz:.TP
    timerfd_create.2.gz:.B EMFILE
    timerfd_create.2.gz:The per-process limit of open file descriptors has been reached.
    timerfd_create.2.gz:.TP
    truncate.2.gz:.\" error conditions EMFILE, EMULTIHP, ENFILE, ENOLINK.  SVr4 documents for
    truncate.2.gz:.\" .BR ftruncate ()
    truncate.2.gz:.\" an additional EAGAIN error condition.
    
    Если вы проверите все эти страницы вручную, вы можете найти что-то интересное. Например, я думаю, что интересно, что epoll_create, базовый системный вызов, который используется NIO каналы, вернет EMFILE "Слишком много открытых файлов", Если

    Ограничение на число экземпляров epoll для каждого пользователя, устанавливаемое обнаружен файл /proc/sys/fs/epoll/max_user_instances. Видеть epoll (7) для более подробной информации.

    Теперь это имя файла фактически не существует в моей системе, но есть некоторые ограничения, определенные в файлах в /proc/sys/fs/epoll и /proc/sys/fs/inotify, которые вы можете использовать, особенно если вы запускаете несколько экземпляров одного и того же теста на та же машина. Выяснение, если это так, само по себе является рутиной-вы можете начать с проверки системного журнала на наличие любых сообщений ...

Удачи!