2010-06-08 4 views
3

Solaris에서 RH Linux로 마이그레이션 할 클라이언트/서버 응용 프로그램 (Java)이 있습니다. RH에서 실행하기 시작한 이래 대기 시간과 관련된 몇 가지 문제점을 발견했습니다. 나는이처럼 보이는 문제를 분리 관리 :Solaris를 RH로 마이그레이션 : 네트워크 대기 시간 문제, TCP 창 크기 및 기타 TCP 매개 변수

  • 클라이언트가 서버에 5 메시지 행 (동일한 응용 프로그램 타임 스탬프)에서 (각 32 바이트)를 보냅니다.
  • 서버 에코 메시지
  • 클라이언트는 각 메시지에 대한 응답을 받고 왕복 시간을 인쇄합니다. 솔라리스에서

는, 모두가 잘 : 나는 동시에 ALL 5 개 응답을 얻을, 대략 평균 80ms가 보낸 원래 메시지를 (클라이언트 & 서버를 가진 후 몇 천 마일이 서로 떨어져있는 내 핑 RTT는 모두 평균 80ms입니다 표준).

(RH에서) 처음 세 개의 메시지는 정상적으로 에코됩니다 (전송 된 후 80ms가 지나면 도착합니다). 그러나 다음 2 분이 80ms 후에 도착합니다 (총 160ms RTT).

패턴은 항상 동일합니다. TCP 문제처럼 보입니다.

내 솔라리스 상자에

, 내가 이전에이 특정 옵션을 사용하여 TCP 스택을 구성했다 :

  1. 해제의 Nagle 알고리즘 세계적으로
  2. 설정 tcp_deferred_acks_max 0 RH에

에, 그것은 불가능 전역 적으로 nagle을 사용하지 않도록 설정했지만 모든 응용 프로그램 소켓 (TCP_NODELAY)에서 사용하지 않도록 설정했습니다. 그래서

17 2.081163 client   server   TCP  55879 > 6006 [PSH, ACK] Seq=111 Ack=106 Win=66672 Len=22 "MSG_1 RCV" 
18 2.081178 server   client   TCP  6006 > 55879 [ACK] Seq=106 Ack=133 Win=5888 Len=0 
19 2.081297 server   client   TCP  6006 > 55879 [PSH, ACK] Seq=106 Ack=133 Win=5888 Len=21 "MSG_1 ECHO" 
20 2.081711 client   server   TCP  55879 > 6006 [PSH, ACK] Seq=133 Ack=106 Win=66672 Len=22 "MSG_2 RCV" 
21 2.081761 client   server   TCP  55879 > 6006 [PSH, ACK] Seq=155 Ack=106 Win=66672 Len=22 "MSG_3 RCV" 
22 2.081846 server   client   TCP  6006 > 55879 [PSH, ACK] Seq=127 Ack=177 Win=5888 Len=21 "MSG_2 ECHO" 
23 2.081995 server   client   TCP  6006 > 55879 [PSH, ACK] Seq=148 Ack=177 Win=5888 Len=21 "MSG_3 ECHO" 
24 2.082011 client   server   TCP  55879 > 6006 [PSH, ACK] Seq=177 Ack=106 Win=66672 Len=22 "MSG_4 RCV" 
25 2.082362 client   server   TCP  55879 > 6006 [PSH, ACK] Seq=199 Ack=106 Win=66672 Len=22 "MSG_5 RCV" 
26 2.082377 server   client   TCP  6006 > 55879 [ACK] Seq=169 Ack=221 Win=5888 Len=0 
27 2.171003 client   server   TCP  55879 > 6006 [ACK] Seq=221 Ack=148 Win=66632 Len=0 
28 2.171019 server   client   TCP  6006 > 55879 [PSH, ACK] Seq=169 Ack=221 Win=5888 Len=42 "MSG_4 ECHO + MSG_5 ECHO" 
29 2.257498 client   server   TCP  55879 > 6006 [ACK] Seq=221 Ack=211 Win=66568 Len=0 

:

SOLARIS :

22 2.085645 client   server   TCP  56150 > 6006 [PSH, ACK] Seq=111 Ack=106 Win=66672 Len=22 "MSG_1 RCV" 
23 2.085680 server   client   TCP  6006 > 56150 [ACK] Seq=106 Ack=133 Win=50400 Len=0 
24 2.085908 client   server   TCP  56150 > 6006 [PSH, ACK] Seq=133 Ack=106 Win=66672 Len=22 "MSG_2 RCV" 
25 2.085925 server   client   TCP  6006 > 56150 [ACK] Seq=106 Ack=155 Win=50400 Len=0 
26 2.086175 client   server   TCP  56150 > 6006 [PSH, ACK] Seq=155 Ack=106 Win=66672 Len=22 "MSG_3 RCV" 
27 2.086192 server   client   TCP  6006 > 56150 [ACK] Seq=106 Ack=177 Win=50400 Len=0 
28 2.086243 server   client   TCP  6006 > 56150 [PSH, ACK] Seq=106 Ack=177 Win=50400 Len=21 "MSG_1 ECHO" 
29 2.086440 client   server   TCP  56150 > 6006 [PSH, ACK] Seq=177 Ack=106 Win=66672 Len=22 "MSG_4 RCV" 
30 2.086454 server   client   TCP  6006 > 56150 [ACK] Seq=127 Ack=199 Win=50400 Len=0 
31 2.086659 server   client   TCP  6006 > 56150 [PSH, ACK] Seq=127 Ack=199 Win=50400 Len=21 "MSG_2 ECHO" 
32 2.086708 client   server   TCP  56150 > 6006 [PSH, ACK] Seq=199 Ack=106 Win=66672 Len=22 "MSG_5 RCV" 
33 2.086721 server   client   TCP  6006 > 56150 [ACK] Seq=148 Ack=221 Win=50400 Len=0 
34 2.086947 server   client   TCP  6006 > 56150 [PSH, ACK] Seq=148 Ack=221 Win=50400 Len=21 "MSG_3 ECHO" 
35 2.087196 server   client   TCP  6006 > 56150 [PSH, ACK] Seq=169 Ack=221 Win=50400 Len=21 "MSG_4 ECHO" 
36 2.087500 server   client   TCP  6006 > 56150 [PSH, ACK] Seq=190 Ack=221 Win=50400 Len=21 "MSG_5 ECHO" 
37 2.165390 client   server   TCP  56150 > 6006 [ACK] Seq=221 Ack=148 Win=66632 Len=0 
38 2.166314 client   server   TCP  56150 > 6006 [ACK] Seq=221 Ack=190 Win=66588 Len=0 
39 2.364135 client   server   TCP  56150 > 6006 [ACK] Seq=221 Ack=211 Win=66568 Len=0 

