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

API standards et tierces Java Discussion :

Pb de MultiThread Callable et JSCH


Sujet :

API standards et tierces Java

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 705
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 705
    Points : 934
    Points
    934
    Par défaut Pb de MultiThread Callable et JSCH
    Bonsoir

    J'ai un programme java qui effectue sue 30 serveurs different la commande "ls" grace à l'API JSCH. Afin d'accelerer ces traitements j'ai ajouté du Threading avec du "callable"
    Je constate que lorsque je lance le War depuis mon tomcat7 sous Windows7, cela met 3 secondes pour tous les serveurs alors que sur la machine Linux en kernel 2.6.32 cela met 30*3 secondes
    Les threads ne sont pas parallelisé,chaque commande attend la fin du précedent pour se lancer ?
    Pourquoi une difference alors que c'est le meme programme ?
    C'est du Java7/Tomcat7

    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
     
        public String sendCommandWithouthSecurityCheck(String hostname,String command,boolean forceExit) throws MyDomainException{
            publicKeyValidThrowException();        
     
            Session session = null;
            ChannelExec channel=null;        
            try(ByteArrayOutputStream outputStreamErr = new ByteArrayOutputStream()) {
                session = jsch.getSession(USER_MM, hostname);
                session.setConfig("StrictHostKeyChecking", "no");  
                session.setConfig("PreferredAuthentications","publickey,keyboard-interactive,password");//Permet de ne pas bloquer a l'attente du mot de passe de la session
                session.connect(); //NoTimeout
     
                channel= (ChannelExec)session.openChannel("exec");            
     
                channel.setInputStream(null);
                channel.setErrStream(outputStreamErr);
     
                channel.setCommand(command);
     
                channel.connect();
     
                String resultOut,resultErr;
                try (InputStream is = channel.getInputStream()) {
                    resultOut = toString(is);
                }
     
                if(outputStreamErr.size()==0){
                    resultErr = null;
                }else{
                    resultErr = outputStreamErr.toString();
                }            
     
                //il faut deconnecter le channel avant de recuperer le retour code
                channel.disconnect();
                session.disconnect();
     
                int nbRetry = 0;
                while(!channel.isClosed() && !forceExit){
                    if(nbRetry>=NB_RETRY_CLOSE){
                        throw new MyDomainRollbackException("Impossible de fermer la connexion SSH de la '" + command + "' sur l'hote " + hostname+" apres "+NB_RETRY_CLOSE+" tentatives");
                    }
                    nbRetry++;
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException ex) {
                        log.error("Timeout connexion SSH de la '" + command + "' sur l'hote " + hostname);
                        forceExit=true;
                    }
                }
     
                if(nbRetry!=0){
                    log.warn("Fermeture de la connexion SSH de la '" + command + "' sur l'hote " + hostname + "  apres " + nbRetry+" tentatives");
                }
     
                int exitStatus = channel.getExitStatus();
     
                if (exitStatus == 0) {
                    log.info("Command '" + command + "' execute sur l'hote " + hostname + " : '" + resultOut+"'");
                    return resultOut;
                } else { 
                    if(exitStatus == -1){
                        log.error("Le canal SSH n'a pas ete correctement ferme avant la recuperation du retour code de la commande '" + command + "' sur l'hote " + hostname + " (test canal ferme via API : " + channel.isClosed() +", nombre de retry : "+nbRetry+", force exit : "+forceExit+")");
                    }
                    if (resultErr == null) {
                        throw new MyCommandException("Une erreur est survenue lors de l'execution de la commande '" + command + "' sur l'hote " + hostname + " (exit code " + exitStatus + ")",exitStatus,resultErr);
                    } else {
                        throw new MyCommandException("Une erreur est survenue lors de l'execution de la commande '" + command + "' sur l'hote " + hostname + " : '" + resultErr + "' (exit code " + exitStatus + ")",exitStatus,resultErr);
                    }
                }
            } catch (JSchException | IOException ex) {
                throw new MyDomainRollbackException(ex);
            } finally {
                if (channel != null && !channel.isClosed()) {
                    channel.disconnect();
                }
                if (session != null && session.isConnected()) {
                    session.disconnect();
                }
            }
        }
     
     
    -------------
    Je n'ai pas tout mis
            ExecutorService      executor = Executors.newFixedThreadPool(NTHREDS);
            List<Future<String>> list     = new ArrayList<Future<String>>();
     
            for (int cpt = 0; cpt < max; cpt++) {
                Callable<String> worker = new MyCallableB(cpt, show, s);
                Future<String>   submit = executor.submit(worker);
     
                list.add(submit);
            }
     
        for (Future<String> future : list) {
     
                       try {
                    rt = future.get();
     
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ExecutorService      executor = Executors.newFixedThreadPool(NTHREDS);
    La première chose que je vérifierais, c'est si NTHREDS vaut 1 ou plus.

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 705
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 705
    Points : 934
    Points
    934
    Par défaut
    Bonjour

    Oui NTHREDS vaut 15

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    En serveur recette LINUX vers la base de recette
    2017-11-02 08:03:59,737 INFO [http-bio-xx.xx.x.xx-10587-exec-2] service.ApplicationRSImpl.checkAndAddAllLinks (ApplicationRSImpl.java:320) - checkAndAddAllLinks() - date Debut 2017-11-02 08:03:59, nbThread=15
    2017-11-02 08:04:01,090 INFO [pool-2-thread-9] sshj.CommandUSImpl.sendCommandWithouthSecurityCheck (CommandUSImpl.java:68) - Command 'ls -ld /tech/prod/client/TOTO' execute sur l'hote serveur01 : 'lrwxrwxrwx 1 zorro zorro 21 Sep 8 2015 /tech/prod/client/TOTO -> /tech/prod/8.0.0.2'
    2017-11-02 08:04:03,979 INFO [pool-2-thread-7] sshj.CommandUSImpl.sendCommandWithouthSecurityCheck (CommandUSImpl.java:68) - Command 'ls -ld /tech/prod/client/TOTO' execute sur l'hote serveur02 : 'lrwxrwxrwx 1 zorro zorro 21 Sep 8 2015 /tech/prod/client/TOTO -> /tech/prod/8.0.0.2'
     
     
    En serveur localhost windows tomcat7 vers la base de recette
    2017-11-02 09:05:32,484 INFO [pool-2-thread-4] sshj.CommandUSImpl.sendCommandWithouthSecurityCheck (CommandUSImpl.java:68) - Command 'ls -ld /tech/prod/client/TOTO' execute sur l'hote serveur02 : 'lrwxrwxrwx 1 zorro zorro 21 Sep 8 2015 /tech/prod/client/TOTO -> /tech/prod/8.0.0.2'
    2017-11-02 09:05:32,499 INFO [pool-2-thread-6] sshj.CommandUSImpl.sendCommandWithouthSecurityCheck (CommandUSImpl.java:68) - Command 'ls -ld /tech/prod/client/TOTO' execute sur l'hote tlszz02 : 'lrwxrwxrwx 1 zorro zorro 21 Oct 13 2015 /tech/prod/client/TOTO -> /tech/prod/8.0.0.2'
    2017-11-02 09:05:32,504 INFO [pool-2-thread-3] sshj.CommandUSImpl.sendCommandWithouthSecurityCheck (CommandUSImpl.java:68) - Command 'ls -ld /tech/prod/client/TOTO' execute sur l'hote tlszz01 : 'lrwxrwxrwx 1 zorro zorro 21 Oct 13 2015 /tech/prod/client/TOTO -> /tech/prod/8.0.0.2'
    2017-11-02 09:05:32,511 INFO [pool-2-thread-9] sshj.CommandUSImpl.sendCommandWithouthSecurityCheck (CommandUSImpl.java:68) - Command 'ls -ld /tech/prod/client/TOTO' execute sur l'hote serveurx01 : 'lrwxrwxrwx 1 zorro zorro 21 Sep 8 2015 /tech/prod/client/TOTO -> /tech/prod/8.0.0.2'
     
    depuis mon ordinateur avec le meme programme le multi-rhreading fonctionne alors que sur le serveur linux cela donne l'impression qu'on attend la fin de la commande précédente
    Je viens de faire un test simple en mode bash et le temps est correct. C'est donc lié à la configuration du tomcat7 !!

  4. #4
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Ok, il faudrait le code complet de ta classe Callable et l'output complet sous linux (pas juste la première exécution)

    ensuite, rajouter des logs à différentes étapes de l'opération (création du job, entrée dans la méthode call du callable, initialisation de la connection ssh, ...) permettrait de voir quel composant pose problème. Pas impossible que ton serveur de production aie simplement une limitation sur le nombre de session ssh autorisées en parallèle.

    Note qu'on voie clairement dans ton output que les deux commandes ssh sortent de deux threads différents, donc peu de chance que le pool soit en tord. A moins que ton Callable aie un verrou dont tu ne nous aie pas parlé.

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 705
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 705
    Points : 934
    Points
    934
    Par défaut
    Bonsoir

    Comme je le disais j'ai copié les deux classes de thread et d'envoi dans un jar a part que j'ai lancé depuis le même serveur LINUX ou se trouve mon projet et la les temps de réponses sont très correct !
    J'ai demandé l'ouverture des ports JMX sur la machine de "recette" qui à les même symptômes afin de voir si le projet complet ne "mange" pas la mémoire ce qui expliquerait pourquoi mon tomcat local lie à eclipse fonctionne bien.

    je vous met le code demain

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 705
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 705
    Points : 934
    Points
    934
    Par défaut
    Bonsoir

    JMX me donne effectivement du LOCK de THREAD uniquement sur le tomcat de la machine LINUX/REDHAT avec le JDK 1.7.51
    at net.schmizz.sshj.transport.random.SingletonRandomFactory.<init>(SingletonRandomFactory.java

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    "pool-2-thread-14" - Thread t@84
       java.lang.Thread.State: BLOCKED
                    at sun.security.provider.NativePRNG$RandomIO.implGenerateSeed(NativePRNG.java:218)
                    - waiting to lock <58e758ca> (a java.lang.Object) owned by "pool-2-thread-9" t@79
                    at sun.security.provider.NativePRNG$RandomIO.access$300(NativePRNG.java:125)
                    at sun.security.provider.NativePRNG.engineGenerateSeed(NativePRNG.java:119)
                    at java.security.SecureRandom.generateSeed(SecureRandom.java:517)
                    at net.schmizz.sshj.transport.random.BouncyCastleRandom.<init>(BouncyCastleRandom.java:44)
                    at net.schmizz.sshj.transport.random.BouncyCastleRandom$Factory.create(BouncyCastleRandom.java:36)
                    at net.schmizz.sshj.transport.random.BouncyCastleRandom$Factory.create(BouncyCastleRandom.java:31)
                    at net.schmizz.sshj.transport.random.SingletonRandomFactory.<init>(SingletonRandomFactory.java:27)
                    at net.schmizz.sshj.DefaultConfig.initRandomFactory(DefaultConfig.java:117)
                    at net.schmizz.sshj.DefaultConfig.<init>(DefaultConfig.java:93)
    java.security.properties=/share/scripts/etc/java.security ne contient pas de ligne securerandom.source=file:/dev/urandom

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 705
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 705
    Points : 934
    Points
    934
    Par défaut
    La solution etait dans le demarrage de Tomcat
    JAVA_OPTIONS=" -Djava.security.egd=file:/dev/./urandom"

  8. #8
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Bien vu

    attention que urandom est moins sur que random

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 705
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 705
    Points : 934
    Points
    934
    Par défaut
    Oui, mais mon appli Web est une appli interne qui sert à la gestion de l'infrastructure technique interne basé sur MQ-SERIES
    Merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 18/02/2009, 17h40
  2. [WinAPI C++] MultiThreading et PostMessage
    Par Gruik dans le forum Windows
    Réponses: 7
    Dernier message: 29/03/2004, 15h58
  3. [WinAPI C++] MultiThreading?
    Par Gruik dans le forum Windows
    Réponses: 2
    Dernier message: 25/03/2004, 00h08
  4. [Win32]App multithread
    Par billyboy dans le forum Windows
    Réponses: 5
    Dernier message: 25/09/2003, 09h57
  5. Multithreading sous HP Ux 11
    Par pykoon dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 18/10/2002, 23h36

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