나는 거의 모든 활동을 제외하고 즉시 한 번에 2,000의 야구장에서 열린 주소로 많은 연결을 유지하는 Java 응용 프로그램을 가지고 있습니다. 대부분 모니터링 목적으로 열 때마다 몇 바이트를 전달합니다. 새 연결을 열어야 할 때 자동으로 연결을 열어 풀에 추가합니다. 때로는 알 수없는 이유로 응용 프로그램이 원격 주소에 대한 소켓을 만드는 동안/후에 즉시 ClosedByInterruptException을 수신합니다. 가장 잘 알고있는 한, 스레드에 대한 인터럽트 신호의 결과로 클라이언트 측에서만 발생합니다. 문제 영역을 둘러싼 소스 코드를 확인하고 다시 확인해 보니 괜찮습니다. 예를 들어, 소스 코드 외에도 다른 원인이있을 수 있는지에 대해 누군가의 전문 지식을 얻을 수 있기를 바랬습니다. 시스템 원인으로 인해이 문제가 발생 했습니까? 하드웨어 원인이 있습니까? 서버 수준/라우터 수준? 내 네트워크 지식 나는 아마추어를 고려할 것이지만, 라우터에 2K 연결이 너무 많거나 없습니까?소켓을 열면 Java 응용 프로그램이 ClosedByInterruptException을 throw합니다. 원인은 무엇입니까?
INFO [08 Sep 2011 23:11:45,982]: Reconnecting id 20831
ERROR [08 Sep 2011 23:11:45,990]: IOException while creating plain socket channel
java.nio.channels.ClosedByInterruptException
at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:184)
at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:518)
at com.*.createSocketChannelPlain(MyTask.java:441)
at com.*._executeTask(MyTask.java:176)
at com.*.executeTask(MyTask.java:90)
at com.*.ThreadPool$WorkerThread.run(ThreadPool.java:55)
ERROR [08 Sep 2011 23:11:45,990]: Could not open socket
WARN [08 Sep 2011 23:11:45,990]: WorkerThread_24 received interrupted exception in ThreadPool
java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at com.*.TaskQueue.getTask(TaskQueue.java:39)
at com.*.ThreadPool$WorkerThread.run(ThreadPool.java:48)
업데이트 : 내가 시도하고 다른 사람이 진단에 기여하기 위해 내가 할 수있는 모든을 제공하고 싶습니다. 그래서 여기에 예외가 발생하는 실제 함수가 있습니다. 차이점은 라인 441에 추가 한 라인 마킹뿐입니다.
private SocketChannel createSocketChannelPlain() throws TaskFailedException {
SocketChannel socketChannel = null;
try {
// Create a non-blocking socket channel to use to communicate for imap connection
socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
try {socketChannel.socket().setSoLinger(true, 0);} catch (Exception e) {}
try {socketChannel.socket().setKeepAlive(true);} catch (Exception e) {}
/*Line 441*/ socketChannel.connect(new InetSocketAddress(_HOSTNAME, _PORT));
//System.out.println("Started connection");
// Complete connection
while (!socketChannel.finishConnect()) {
// do something until connect completed
try {
//do what you want to do before sleeping
Thread.sleep(500);//sleep for 500 ms
//do what you want to do after sleeping
} catch(InterruptedException ie){
//If this thread was interrupted by another thread
try { socketChannel.close(); } catch (Exception e) {}
finally { socketChannel = null; }
break;
}
}
//System.out.println("Finished connecting");
return socketChannel;
} catch (IOException e) {
logger.error("IOException while creating plain socket channel to gmail", e);
try { socketChannel.close(); } catch (Exception e1) {}
finally { socketChannel = null; }
//throw new TaskFailedException("IOException occurred in createSocketChannel");
}
return socketChannel;
}
리눅스 데비안입니다. 나는 사실 파일 설명자 문제를 겪기 시작했고 예외적 인 설명은 계속해서 "나쁜 호스트 이름"이었다. 그 이후로 제한을 상당히 높이기 위해 시작 스크립트를 설정했습니다. 'tcpdump'는 실제로 아직 시도하지 않은 훌륭한 아이디어입니다. – casey
sysadmin이 나에게 tcpdump하지 못하게했다. 나중에 개인 시스템에서이 것을 시험해 봐야 할 것이다. – casey
아니면 명령을 주면 명령을 내릴 수 있습니까? 'tcpdump -i any -s 0 -w /tmp/casey.pcap port 80'은 거의 맞을 것입니다. 어쩌면 다른 사람의 트래픽을 덤핑하는 것을 피하기 위해 Google의 네트워크와 소스 IP를 제한으로 추가 할 수 있습니다. –