Java Apache Mina, каков риск ошибки слишком большого количества открытых файлов? И как это исправить?

1

У меня есть приложение сокета, написанное с Apache MINA, с ОС Linux,

На этот раз я получил слишком много ошибок, когда вижу файлы журнала с этим кодом:

IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
acceptor.setCloseOnDeactivation(true);
acceptor.setHandler(new ChatHandler());
acceptor.getSessionConfig().setReadBufferSize(2);
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
acceptor.bind(new InetSocketAddress(15000));

Когда я тестировал его с 2-3 клиентом одновременно, я получил эту ошибку:

Caused by: java.io.IOException: Too many open files
at sun.nio.ch.IOUtil.makePipe(Native Method) ~[?:?]
at sun.nio.ch.EPollSelectorImpl.<init>(EPollSelectorImpl.java:65) ~[?:?]
at sun.nio.ch.EPollSelectorProvider.openSelector(EPollSelectorProvider.java:36) ~[?:?]
at java.nio.channels.Selector.open(Selector.java:227) ~[?:?]
at org.apache.mina.transport.socket.nio.NioProcessor.<init>(NioProcessor.java:59) ~[MC.jar:?]

У меня есть googled, но я не знаю, каков риск этого исключения, приведет ли эта ошибка к отказу моего приложения при транзакции или нет?

Если да, может кто-нибудь объяснить это? и как его решить?

Теги:
apache-mina

2 ответа

3
Лучший ответ

Это может быть довольно сложной задачей. Эта ошибка (ENFILE) означает, что либо у вас, либо у ОС имеется слишком много открытых файловых дескрипторов.

stdin, stdout и stderr - файловые дескрипторы; любой открытый файл является файловым дескриптором; любой сокет, который вы создаете, также является файловым дескриптором.

Чтобы узнать свой лимит открытых файлов, как пользователь, выполните следующие действия:

ulimit -n

Чтобы узнать предел ОС, выполните следующие действия:

cat /proc/sys/fs/file-max

Как правило, это проблема пользователя.

Вы можете попытаться повысить лимит, используя:

ulimit -n <a greater number here>

но, скорее всего, это не сработает. Что вам нужно сделать, это отредактировать /etc/security/limits.conf, /etc/security/limits.conf, создать новый файл в /etc/security/limits.d с соответствующим именем и добавить эти две строки:

theuser soft nofile <somelargenumber>
theuser hard nofile <somelargenumber>

Обратите внимание, что для того, чтобы эти лимиты вступили в силу, пользователь должен выйти из системы и снова войти в систему; если это пользователь, посвященный системной службе, то перезапуск этой службы будет выполнен.

Кроме того, если вы знаете PID процесса, запускающего ваше приложение, вы можете увидеть количество открытых в данный момент дескрипторов файлов, выполнив команду:

ls /proc/<thepid>/fd|wc -l

Если ограничение ядра является проблемой (очень маловероятно, но кто знает), вам придется отредактировать /etc/sysctl.conf и изменить proc.sys.fs.file-max, а затем запустить sysctl - с root.

  • 0
    позвольте мне сначала попробовать, ваш ответ действительно потрясающий.
0

Я уверен, что вы не можете вызвать метод dispose соединителя.

Этот метод отключает бизнес-потоки, вызывая метод выключения ExecuteService.

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню