2010-03-09 3 views
4

У меня довольно неприятная проблема в моем серверном приложении.Apache Mina Server Restart java.net.BindException: адрес уже используется

Я связываю Apache Mina со следующим кодом:

acceptor.bind(new InetSocketAddress(PORT)); 

Где акцептором является NioSocketAcceptor. Через интерфейс HTTP я могу завершить работу сервера, чтобы перезапустить его.

Server.ioAcceptor.unbind(new InetSocketAddress(Server.PORT)); 
     for(IoSession session: Server.ioAcceptor.getManagedSessions().values()){ 
      if(session.isConnected() && !session.isClosing()){ 
       session.close(false); 
      } 
     } 
     Server.ioAcceptor.dispose(); 

     Main.transport.stop(); 
     Logger.getRootLogger().warn("System going down. Request from "+context.getRemoteAddress()); 
     System.exit(10);  

Это код, который я использую для остановки сервера Mina. Однако, если я попытаюсь запустить сервер снова в ближайшие пару минут. (Где-то между 5 и 15 минутами) При запуске я получаю следующее исключение: java.net.BindException: Адрес уже используется

Я также попробовал простой ioAcceptor.unbind(), но не было никакой разницы. Сервер работает на Centos 5 с OpenJDK. Версия Apache Mina 2.0 RC1.

Заранее благодарю вас за любые идеи о том, как решить эту проблему.

ответ

0

Не то, что я знаком с МИНА, но как

NETSTAT -apn | grep ПОРТ
ps -ef | grep java

похоже?

О, хорошо. Вы попали в команду с правами пользователя root?

+0

Оба они не показывают ничего. «lsof -i» также не показывает соединений на этом порту – Kosaki

+0

@ Kosaki: PS. Извините, я должен был сделать это комментарий, а не ответ .. –

0

Вы должны быть осторожны с закрытием, иначе TCP ведет себя таким образом. См this

+0

Спасибо. Я сейчас пытаюсь это сделать, но я должен ждать, чтобы увидеть результаты. Любые идеи о том, как я буду тестировать это, не помещая его на производственный сервер? Обычно у меня открыто около 2000 сокетов, и их трудно реплицировать в тестовой среде. – Kosaki

+0

Просто откройте и закройте один разъем и посмотрите, работает ли он? – LenW

6

Я не уверен, первопричины, но я читал где-то исправить это, что, кажется, работает для меня:

acceptor.setReuseAddress(true); 

Просто добавив, что позвольте мне выключения и перезагрузки

3

пару вещей, которые я бы добавил:

  1. Установите акцептор повторно привязанный адрес
    acceptor.setReuseAddress(true)
  2. В вашем закрытом блоке вместо
    session.close(false)
    используйте
    session.close(true)
    Это немедленно закроет сеанс, а не ждет флеш.

Ссылки:

закрытия сессии - http://mina.apache.org/report/trunk/apidocs/org/apache/mina/core/session/IoSession.html#close(boolean)

ServerSocket повторное использование адреса - http://download.oracle.com/javase/1.5.0/docs/api/java/net/ServerSocket.html?is-external=true#setReuseAddress(boolean)

0

Добавьте следующий код:

acceptor.setReuseAddress(true) 

Thi s позволяет использовать порт.

0

Сначала проверьте конфигурацию ОС на "Sysctl net.ipv4.tcp_fin_timeout", а затем изменить его до 30 секунд, во-вторых "Sysctl -a | Grep net.ipv4.tcp_tw" измените значение, как этот net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1