HP-UX
1753802 회원
8539 온라인
108805 솔루션
새 메시지

iplanet log관련문의

 
최이석
임시 조언자

iplanet log관련문의

iPlanet-WebServer-Enterprise,hpux11i,sdk1.3.1.02환경입니다.



위의 메시지를 뿌리면서 ns-httpd가 restart합니다.



Core발생시키면서요.



Error accepting connection -5974, oserr=233 (Insufficient resources)

failure ( 5820): Child process admin thread is shutting down



ndd파라미터나 커널값에는 문제가 없는거 같은데.

혹시 아시는분 계신가요? 비슷한 현상이나...



tcp_conn_req_max 4096

tcp_ip_abort_interval 60000 등 iplanet권고값



커널파라미터

max_thread_proc 2048

maxdsiz 0x100000000

maxfiles(64) 8196

nkthread 8192

nproc 1044



oserr=233 (Insufficient resources)메세지는 뿌렸지만

OS측 문제는 아니라는 생각이듭니다.

HPjconfig함 돌려보고 java patch나 살펴볼 생각입니다.



3 응답 3
김병수
본과생

iplanet log관련문의

tcp/ip관련 parameter나 kernel parameter문제는 아니듯합니다.



이와 관련된 patch가 있으니

PHSS_28198

patch를 적용하시기 바랍니다.



그럼~~~

최이석
임시 조언자

iplanet log관련문의

답변 감사합니다.

그런데 해당 patch는 HPUX11.04(Virtual Vaults)로 11i에 설치가

안되는 걸로 아는데요.

고광태
중학생

iplanet log관련문의

혹시 FIN_WAIT_2 가 발생해서 생긴것이 아닌지..체크해보시기 바랍니다.



ndd -get /dev/tcp tcp_status (and grep for FIN_WAIT_2)







먼저, FIN_WAIT_1, FIN_WAIT_2, CLOSE_WAIT 이라는 TCP Status의 의미를 알고 있어야 할 것같습니다.



TCP(Transmission Control Protocol)은 비동기식 connectionless-protocol인 UDP(User

Datagram Protocol)와는 달리 connection-oriented, reliable, flow-controlled, end-to-

end communication protocol입니다. 즉, TCP는 데이타의 손실없이 보내어진 순서대로 전달되는

것을 보장하는 것이지요. 또한 TCP는 양측(two end points of a connection)에서 동시에

데이타를 전송할 수 있습니다. "full-duplex mode"인 것이지요. TCP 레벨에서 오고가는

프로토콜데이타단위(PDU, Protocol Data Unit)를 "segment"라고 부릅니다.



논리적으로 구분된 두 진영간에 데이타를 주고 받으려면, 먼저 그들 간에 "connection"이

이루어져야 합니다. TCP는 신뢰성 높은 연결 매카니즘을 제공하고 있는데, three-way

handshake라고 불립니다.(아직까지는 질문의 핵심과는 관련이 없는 내용들입니다. 계속

읽어보세요)

아래의 그림은 connection이 연결(establishment)되는 과정을 나타내고 있는데, 논리적인

호스트 A,B를 나타내고 있고, 수직선은 시간축입니다. host A에서 host B로 TCP 연결을

시도한다고 가정해 보겠습니다.



host A host B

| |

| LISTEN

| SYN |

|--------------------------->|

SYN_SENT |

| SYN |

|<---------------------------|

ESTABLISHED SYN_RECV NOTE: incomplete connection queue

| |

| ACK |

|--------------------------->|

| ESTABLISHED

| |



이 때 API 내부적으로 일어나는 일련의 bind/connect 과정에서 TCP레벨에서는 다음과

같이 동작하게 됩니다.

먼저, host A에서 SYN(synchronization) segment를 host B로 넘깁니다. host B는 동일하게

SYN segment를 host A로 reply 합니다. 아직까지는 연결(connection)이 완료된 것이

아닙니다. host A가 다시 ACK(acknowledgement) segment를 host B로 넘겨주어야만이 비로소

완전한 연결(established)이 이루어지게 됩니다. 즉, 총 3회의 SYN, SYN, ACK segment를

주고받는다하여 three-way handshake라고 부르는 것이지요. 이렇게 connection이 완료되면,

"netstat -n" 으로 보았을 때, 다음처럼 TCP상태가 "ESTABLISHED"로 나타나게 되는 것이지요.



host A:

# netstat -n | more

Proto Recv-Q Send-Q Local Address Foreign Address (state)

.........

