#java #linux #multithreading #sockets #nio
#java #linux #многопоточность #сокеты #nio
Вопрос:
У меня проблема, мой поток завершен без каких-либо исключений!!!
У меня есть поток для приема сокета (nio, но в режиме блокировки).это работает хорошо, если сокет получает запросы на получение с низкой скоростью, но при получении большого количества запросов одновременно поток останавливается.
Я изменил несколько параметров в Linux, может быть, для этого?
часть моего кода:
while(!Thread.interrupted() amp;amp; !serverSocketChannel.socket().isClosed()){
try
{
SocketChannel socketChannel = serverSocketChannel.accept();
while (!socketChannel.finishConnect() amp;amp; check < 50) {
try {
Thread.sleep(20);
}
catch (InterruptedException ignored) {}
check = 1;
}
check = 0;
if(!socketChannel.finishConnect()){
socketChannel.close();
continue;
}
NioSocket socket = new NioSocket(server, socketChannel);
if(acceptedSocketQueue.offer(socket))
server.addSocket(socket);
else
socket.forceClose();
}
catch(Throwable e){
Logger.log(SocketAccepter.class, e,"SocketAccepter, on accepting.");
}
}
Logger.log(SocketAccepter.class,"SocketAccepter ### interrupted.");
// I do not get here
изменены параметры:
echo fs.file-max=500000 >> /etc/sysctl.conf
echo fs.nr_open=500000 >> /etc/sysctl.conf
echo fs.aio-max-nr=300000 >> /etc/sysctl.conf
echo fs.aio-nr=50000 >> /etc/sysctl.conf
echo net.ipv4.tcp_mem="2048 51200 725376" >> /etc/sysctl.conf
echo net.core.rmem_default=51200 >> /etc/sysctl.conf
echo net.core.rmem_max=725376 >> /etc/sysctl.conf
echo net.ipv4.tcp_rmem="2048 51200 725376" >> /etc/sysctl.conf
echo net.core.wmem_default=51200 >> /etc/sysctl.conf
echo net.core.wmem_max=725376 >> /etc/sysctl.conf
echo net.ipv4.tcp_wmem="2048 51200 725376" >> /etc/sysctl.conf
echo net.ipv4.tcp_syn_retries=4 >> /etc/sysctl.conf
echo net.ipv4.tcp_synack_retries=2 >> /etc/sysctl.conf
echo net.ipv4.ip_local_port_range=1024 65500 >> /etc/sysctl.conf
echo net.ipv4.tcp_fin_timeout=20 >> /etc/sysctl.conf
echo net.ipv4.tcp_keepalive_time=240 >> /etc/sysctl.conf
echo net.ipv4.tcp_keepalive_probes=3 >> /etc/sysctl.conf
echo net.ipv4.tcp_keepalive_intvl=30 >> /etc/sysctl.conf
echo net.core.somaxconn=5000 >> /etc/sysctl.conf
echo net.core.netdev_max_backlog=5000 >> /etc/sysctl.conf
echo net.ipv4.tcp_max_syn_backlog=5000 >> /etc/sysctl.conf
echo net.core.rps_sock_flow_entries=32000 >> /etc/sysctl.conf
echo net.core.optmem_max=51100 >> /etc/sysctl.conf
echo net.ipv4.tcp_rfc1337=1 >> /etc/sysctl.conf
echo net.ipv4.tcp_max_orphans=2000 >> /etc/sysctl.conf
echo net.ipv4.tcp_syncookies=0 >> /etc/sysctl.conf
echo net.ipv4.tcp_adv_win_scale=2 >> /etc/sysctl.conf
пожалуйста, помогите мне, если вы знаете.
Обновить:
Я добавил Thread.UncaughtExceptionHandler
в поток. затем я запустил приложение с помощью этой команды
java - jar app.jar amp;>> log.txt
и когда поток останавливается, я открыл файл журнала.
в файле журнала я увидел строку ниже
Exception: java.lang.NullPointerException thrown from the UncaughtExceptionHandler in thread "NioServer Accepter"
мой новый код был таким
SocketChannel socketChannel = serverSocketChannel.accept();
NioSocket socket = new NioSocket(server, socketChannel);
acceptedSocketQueue.offer(socket);
Я понял, serverSocketChannel.accept()
что является причиной этого, у кого-нибудь есть причина?
Комментарии:
1.
catch (InterruptedException ignored) {}
действительно?2. это для inside while{} и не имеет значения, это для Thread.sleep()
3. Вы полностью злоупотребляете
finishConnect()
здесь. (1) Вам вообще не нужно вызывать его послеaccept()
, только послеconnect()
, (2) вам не нужно вызывать его в режиме блокировки, в котором все еще находится принятый канал сокета. Удалите все это. Ваш код не имеет смысла.4. Что ж, я сдался. Я видел документы. Вы правы, я удалю их. Но почему я не получил никаких исключений?
5. Беззаботный мальчик. Я скопировал код с сайта в своей программе без осторожности. Код был для неблокирующего режима. Я немного изменил это. большое спасибо за это.
Ответ №1:
Я решил свою проблему.
После дня проб и ошибок проблема была, наконец, решена путем отключения нескольких опций в Linux.
Я не знаю точно, что делают эти параметры, которые вызвали выброс этого исключения! Кто-нибудь знает?
Но варианты:
fs.file-max=500000
fs.nr_open=500000
fs.aio-max-nr=300000
fs.aio-nr=50000
Я удалил их, и программа заработала должным образом.
Комментарии:
1. Ничто из этого не имеет ничего общего с
NullPointerException
. Единственное, что в вашем коде могло бы это сделать, — этоaccept()
возвращать null , что означает, что вы должны иметьServerSocketChannel
в неблокирующем режиме, что означает, что вы должны использоватьSelector
, чтобы сообщить вам, когда вызыватьaccept()
, вместо зацикливания.2. Я тоже был удивлен. Но, изменив параметры, моя проблема была решена. Это исключение возникло внутри метода accept(). Это был не тот случай, когда результат метода был нулевым.