REDHAT

그래서 두 출력 (서버 시스템에서) tcpdump와 함께 재생을 시작하고, 비교 나는 RH에 대해 제대로 작동하지 않는다는 확인을 얻었습니다. 패킷 28은 너무 늦게 전송되었습니다. 서버는 아무것도 수행하기 전에 패킷 27의 ACK를 기다리고 있습니다. RH에 Solaris에서 50400 만 5888 :

다음 나는 "승리"매개 변수를 덤프 솔라리스 & RH에 다른 것을 깨달았다 ... 그것은 가장 가능성있는 이유는 나에게 보인다. 즉, (I 체크 내가 슬라이드 창 & 버퍼 창에 대한 문서를 읽을 수없고, 내 소켓에 자바에 rcvBuffer & sendBuffer와 함께 놀았지만, 결코 다른 어떤이 5888 값을 변경 관리

... 또 다른 힌트 매번 tcpdump로 직접).

누구나이 작업을 수행하는 방법을 알고 있습니까? 어떤 경우에는 바이 패스해야 할 수도있는 "자동 교섭"이있는 것처럼 확실한 정보를 얻는 데 어려움을 겪고 있습니다.

결국 RH에서 "tcp_slow_start_after_idle"매개 변수를 0으로 설정하여 초기 문제를 부분적으로 없애 버렸지 만 "win"매개 변수를 전혀 변경하지 않았습니다. TCP 재전송 & tcpdump에서 TCP Dup ACK를 사용하여 5 개의 메시지로 이루어진 처음 4 개 그룹에 동일한 문제가 있었지만 다음 메시지는 5 개의 메시지 그룹 모두에서 사라졌습니다.

나에게 매우 깨끗하거나 일반적인 해결책으로 보이지 않습니다. 두 OS 모두에서 정확히 같은 조건을 재현하고 싶습니다.

저는 계속 조사하겠습니다 만, TCP 전문가의 도움을 받아 주시면 감사하겠습니다!

+0

추적 내용이 설명과 일치하지 않습니다. 레드햇 트레이스는 솔라리스보다 시간이 적으므로 대기 시간 문제는 볼 수 없습니다. 또한 에코는 너무 빠르기 때문에 (1ms 미만) 루프백이나 LAN에서 처리되는 것처럼 보입니다. –

+0

왼쪽의 타임 스탬프는 (솔라리스와 RH 사이에서) 비교할 수 없습니다. 각 패킷 내에서 첫 번째 패킷이 수신 된 순간과 관련이 있습니다. 시험은 동시에 수행되지 않습니다. 문제는 MSG 수신과 서버에서 측정 한 반향 응답 간의 응답 시간입니다. solaris에서 모든 에코는 첫 번째 메시지 (2.087500 - 2.085645 = 0.001855) 수신시 약 2ms 이내에 전송됩니다. RH, 4 번째 & 5 번째 에코가 90ms 후에 전송됩니다 (2.171019 - 2.081163) – Bastien

답변

1

Red Hat 상자에서 혼잡 방지 알고리즘이 작동하는 것처럼 보입니다.

패킷 26에서 서버는 클라이언트로부터 모든 것을 확인하고 ACK하지만 클라이언트는 아직 서버의 메시지 중을 번 ACK하지 않은 것을 알 수 있습니다. 또 다시 패킷 27은 서버의 처음 두 개의 데이터 (패킷 19와 22)를 확인하는 클라이언트입니다.

Red Hat 상자 중 어떤 혼잡 제어 알고리즘을 사용합니까? (/proc/sys/net/ipv4/tcp_congestion_control) - 다른 사용 가능한 것으로 전환 해보십시오.

+0

예 포인트입니다. 우려, 많은 에코 클라이언트에 의해 ACKed되지 않습니다 참조하십시오 및 일부 메커니즘을 더 이상 ACK를받을 때까지 서버를 보내는 중지합니다 상상해보십시오 : 그것은 단지 ACK를받은 후 4와 5 에코를 보냅니다. 이 메커니즘을 일으키는 원인과 영향을 미치는 방법을 잘 모릅니다. 은 정체 제어와 함께 놀 것이며, 현재는 "3 차"입니다. 연구 할 것입니다 ... 감사합니다! – Bastien

+0

@Bastien : "reno"(그냥'echo "reno">/proc/sys/net/ipv4/tcp_congestion_control')로 설정해 보시고 그 행동이 더 마음에 드는지보십시오. – caf

+0

을 "reno"로 변경했는데 동작이 전혀 변경되지 않았습니다 ... – Bastien