tcp 0 0 192.168.0.10.62300 192.168.0.20:6123 ESTABLISHED

........





host B:

# netstat -n | more

Proto Recv-Q Send-Q Local Address Foreign Address (state)

.........

tcp 0 0 192.168.0.20.6123 192.168.0.10:62300 ESTABLISHED

........



PS: 물리적으로 같은 머신일 경우, 위 2가지가 같은 IP로 모두 나타나겠지요.





이제부터 데이타를 주고 받을 수 있는 상태가 되었습니다. (데이타를 주고받는 부분에 대한

매카니즘은 아래의 를 참조하세요)



이번에는 ESTABLISHED 된 상태에서 연결을 close 하는 과정을 지켜 보겠습니다.

TCP의 connection closing은 half-close 라고 불립니다. close() 메소드를 호출하면,

실질적인 연결이 양측 모두에서 정말 close 되는 것이 아니라, "앞으로 더이상

해당 connection을 통해서는 DATA를 보내지 않겠다"는 표식을 달아두는 것에 지나지

않습니다. 즉, 여전히 DATA를 받을 수 있습니다.



아래의 그림을 보겠습니다. host A에서 먼저 close() 메소드를 호출한다고 가정합니다.





host A host B

| |



ESTABLISHED ESTABLISHED

| |

close() |

| FIN_ACK |

|--------------------------->|

FIN_WAIT_1 CLOSE_WAIT

| |

| ACK |

|<---------------------------|

FIN_WAIT_2 |

. .

. .

. .



| (DATA) | 이 단계에서는 DATA 를 보낼 수도 있고, 그렇지 않을

|<---------------------------| 수도 있습니다.

| |

. .

. .

. . 일정한 시간동안 host A가 host B로부터 FIN_ACK를 받지

TIME_WAIT . 못할 경우, host A의 FIN_WAIT_2 상태가 TIME_WAIT으로

. . 변합니다.

. . 따라서, 아래처럼 host B에서도 반드시 close()가 불려져야

. . 합니다.

. close()

| |

| FIN_ACK |

|<---------------------------|

| LAST_ACK

| ACK |

|--------------------------->|

(CLOSEED) (CLOSED)



먼저 host A에서의 응용어플리케이션이 close()를 메소드를 호출하게 되면(client.close() )

TCP 레벨에서는 FIN_ACK(FINish ACKnowledgement) segment를 host B로 보내면서, host A의

TCP 상태는 FIN_WAIT_1 상태가 됩니다.

host B는 ESTABLISHED상태에서, host A로부터 날아온 FIN_ACK segment를 받으면 자신의 상태를

CLOSE_WAIT으로 만들면서, 응답을 위한 ACK 를 보냅니다.

host B로 부터 날아온 응답 ACK를 host A가 받으면, FIN_WAIT_1 상태가 FIN_WAIT_2 상태로

변하게 됩니다.



이제 여기서부터가 중요한데, 이 상태에서도, host A의 Input Stream에서는 Host B로부터

추가로 날아오는 데이타를 받아 들일 수 있습니다.(보낼 수는 없지만.)

만약, 이 상태(host A는 FIN_WAIT_2, host B는 CLOSE_WAIT상태)에서 host B에서의 응용

어플리케이션이 명시적으로 close() 메소드를 호출하지 않고 아무런 Action도 취하지 않게

되면, 일정한 시간동안 이 상태가 그대로 유지가 됩니다. 일정한 시간이 경과하면, host A의

상태는 TIME_WAIT상태로 넘어가게 되고, 또다시 일정한 시간이 경과하면 비로소 사라지게

(CLOSED) 됩니다.

host B에서도 유사한 현상이 일어납니다. CLOSE_WAIT 상태가 일정한 시간이 경과하여야만

비로소 사라지게 됩니다.



PS: host A에서 FIN_WAIT_2--> TIME_WAIT으로 넘어가는 시간, TIME_WAIT 상태가 사라지는

(CLOSED) 시간, 그리고, host B에서의 CLOSE_WAIT상태가 사라지는(CLOSED) 시간은

OS마다 설정이 다르며, 이 부분에 관련해서는 를 참조하세요.



만약, host A에서의 응용어플리케이션이 close() 메소드를 호출하여 날아온 FIN_ACK를

host B가 받고 TCP 레벨에서는 곧바로 응답 ACK를 host A로 보내 주었으며, 그래서

현재 host B의 상태가 CLOSE_WAIT상태에 있는데, 여기서 host B의 응용어플리케이션 내에서

