2017-01-11 9 views
0

C/S 기반 온라인 게임 프로젝트에서 네트워크 전송을 위해 TCP를 사용합니다. Libevent을 포함하고 네트워크 I/O를 자동으로 처리하는 각 연결에 bufferevent를 사용합니다.네트워크가 바쁠 때 매우 높은 대기 시간, TCP, libevent

이전에는 잘 작동했지만 지연 문제는 최근에 표면에 나타납니다. 네트워크를보다 효율적으로 사용하기 위해 스트레스 테스트를 수행하면 대기 시간이 수초 또는 그 이상으로 매우 길어집니다. 서버는 혼란 상태로 싱크 :

평균 CPU 사용량이 감소
  • (0 % -60 % -0 % -60 % 반복, 대기 무엇인가?) 순 트래픽 (nethogs)
  • 감소
  • 아직 서버 살아 그것은 뭔가처럼 보인다 (NETSTAT & tcpdump를)

에 연결된 클라이언트는 마술 아래 모든 시스템을 둔화하지만 서버에 새 연결 시간 종료 대응했다.

프로토콜을 UDP로 변경했을 때, 동일한 상황에서 잘 작동합니다. 명백한 대기 시간이없고 시스템이 빠르게 실행됩니다. 순 트래픽은 약 3M/S입니다.

프로젝트가 인트라넷에서 실행 중입니다. 또한 최대 다운로드 속도, 거의 18M/S를 테스트했습니다.

나는 Libevent의 헤더 파일과 ducumentations의 일부를 연구하여 모든 연결에 속도 제한을 설정하려고했습니다. 몇 가지 개선 사항을 수행했지만 몇 가지 다른 구성을 시도했지만 문제를 완전히 해결하지는 못했습니다. 여기 내 매개 변수가 있습니다 : read_rate 163840, read_burst 163840, write_rate 163840, write_burst 163840, tick_len 500ms.

도움 주셔서 감사합니다.

답변

1

TCP = 전송 제어 프로토콜. 지연 후 미확인 패킷을 재전송하여 패킷 손실에 응답합니다. 반복적 인 손실의 경우에는 기하 급수적으로 감소 할 것입니다. 응답하지 않는 그 호스트에 대한 연결을 열 시도의 네트워크 캡처를 살펴 보자 : 그것은 초기 SYN 보낸 다음 1 초 동안 ACK를받지 후 다시 시도

enter image description here

. ack을 얻지 못한 후에는 ~ 2s, ~ 4s, then ~ 8s 등등 다음에 또 다른 것을 보냅니다. 따라서 반복되는 패킷 손실에도 불구하고 심각한 대기 시간을 확보 할 수 있음을 알 수 있습니다.

의도적으로 네트워크에 부하를주고 CPU 사용량에 일관성이 없다고 말했기 때문에 TCP가 손실 된 패킷을 재전송하기 위해 대기 중입니다.

무슨 일이 벌어지고 있는지 확인하는 가장 좋은 방법은 실제로 전송 된 것을 네트워크로 캡처하는 것입니다. 호스트가 단일 스위치에 연결되어있는 경우 관심 대상 포트를 캡처 할 수있는 다른 호스트의 포트로 "스팬"할 수 있습니다.

스위치가이 기능을 지원하지 않거나 스위치에 대한 관리 권한이없는 경우 온라인 게임과 관련된 호스트 중 하나에서 캡처해야합니다. 이 단점은 캡처를 수행하면 상황이 바뀔 수 있으며 실제로 와이어에 무엇이 있는지를 알 수 없습니다. 예를 들어 인터페이스에서 TCP 세그먼트 오프로드를 사용하도록 설정 한 경우 캡쳐에 네트워크 인터페이스에서 깨질 큰 패킷이 표시됩니다.

wireshark를 설치하여 네트워크 캡처 (wireshark를 사용하여 실시간으로 캡처를 수행 할 수 있음)를 분석하는 것이 좋습니다. 네트워크로 연결된 시스템으로 작업 할 때마다 wireshark를 사용하여 실제로 네트워크에서 어떤 일이 일어나는지 알 수 있습니다. 내가 사용하기를 제안하는 첫 번째 필터는 tcp.analysis.flags입니다.이 필터는 문제를 암시하는 패킷을 보여줍니다.

속도 제한 기능을 끄는 것이 좋습니다 (속도 제한은 다른 패킷을 보내지 않는 이유입니다. 이는 어떤 일이 일어나는지 진단하기가 더 어려워 질 것입니다).). 또한 게임이 작동하는 방식에 따라 500ms가 길어질 수도 있습니다 (tick_len). 버스트 구성으로 100ms 이내에 속도를 사용할 수있게되면 다시 전송하기 전에 400ms를 기다려야합니다. IO 그래프는 이와 관련하여 Wireshark의 매우 유용한 기능입니다. 기본 눈금 간격과 단위가이 점에별로 도움이되지 않지만 전송 속도를 볼 수 있습니다.

enter image description here

눈금 간격이 1ms 인 것으로 도시 및 장치가 비트/체크된다 차트 1기가바이트/s의 상단한다 : 여기 200mbit/s로 제한된 버스트 유동되는 레이트의 예는 , 문제의 인터페이스 속도.

+0

정말 감사드립니다. 정말 고마워요. wireshark를 통해 네트워크 캡처를 얻으려는 귀하의 충고를 따랐습니다. 180 초 동안 총 312788 프레임을 얻었습니다. 37 클라이언트에서 서버로의 중복 ACK, 27 서버에서 클라이언트로의 재전송. 입출력 그래프 또한 매우 일관성이 없으며 대개 94KB/S이며 갑자기 일정한 시간 간격으로 4040 ~ 5586KB/S로 급상승합니다. 평균 시간 간격은 약 7 초이며 시간이 지남에 따라 간격이 길어지고 길어집니다. 즉 IO 그래프의 일관성이 떨어지고 있습니다. – walter

+0

@walter 안녕하세요. 캡처를 어딘가에 넣을 수 있다면 기꺼이 받아 볼 수 있습니다. 네트워크 캡쳐에서 어떤 일이 일어나고 있는지 파악할 수있는 것은 실제 스킬이며, 디버거를 사용하는 것이 좋습니다. 하지만 투자 가치가있는 매우 가치있는 기술이 될 수 있습니다. –

+0

이메일 주소를 알려주시겠습니까? 쉽게 얻을 수있는 클라우드 서비스에 파일을 업로드하는 것이 조금 어렵습니다. 외국 웹 사이트를 탐색하는 속도가 너무 느립니다. – walter