2011-04-12 8 views
20

Windows 용 WebLogic 11g에서 Java 응용 프로그램을 실행하고 며칠 후 응답하지 않습니다. 한 가지 의심스러운 증상은 서버가 유휴 상태 일 때도 CLOSE_WAIT 상태의 많은 연결 (약 3000)이 netstat에 표시된다는 것입니다. 응용 프로그램 서버가 클라이언트 연결을 관리하고 있으므로이 문제를 일으키는 원인이 확실하지 않습니다. 또한 동일한 서버에 루프백하는 여러 웹 서비스 호출을 만들지 만 이러한 연결이 제대로 닫히지는 않습니다. 또 다른 원인은 무엇이며 어떻게 이런 문제를 해결할 수 있습니까?CLOSE_WAIT 상태에서 연결이 끊어졌습니다.

+0

항상 서버 쪽에서 연결을 닫으시겠습니까? – weekens

+0

응용 프로그램이 응답하지 않더라도 CLOSE_WAIT로 표시됩니까? –

+0

@ weekens- 저는 서버 측의 연결을 닫지 않습니다. WebLogic은 않습니다. @ Robin- 예, 비슷하게 구성된 서버에서 서버가 넘어지기 전에 연결이 누적되는 것을 봅니다. –

답변

1

문제는 버그는 웹 로직에서 참으로 "사용 JSSE SSL을"설정에 의해 촉발되었다. JSSE 대신 WebLogic 자체의 SSL 구현을 사용하는 것은 애플리케이션에서 문제가되지 않으므로 설정을 취소하고 문제가 사라지는 것일뿐입니다.

0

CLOSE_WAIT 파일 정리에 대해 다음과 같은 인용문을 발견했습니다. "무엇인가가 HTTP 세션에서 의 진행을 방해하거나 (닫히지 않아 중단됩니다) 또는 소켓이 닫히지 않도록하는 버그가 도입되었습니다. 이것이 일어날 수있는 여러 가지 방법이 있습니다. "

생각 : 요청을 처리하는 동안 응용 프로그램이 멈추는 방법이 있습니까? 아니면 WebLogic 자체?

검사 : 실제로 Java 스레드 덤프 (kill-SIGQUIT는 Linux 용 Oracle JVM에서 사용할 수 있음)를 사용하여 실제로 스레드가 걸려 있는지 확인할 수 있습니까?

클라이언트 측 검사 : 먼저 CLOSE_WAIT 소켓에 연결된 클라이언트의 IP 주소 또는 호스트 이름을 찾습니다. 그런 다음 해당 고객에 대해 의심스러운 사항이 있는지 확인하십시오.

4

CLOSE_WAIT 상태는 다른 쪽이 연결 닫기를 시작했지만 로컬 쪽의 응용 프로그램이 아직 소켓을 닫지 않았 음을 의미합니다.

로컬 응용 프로그램에 버그가있는 것 같습니다.

14

CLOSE_WAIT은 원격 호스트가 FIN (연결을 닫음)을 보내지 만 로컬 응용 프로그램이 동일한 작업을 수행하지 않고 응답 FIN을 보낸 상태의 로컬 TCP 상태 시스템입니다. 클라이언트가 데이터를 수신 할 수는 없지만 로컬 시스템에서 데이터를 보낼 수는 있습니다 (연결에서 반 닫음을 제외하고는).

원격 호스트가 닫히면 (FIN을 보냄) 로컬 응용 프로그램에서 일종의 이벤트 (기본 C 라이브러리의 소켓에서 "읽기"이벤트)가 발생하지만 해당 연결을 읽으면 오류가 반환됩니다 연결이 닫혔 음을 나타냅니다. 이 시점에서 로컬 응용 프로그램은 연결을 닫아야합니다.

저는 Java에 대해서는 거의 알지 못하지만 WebLogic에 대해서는 아무것도 모릅니다. 응용 프로그램이 읽기 오류를 올바르게 처리하지 못해서 연결을 닫지 않을 가능성이 있습니다.

17

나는 동일한 문제를 겪고 있으며이 문제를 해결하기 위해 소켓을 연구하고 있습니다.

몇 마디 말하지만, 나는 자바 프로그래머가 아닙니다.

Brian White는 이미 말해야 할 모든 것을 말한 것처럼 close_wait이 무엇인지 설명하지 않겠습니다.

close_wait를 피하려면 먼저 연결을 끊은 사람이 close_wait 및 time_wait에서 멈추기 때문에 응답을 보낸 후에 서버가 연결을 닫지 않아야합니다. 따라서 서버가 close_wait에서 멈추는 경우 응답을 보낸 후 연결이 끊어졌습니다.

몇 가지 작업을 수행하면 안됩니다.

1 - 클라이언트 응용 프로그램이 http 1.1 프로토콜을 사용하지 않는 경우 'keep-alive http 헤더 옵션으로 인해이를 사용하도록 설정해야합니다.

2 - 당신은 클라이언트가 HTTP 1.1을 실행하고 HTTP 1.0을 사용해야하는 경우 즉, 일을하거나하지 않는 경우, 당신은 연결 요청 헤더 속성을 설정해야합니다

connection: keep-alive 

이 그 어느 쪽도 서버를 알려줍니다 클라이언트와 서버는 요청을 완료 한 후 연결을 끊어야합니다. 그렇게하면 서버는 요청을받을 때마다 연결을 끊지 않습니다.

3 - 클라이언트에서 소켓을 다시 사용하십시오. 예를 들어 루프에 많은 소켓 클라이언트를 만드는 경우 소켓을 한 번 만들어야하며 요청을 보낼 때마다 소켓을 사용해야합니다. 내 응용 프로그램에서 사용한 접근 방식은 소켓 풀을 사용하고 소켓 (이미 서버에 연결되어 있고 연결 유지 속성이 있음)을 가져 오는 것입니다. 그렇다면 그것을 사용하고 내가 끝나면 다시 수영장에 넣어서 재사용 할 수 있습니다.

4 - 요청을 보내고 나서 실제로 연결을 끊어야하는 경우 고객을 확인하고 connection: keep-alive을 유지하십시오.

예, 서버 측에서 close_waits 또는 time_waits를 많이 사용하면 문제가 발생할 수 있습니다.

무엇이 keep-alive인지 설명하는 [link] [1]을 (를) 확인해보십시오.

도움이 되었기를 바랍니다. 그 일로 나는 내 문제를 해결할 수 있었다. [1]

: http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01.html#Persistent 연결

+3

나는 당신이 대답에서 close_wait와 time_wait을 심각하게 혼동한다고 생각합니다. – wick

+0

이것은 TCP FSM 사양에 따라 올바르지 않습니다. CLOSE_WAIT는 서버가 응답을 보낸 후 연결이 끊어 질 때 발생하지 않습니다. 클라이언트 (다른 ​​쪽)가 TCP 연결의 종료를 시작하고 close() sys 호출이 서버 측의 응용 프로그램에 의해 발행되지 않는 경우입니다 (이 스레드의 Brian White에 설명되어 있음) –

0

이렇게하면 accept() 호출에서 소켓에서 "close"를 호출하지 않을 수도 있습니다.

관련 문제