IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

Performances d'un serveur.


Sujet :

Java

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 17
    Points : 6
    Points
    6
    Par défaut Performances d'un serveur.
    Bonjour,
    Je suis actuellement en train de réaliser une application client/serveur pour un petit jeu en ligne.
    J'ai quelques soucis de performances avec mon serveur. Voici son schéma :
    J'ai un Thread qui s'occupe d'accueillir le client jusqu'à sa connexion (un par client) et qui envoie ensuite le client dans un container :
    le container est un triplet de Threads.
    Chaque container contient au maximum 10 clients dans une ArrayList.
    Le container distribue chaque client parmis ces trois Threads :
    Un bufferedReader pour le Thread qui recevra les packets et un PrintWriter pour le Thread qui enverra les paquets.
    Le dernier Thread est celui qui traite les paquets. Ces trois Thread sont reliés pas des tubes interThread : PipedWriter et PipedReader.
    Tout marche parfaitement seulement, lors de la connexion d'un client, le processeur s'excite et affiche 100% d'utilisation, donc en gros il est au maximum de ses capacités. J'ai bien vérifié, aucun Thread de trop n'est lancé, et à chaque déconnexion/vidage d'un container, les threads sont tués.

    Pour la réception des paquets : une boucle for qui parcourt l'ArrayList de BufferedReader : Si il y a quelque chose a lire dans le br on le lit, sinon on passe au suivant. tout ça dans une boucle while qui se stoppe uniquement si le container est vide.

    Est ce ma méthode qui ne fonctionne pas ? D'ou peut bien venir ce problème ? Je n'ai pas un PC surpuissant mais je n'ai jamais réussi à atteindre ces 100% d'utilisation...

  2. #2
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    100% d'utilisation CPU et une boucle infini... J'ai bien peur que ta boucle tourne un peu trop !


    Quels sont les informations qui doivent être échangé ? On pourrait voir un peu de code ?


    a++

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 17
    Points : 6
    Points
    6
    Par défaut
    Les informations échangées ? l'id du compte propriétaire du message, une chaine de caractères contenant le paquet à transmettre.
    Voici le code : du Receiver.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    package network;
     
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.util.ArrayList;
     
    import common.Container;
    import manager.Writer;
     
    public class Receiver extends Thread {
     
    	private ArrayList<BufferedReader> in = new ArrayList<BufferedReader>(); // Liste de tous les br (l'id dans l'arraylist est la même pour chaque partie du container)
    	private Writer out; // Le writer est un objet que j'ai créé (contrairement au Writer de java.io) qui contient un PipedWriter avec un systeme pour "normaliser" les paquets.
    	private String packet;
    	private Container container;
     
    	public Receiver(Writer _out, Container _container) { // Constructeur
    		this.out = _out;
    		container = _container;
    	}
     
    	public void run() {
    		while (true) {
    			for (BufferedReader br : in) {  // Parcours de la liste de in
    				try {
    					if (br.ready()) { // Si il y a quelque chose à lire
    						packet = br.readLine(); // on le lit
    						System.out.println("Receiver : J'ai reçu le paquet " + packet); // Mouchard
    						out.send(packet, in.indexOf(br)); // On l'envoi dans le tube au Handler (traitement du packet)
    					}
    				} catch (IOException e) {
    					int id = in.indexOf(br);
    					System.out.println("Probleme avec le compte d'id : " + id + ", kick du compte");
    					container.kickID(id);
    				}
    				try {
    					Thread.sleep(10); // J'ai essayé de faire dormir le Thread après chaque br testé, mais ça ne change rien.
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			}
    		}
     
    	}
     
    	public void add(BufferedReader _in) {
    		in.add(_in);		
    	}
     
    	public void remove(int id) {
    		in.remove(id);
    	}
     
    }

  4. #4
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Normal : tu utilises une boucle active !!!

    Ton code consomme plus de CPU quand il ne fait rien, puisqu'il passe son temps à tourner en rond dans une boucle vide...

    Essayes d'augmenter le temps du sleep(), et de le déplacer dans le while()...


    Mais je pense que tu devrais te tourner vers NIO.2 qui propose des selecteurs pour cela.


    Attention également au fait que ton code n'est pas du tout synchronisé


    a++

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 17
    Points : 6
    Points
    6
    Par défaut
    Comment ça pas synchronisé ? (encore des choses à apprendre )
    Je vais faire un tour pour savoir ce qu'est NIO.2
    Le déplacer ? Pour le mettre où ? j'ai déjà essayé en dehors du for mais sans succès, je vais essayer d'augmenter le temps d'attente.

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 17
    Points : 6
    Points
    6
    Par défaut
    Le truc, c'est que je ne vois pas quelle méthode synchronisée dans ma classe Receiver.

  7. #7
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    Déjà, , c'est mauvais : tu ne veux pas que ta boucle tourne jusqu'à la fin des temps, il y a donc une condition de sortie, donc cela ne correspond pas à ce que tu veux faire.

    Ensuite, comment appelles-tu ce thread "Receiver" ? Par "run" ou par "start" ?
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 17
    Points : 6
    Points
    6
    Par défaut
    Le while (true) est temporaire, je compte mettre un timer qui "détruit" les container vides toute les x minutes.
    J'appelle mon Receiver par receiver.start() sinon quel interet de l'extends en Thread ?

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 17
    Points : 6
    Points
    6
    Par défaut
    En ajoutant un Thread.sleep(100); à chaque boucle (recevier, handler, sender) j'obtiens un processeur moins excité, mais je ne pense pas que ce soit la solution...

  10. #10
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    Pour "run/start" je pose la question parce qu'on ne sait jamais, quoiqu'en relisant mieux j'aurais peut-être pu le comprendre tout seul.

    Sinon pourquoi 100 dans les sleeps ? comment as-tu calculé ça ?
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  11. #11
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 17
    Points : 6
    Points
    6
    Par défaut
    J'ai testé avec plusieurs valeurs, le 100 est un peu hasardeux enfait...
    J'ai changé le while (true) par un while (boolean) et ce booléen passe à faux lorsque le container est vide. (timer de 10 minutes).
    Je ne sais pas par quoi remplacer les 100 ms... C'est une solution de secours mais je pense que c'est la moins efficace..;

  12. #12
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    Pas forcément... Il faut calculer un peu le temps que prennent les choses, et voir... en revanche, mettre plusieurs sleep je ne pense pas que ce soit une bonne idée...
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  13. #13
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 17
    Points : 6
    Points
    6
    Par défaut
    A terme ce sera 10 joueurs max par container.
    On pourrait faire une formule pour calculer le temps d'attente en fonction du nombre de clients dans le container.
    Pour les sleep il y en a un par Thread. ça devrait suffire je pense.
    je pensais 200ms / x avec x le nombre de client.
    Ou sinon on nombre constant, mais lequel...

  14. #14
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    Tu peux peut-être faire un petit interface d'options pour régler facilement et pouvoir tester sans devoir changer le code ; c'est probablement ce que je ferais.
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  15. #15
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 17
    Points : 6
    Points
    6
    Par défaut
    Oui pas bête ! et je regarde lequel est le plus efficace.

  16. #16
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 17
    Points : 6
    Points
    6
    Par défaut
    Il n'y a pas un système de notification avec les socket autre que Socket.ready() ?
    Normalement je crois que le caractère signifiant qu'il n'y a rien à lire est -1 ?

Discussions similaires

  1. [Debian_Etch] Petits soucis de performance sur un serveur
    Par Arnulf dans le forum Administration système
    Réponses: 7
    Dernier message: 22/01/2008, 17h09
  2. Des conseils pour la performance d'un serveur firebird?
    Par _skip dans le forum Installation
    Réponses: 2
    Dernier message: 19/12/2007, 21h05
  3. Performance requete client/serveur
    Par Shiven dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 30/11/2007, 19h15
  4. Problème de performance sur un serveur
    Par vbcasimir dans le forum Administration système
    Réponses: 3
    Dernier message: 30/06/2006, 01h08
  5. Réponses: 13
    Dernier message: 21/02/2006, 23h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo