2017-01-11 10 views
0

Dans notre projet de jeu en ligne basé sur C/S, nous utilisons TCP pour la transmission réseau. Nous incluons Libevent, utilisons un bufferevent pour chaque connexion à gérer avec les E/S réseau automatiquement.Latence extrêmement élevée lorsque le réseau est occupé, TCP, libevent

Cela fonctionne bien avant, mais le problème de retard vient à la surface récemment. Lorsque je fais un test de stress pour rendre le réseau plus actif, la latence devient extrêmement élevée, plusieurs secondes ou plus. Le serveur s'enfonce dans un état confus:

  • l'utilisation moyenne du processeur a diminué (0% -60% -0% de répétition -60%, quelque chose d'attente?)
  • le trafic net a diminué (nethogs)
  • les clients connectés au serveur encore en vie (netstat & tcpdump)

Il ressemble à quelque chose ralenties par magie tout système vers le bas, mais une nouvelle connexion au serveur a répondu à arrêter dans le temps.

Lorsque j'ai changé le protocole en UDP, cela fonctionne bien sur la même situation: pas de latence apparente, le système s'exécute rapidement. Le trafic net est d'environ 3M/S.

Le projet s'exécute sur un intranet. J'ai également testé la vitesse de téléchargement max, près de 18M/S.

J'ai étudié une partie des fichiers d'en-tête et des instructions de Libevent, j'ai essayé de configurer une limite de débit pour toutes les connexions. Il a fait quelques améliorations, mais pas complètement résolu le problème même si j'avais essayé plusieurs configurations différentes. Voici mes paramètres: read_rate 163840, read_burst 163840, write_rate 163840, write_burst 163840, tick_len 500ms.

Nous vous remercions de votre aide!

Répondre

1

TCP = protocole de contrôle de transmission. Il répond à la perte de paquets en retransmettant des paquets non reconnus après un délai. Dans le cas de perte répétée, il va exponentiellement reculer. Jetez un oeil à cette capture réseau d'une tentative d'ouverture d'une connexion à l'hôte qui ne répond pas:

enter image description here

Il envoie le SYN initial, puis après ne pas avoir un ack pour 1s il essaie à nouveau. Après ne pas avoir reçu un accusé de réception, il en envoie un autre après ~ 2s, puis ~ 4s, puis ~ 8s, et ainsi de suite. Donc, vous pouvez voir que vous pouvez obtenir une latence grave face à la perte répétée de paquets. Comme vous avez dit que vous étiez en train d'insister sur le réseau et que l'utilisation du processeur est incohérente, une explication possible est que TCP attend de retransmettre les paquets perdus.

La meilleure façon de voir ce qui se passe est d'obtenir une capture réseau de ce qui est réellement transmis. Si vos hôtes sont connectés à un seul commutateur, vous pouvez "étendre" un port d'intérêt au port d'un autre hôte où vous pouvez effectuer la capture.

Si votre commutateur n'est pas capable de cela, ou si vous n'avez pas le contrôle administratif du commutateur, alors vous devrez obtenir la capture de l'un des hôtes impliqués dans votre jeu en ligne. L'inconvénient de ceci est que le fait de prendre la capture va peut-être modifier ce qui se passe, et il ne voit pas ce qui est réellement sur le fil. Par exemple, vous pouvez activer le déchargement de la segmentation TCP pour votre interface, auquel cas la capture affichera des paquets volumineux qui seront décomposés par l'interface réseau.

Je suggère d'installer wireshark pour analyser la capture réseau (que vous pouvez faire en temps réel en utilisant wireshark pour faire la capture aussi bien). Chaque fois que vous travaillez avec un système en réseau, je vous recommande d'utiliser wireshark afin que vous ayez une certaine visibilité sur ce qui se passe réellement sur le réseau. Le premier filtre que je vous suggère d'utiliser est le tcp.analysis.flags qui vous montrera des paquets suggérant des problèmes.

Je suggère également de désactiver le taux limite d'abord à essayer de voir ce qui se passe (la limitation du débit est l'ajout une autre raison de ne pas envoyer des paquets, qui va probablement rendre plus difficile à diagnostiquer ce qui se passe). En outre, 500ms peut être un tick_len selon la façon dont votre jeu fonctionne. Si votre configuration en rafale permet d'utiliser le débit en 100 ms, vous devrez attendre 400 ms avant de pouvoir transmettre à nouveau. Le graphique IO est une fonctionnalité très utile de Wireshark à cet égard. Cela peut vous aider à voir les taux de transmission, bien que l'intervalle de tique par défaut et l'unité ne soient pas très utiles à cet égard. Voici un exemple d'un taux étant de débit en rafale limité à 200Mbit/s:

enter image description here

Notez que l'intervalle de tique est 1ms et l'unité est bits/TICK, ce qui rend le haut du tableau 1Go/s , la vitesse de l'interface en question.

+0

Je suis vraiment reconnaissant pour votre aide, merci beaucoup! J'ai suivi votre conseil pour obtenir une capture réseau via wireshark. J'ai obtenu un total de 312788 images pendant 180 secondes, y compris: 37 ACK Dupliquer du client au serveur, 27 retransmissions du serveur au client. Le graphique IO est également très incohérent, principalement 94KB/S, et soudainement monter à 4040 ~ 5586 KB/S dans un intervalle de temps régulier. L'intervalle de temps moyen est d'environ 7 secondes et l'intervalle devient plus long et plus long au fil du temps, en d'autres termes, le graphique IO devient de plus en plus incohérent. – walter

+0

@walter De rien. Si vous pouvez mettre la capture quelque part je peux l'obtenir, je serais heureux de jeter un coup d'oeil. Être capable de comprendre ce qui se passe à partir d'une capture de réseau est une vraie compétence, un peu comme si l'on utilisait un débogueur. Mais il peut être une compétence très utile d'investir. –

+0

Puis-je avoir votre adresse e-mail s'il vous plaît? C'est un peu difficile pour moi de télécharger le fichier vers un service cloud que vous pouvez obtenir facilement. La vitesse ici pour naviguer sur un site Web étranger est très lente. – walter