2011-06-12 2 views
9

나는 앞에 100 개 요청을하는 웹 사이트에서 nginx를 사용하여 Jetty를 실행하고 있습니다. 난 그냥 로그에 발견하는 배포를하고 작은 것이 스팸 동안 것을, 부두를 시작한 후 단 몇 분 :Jetty IOException : 열려있는 파일이 너무 많습니다.

java.io.IOException: Too many open files 
    at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method) 
    at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:163) 
    at org.mortbay.jetty.nio.SelectChannelConnector$1.acceptChannel(SelectChannelConnector.java:75) 
    at org.mortbay.io.nio.SelectorManager$SelectSet.doSelect(SelectorManager.java:673) 
    at org.mortbay.io.nio.SelectorManager.doSelect(SelectorManager.java:192) 
    at org.mortbay.jetty.nio.SelectChannelConnector.accept(SelectChannelConnector.java:124) 
    at org.mortbay.jetty.AbstractConnector$Acceptor.run(AbstractConnector.java:708) 
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582) 

2 분하십시오. 는 나는 "lsof를 -u 부두"를했고, 수백 줄의 보았다 : 192.168.1.100는 서버 내부 IP입니다

java 15892 jetty 1020u IPv6   298105434  0t0  TCP 192.168.1.100:http-alt->192.168.1.100:60839 (ESTABLISHED) 
java 15892 jetty 1021u IPv6   298105438  0t0  TCP 192.168.1.100:http-alt->192.168.1.100:60841 (ESTABLISHED) 
java 15892 jetty 1022u IPv6   298105441  0t0  TCP 192.168.1.100:http-alt->192.168.1.100:60842 (ESTABLISHED) 
java 15892 jetty 1023u IPv6   298105443  0t0  TCP 192.168.1.100:http-alt->192.168.1.100:60843 (ESTABLISHED) 

합니다.

위에서 볼 수 있듯이 이것은 열린 파일의 수를 기본 최대 1024 개로 늘 렸습니다. 단지 이것을 늘릴 수는 있었지만 처음에는 왜 이런 일이 발생하는지 궁금합니다. 그것은 Jetty의 nio 소켓 수락 자 (acceptor)에 있습니다. 이것은 연결 요청의 폭풍으로 인한 것입니까?

+1

모든 소켓은 파일이므로 모든 연결에 대기중인 파일 (설명자)이 있습니다. 일반적으로 요청은 무엇이며 얼마나 걸리나요? 부두에 100 요청/초, 로컬 db 서버에 2 초/query를 요청하면서 이미 400 개의 "파일"이 있습니다. – extraneon

+0

대부분의 요청은 응용 프로그램이 처음 시작될 때 몇 초가 걸릴 수 있지만 몇 분이 걸립니다. 이것이 내가 생각한 것입니다. 가비지 수집기는 때때로 "세계 멈춤"일시 정지를 수행하여 모든 요청이 잠시 동안 쌓이게하여 간헐적으로이를 일으 킵니다. 나중에 GC를 조정해야 할 것입니다. 평균 한도를 증가 시켰습니다. –

+1

나는 때때로 Tomcat6에서 비슷한 것을 얻고있다. 처음에는 그것이 장난감을 던지는 운영체제라고 생각했다. 또한 임시 솔루션으로 한도가 증가했습니다. –

답변

11

부두에 버그가있을 수 있지만 훨씬 더 많은 가능성있는 설명은 열린 파일 ulimits가 너무 낮다는 것입니다. 일반적으로 1024 기본값은 보통 사용하는 웹 서버에는 충분하지 않습니다.

이것을 테스트하는 좋은 방법은 아파치 벤치를 사용하여보고있는 인바운드 트래픽을 시뮬레이트하는 것입니다. 원격 호스트에서이를 실행하면 10 개 이상의 동시 연결마다 1000 개의 요청이 생성됩니다. 이제

ab -c 10 -n 1000 [http://]hostname[:port]/path 

에서 netstat 사용하여 웹 서버의 소켓을 계산 ...

netstat -a | grep -c 192.168.1.100 

바라건대 당신이 확인할 수있는 것들 당신의 소켓이 극적으로 (1024보다 큰 광산이없는 일부 값 고원 것입니다 16384).

또 다른 좋은 점은 연결이 비즈니스 논리에서 제대로 닫히고 있다는 것입니다.

netstat -a | grep -c CLOSE_WAIT 

이 숫자가 응용 프로그램의 수명주기 동안 계속 증가하면 Connection.close()에 대한 몇 가지 호출이 누락 될 수 있습니다.

+0

또한 Full GC가 실제로 너무 많은 시간을 소비하고 있다는 것이 명백 해지면 java의 ConcurrentMarkSweep 수집기를 살펴보십시오. – jpredham

관련 문제