이 상황을 알아차리고(?) 곧바로 close() 메소드를 날리면, TCP 레벨에서는 host B에서

host A로 FIN_ACK를 역으로 보내게 됩니다. 이 때 host B의 TCP상태는 LAST_ACK 상태, 즉,

host A로 부터 마지막 응답 ACK를 기다리게 되는 것이지요.

Host A는 이제, host B로부터 날아오는 FIN_ACK에 대해 응답 ACK를 보내고 자신의 상태는

완전히 사라진(CLOSED) 상태가 됩니다.

host B의 경우 역시 host A로 부터 날아온 ACK를 받고 나서야 LAST_ACK상태가 비로소 완전히

사라지게(CLOSED) 되는 것이지요.



이처럼, TCP connection을 연결하기 위해서는 3회의 SYN,SYN,ACK segment가 오고가게 되며,

반면, connection을 "closing"하기 위해서는 FIN_ACK, ACK segment를 서로 양측이 주고

받게 됩니다.

특히, 한쪽에서만 close() 한다고 하여 실질적으로 TCP연결이 closing되는 것이 아니라

상대편 역시 명시적인 close() 메소드가 호출되어 FIN_ACK를 양측 모두가 주고 받아야만이

비로소 완전한 단절(CLOSED)이 이루어 지게 됩니다. 그래서 TCP의 close는 half-close라고

불립니다.



얘기가 좀 지루하셨나요? 이제, 질문하신 분의 상황을 추정해 보겠습니다. TCP Socket

클라이언트와 서버가 같은 머신에 모두 존재하므로, netstat -n 으로 확인하시면 하나의

TCP connection에 대해 양측 모두 아래처럼 페어(pair)로 나타나고 있을 것입니다.



# netstat -n | more

Proto Recv-Q Send-Q Local Address Foreign Address (state)

.........

tcp 0 0 127.0.0.1.6123 127.0.0.1.62300 FIN_WAIT_2

tcp 0 0 127.0.0.1.62300 127.0.0.1.6123 CLOSE_WAIT

.........



포트번호 6123는 Socket Server의 Listening port인 것이 분명하고, 62300은 Socket

Client에서 자동으로 할당된 포트일 것입니다.

"Local Address"와 "Foreign Address"의 순서와 포트번호를 보면, 어느 것이 TCP Client이고,

어느 것이 TCP Server 인지 확인할 수 있습니다.



첫번째 라인에서 Local Address가 "127.0.0.1.6123"로 표시된 TCP 상태는 FIN_WAIT_2상태

입니다. 즉, TCP Socket Server 측에서의 응용어플리케이션이 close() 라는 메소드를 날렸고,

이에 따라 TCP레벨에서는 FIN_ACK를 상대편(여기서는 Java JNI C Socket Client)으로 보내주고

응답 ACK를 받은 상태라는 것을 알 수 있습니다.

근데, 뭘 하고 있는 상태입니까? 아직은 완전한 TCP연결이 끊어진 것이 아니라고 했죠?

half-close 상태입니다. 상대편(Java JNI C Socket Client)의 응용어플리케이션 레벨에서

명시적인 close() 메소드를 호출하여 날아오게 될 FIN_ACK를 기다리고 있는 중입니다.



PS: "CLOSE_WAIT" 상태에 빠져 있는 프로세스 쪽이 아직 close()를 하지 않아 close되기를

기다리고 있다"고 외우시면 됩니다.



원인이야 어떻든, TCP 상태는 이러한 상태입니다. 이러한 상황은 JNI C Socket Client 응용

어플리케이션에서 명시적인 close()가 호출되지 전까지, 그리고 OS마다 약간씩 다른 각각의

timeout 시간이 지나지 전까진 계속 지속될 것입니다.

혹은, 해당 unix process 가 kill 로 죽게 되면, OS 레벨에서 관련된 process의 TCP file

descriptor에 암묵적인 close() 동작이 일어나게 되고, 결국 상대편에게 FIN_ACK를

보냄으로써 기구한(?) TCP 상태의 life-cycle이 모두 사라지게 되는 것입니다.









많이 발생을 한다면 아래와 같이 조치하시길..



1. d -set /dev/tcp tcp_discon 0x




you need to update /etc/rc.config.d/nddconf



TRANSPORT_NAME=tcp

NDD_NAME=tcp_fin_wait_2_timeout

NDD_VALUE=660000 (11분정도)



HP 에서는 10분이하는 권장하지 않습니다.



참고하시길..