TCP data가 일정시간 block되는 현상
하나의 서버 process가 대략 400-500개의 socket을 열어 client와 연결을 맺고 있습니다. socket은 non-blocking으로 지정을 합니다.
내부에서 하나의 thread가 TCP 연결만을 처리(socket fd 관리)해 주고 6개의 threads가 client의 조건에 따라서 일방적으로 data를 보내주기만 합니다(client에서 오는 data는 TCP 연결하는 것 말고는 없습니다).
data발생빈도는 무지 높습니다. 초당 20-100건의 data가 client 조건에 따라서 각 client에게 전송됩니다. send socket error가 발생하면 data는 버려 버립니다.
또한 client의 연결도 붙었다 끊어졌다를 반복합니다.
OS는 Solars입니다.
문제현상은 어느순간 data를 client로 전송하지 못한다는 것입니다. 일정시간(짧게 2초에서 길면 10초정도) block이 되었다가 순간적으로 풀리는 현상입니다.
이때 packet이 오가는 것을 보려고 snoop(tcpdump와 비슷함)으로 보면 서버에서 client로 보내지 못합니다.
문제는 snoop은 멈춰있어도 truss로 보면 위의 process는 계속 send()를 하고 있다는 것입니다.
위의 결과를 판단으로 개인적으로 내린 결론은 socket buffer가 차있다는 것입니다.
질문은 다음과 같습니다.
1. 하나의 process에서 400-500개의 TCP 연결을 맺고 있을 때 각 socket마다 send/recv buffer가 별도로 할당되는 건가요? 아니면 하나의 send/recv buffer가 할당되는 건가요?
1.1 만약 하나의 send/recv buffer가 할당된다면 setsockopt를 통해서 socket send buffer를 늘리는 방법이 효과가 있을까요?
1.2 각 socket마다 send/recv buffer가 할당된다면 data를 잘 못 가져가는 client만 지연되거나 하는 현상이 나타나야 할건데 대부분이 그런현상이 나타나는건 어떻게 설명해야 할까요?
2. 위와 같은 경우 순간적인 지연현상을 예방하기 위한 대책이 있을까요? (1.1과 같이 socket buffer를 늘리는 방법등 )
3. process 문제점을 점검할 수 있는 다른 방법이 있을까요?
( 로그로 확인하기에는 data가 너무 많고 block되는 주기는 많지 않기 때문에 문제가 있습니다 )
4. 달리 시도해 볼 수 있는 방법이 있을까요?
1. 각각의 버퍼를 가집니다.1.1 send에서 에러가 난다면 늘
1. 각각의 버퍼를 가집니다.
1.1 send에서 에러가 난다면 늘리는게 효과가 있을수 있고
에러가 나지 않는다면 효과가 없을것 같습니다.
그러나 지연과는 별상관이 없을것 같습니다.(noblocking..)
1.2 cpu사용율이 100%인가요? 혹시 잦은 connect에 의한 지연현상인지 확인해보세요(netstat)로 확인해보세요.
방법은 괜찮아 보이는데... 나머진 잘모르겠군요.. --;
그나저나 백수 언제 탈출하냐... ㅡㅡ; 배고파라.
[quote]cpu사용율이 100%인가요? 혹시 잦은 connect에 의
CPU사용율은 낮습니다. 아주 안정적(CPU 4-7%정도)입니다.
netstat로 어떻게 connect에 의한 지연현상을 확인할 수 있죠?
다른 한가지 질문으로 socket send buffer가 다 찼을 경우 강제적으로 비울수 있는 방법 있을까요?
>/dev/null 2>&1
[quote]혹시 잦은 connect에 의한 지연현상인지 확인해보세요(n
대답이 잘못 되었군요 :(
TIME_WAIT가 많이 발생하고 있는지 확인해보세요.
최대 fd open 갯수를 넘어서 accept할수 없는 상황인지
확인해보세요.
그나저나 백수 언제 탈출하냐... ㅡㅡ; 배고파라.
Non-block Send 가 있는데, 그걸 사용해 보시는 것은 어떤
Non-block Send 가 있는데,
그걸 사용해 보시는 것은 어떤지요...
TCP 를 사용하고, NO_DELAY Option 을 사용하셨다면,
ACK 를 받는데 걸리는 시간 같은데요... -.-;;
[quote]TIME_WAIT가 많이 발생하고 있는지 확인해보세요.
TIME_WAIT는 발생하지 않습니다. 또한 SO_REUSEADDR를 켜놓았습니다.
최대 fd개수는 4096으로 setting해 놓았고 하나의 process에 2048 이상 connect 시켜봤습니다.
그러므로 connect()에서 발생하는 문제는 아닙니다.
Non-block Send가 뭘 말하는건지요?
TCP Non-blocking socket을 얘기하는 것 아닌가요?
우선은 월요일에 확인하겠지만 socket send buffer를 512K를 늘렸고 threads에서 mutex사용을 기존에는 pthread_mutex_lock()과 pthread_cond_wait()를 이용하여 하던 것을 pthread_mutex_lock()만을 사용하게 해 놓았습니다.
어떻게 될지는 모르겠네요 ^^;
>/dev/null 2>&1
send 함수 부를때, flag 주는 게 있습니다. DONTWAIT
send 함수 부를때, flag 주는 게 있습니다.
DONTWAIT 를 주면, TCP Stack 으로 데이타를 넘기고,
바로 리턴이 되지요...
리턴값은 반드시 체크해 보아야 하고요..
질문을 다시 읽어보니깐, Send 할때 Block 되는 것이 아니라,
질문을 다시 읽어보니깐, Send 할때 Block 되는 것이 아니라,
전송했는데, 패킷이 나가지 않는 것을 말하는 것 같네요.. -_-;;
제생각에는 TCP 는 복잡해서리,,
UDP 로 바꾸는게 좋을 것같은네요.. -.-;;
Re: TCP data가 일정시간 block되는 현상
1.send() 를 하고 있다는 것이 send() 에 block되어 있다는 것인가요?
아니면 계속해서 여러번의 send()가 수행되고 있다는 건가요?
(말씀하신대로 버퍼가 다 차서 send()에서 block되어 있는 것으로 보이는데, 혹시나 해서..)
2. 2초에서 10초간 지연되는 현상이 하나의 connection에서만 발생하는건가요?
아니면 해당 프로세스가 열고 있는 모든 소켓에서 다 발생하는건가요?
그 당시에 TCP 윈도우 상태는 어떤가요?
(서버쪽의 TCP쪽이나 프로그램의 잘못인지, 문제있는 클라이언트에서 데이터를 안 받아가서 일어나는 현상인지 궁금해서...)
3. 프로그램 수행한 후 얼마 후에 그런 증상이 발생하나요?
그 후에도 계속 그런 일이 발생하나요?
(혹시 멀티스레드 방식이라면, 해당 스레드가 오래 수행되어서 우선순위가 떨어져서 수행이 늦어지는 것이 아닐까 하는 생각에...)
4. 2초에서 10초간 지연이 하나의 연결에서만 발생하고 정상적인 서비스 수행에 문제가 안된다면(온라인 게임인가요? ㅡ.ㅡ;;)
send 하는 쪽도 멀티플랙싱을 하는 모델을 도입하시는 것은 어떠실지...
이거 해결이 되셨나 모르겠네요...
저도 비슷한 현상이 일어나는 것 같습니다.
우선... 리눅스 프로그래밍이 첨이라 미숙해서
서버를 데몬으로 띄우진 않았는데요
데몬으로 수정해보고 테스트해보려고 처리를 잠시 미루어 두었는데요...
해결되셨으면 어떤 방법으루 되셨는지....
알려주시면 감사하겠습니다..
언제 고수되나.
댓글 달기