У меня есть приложение сокета, написанное с 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, но я не знаю, каков риск этого исключения, приведет ли эта ошибка к отказу моего приложения при транзакции или нет?
Если да, может кто-нибудь объяснить это? и как его решить?
Это может быть довольно сложной задачей. Эта ошибка (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
.
Я уверен, что вы не можете вызвать метод dispose
соединителя.
Этот метод отключает бизнес-потоки, вызывая метод выключения ExecuteService.
Между тем установите внутренний флаг, расположенный для обозначения соединителя, который необходимо остановить, worker thread
останавливается этим флагом.