jeudi 8 avril 2010




SIMULATION GEL THREADS

Pour simuler les contentions d’instance ou de threads, plusieurs méthodes sont envisageables :

PROCESSUS

Pour figer une instance on utiliser la commande système suivante :

figeage
kill -STOP <PID>

liberation
kill - CONT <PID>

THREAD

On peut simuler une attente d’un Thread via la méthode sleep. On aboutit à un Thread dit Stuck. Lors de l’apparition de Stuck, l’instance se met dans un état Warning

figeage
Thread.sleep();

Libération au bout du temps indiqué

On pourra voir dans la console Weblogic les informations suivantes.




Le monitoring pourra nous indiquer le nombre de threads en contention.


Avec des informations dans les logs sur la nature de la contention.

<7 avr. 2010 20 h 41 CEST> <[STUCK] ExecuteThread: '17' for queue: 'weblogic.kernel.Default (self-tuning)' has been busy for "126" second
s working on the request "weblogic.servlet.internal.ServletRequestImpl@8951bd[
GET /TroubleShooting/Freez HTTP/1.1
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.1.249.1045 Safari/532.5
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Encoding: gzip,deflate,sdch
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: JSESSIONID=RvpbL8MTt8n2LqrMPpXJwYSC8G8vnQVpFj47bGVQ1kqzK1DXMn8m!-1289727609; ADMINCONSOLESESSION=Mr66L8Qpp2hc1wnQ90XJbqTWCYXh3pDmLq1t2NSTvks5yLH1LPsh!1363685680

]", which is more than the configured time (StuckThreadMaxTime) of "60" seconds. Stack trace:
Thread-48 "[STUCK] ExecuteThread: '17' for queue: 'weblogic.kernel.Default (self-tuning)'" {
    java.lang.Thread.sleep(Thread.java:???)
    jsp_servlet.__freez._jspService(__freez.java:61)
    weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
    weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:224)
    weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:108)
    weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:198)
    weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
    weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3564)
    weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:308)
    weblogic.security.service.SecurityManager.runAs(SecurityManager.java:117)
    weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2138)
    weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2060)
    weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1399)
    weblogic.work.ExecuteThread.execute(ExecuteThread.java:198)
    weblogic.work.ExecuteThread.run(ExecuteThread.java:165)
}

TABLE

Pour la DataBase on utiliser la commande SQL suivant pour locker une table :

figeage
lock table
in exclusive mode

liberation
rollback


DEAD LOCK

Un Dead lock JAVA est un inter blocage entre deux activations parallèles JAVA (ou autre) qui ne peuvent se libérer (l’un attendant l’autre). Cette situation entraine sur Weblogic un statut FAILED qui rend indisponible l’instance (à la 1er occurrence d’un dead lock). Il suffit donc d’avoir un scénario avec un seul requêtage en inter blocage pour bloquer une plate-forme (malgré la disponibilité d’autres threads).

La seule solution et la correction du code JAVA. Pour simuler ce type de problème, vous pouvez utiliser le code ci-dessous à intégrer dans un WAR.

Servlet d’appel du code qui simule le lock:

DeadLockServlet.java
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class DeadLockServlet
 */
public class DeadLockServlet extends HttpServlet {
      
       private static final long serialVersionUID = 1L;

    /**
     * Default constructor.
     */
    public DeadLockServlet() {
        // TODO Auto-generated constructor stub
    }

       /**
        * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
        */
       protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
             doService(request, response);
       }

       /**
        * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
        */
       protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
             doService(request, response);
       }
      
       protected void doService(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

             Deadlock.doIt();
       }

}

Présenter ci-dessous une classe qui simule le lock. Il faudra itérer plusieurs fois ce code pour obtenir un dead lock.

Deadlock.java
public class Deadlock extends Object {
      
  private String objID;

  public Deadlock(String id) { objID = id; }

  public synchronized void checkOther(Deadlock other) {
        
    print("entering checkOther()");

    try { Thread.sleep(2000);
    } catch (InterruptedException x) { x.printStackTrace(); }

    print("invoke 'other.action()'");
    other.action();

    print("leaving checkOther()");
  }

  public synchronized void action() {
        
    print("entering action()");

    // simulate some work here
    try {  Thread.sleep(500);
    } catch (InterruptedException x) { x.printStackTrace(); }

    print("leaving action()");
  }

  public void print(String msg) { threadPrint("objID=" + objID + " - " + msg); }

  public static void threadPrint(String msg) {
        
    String threadName = Thread.currentThread().getName();
    System.out.println(threadName + ": " + msg);
  }

       // public static void main(String[] args) {
  public static void doIt() {

             final Deadlock obj1 = new Deadlock("Thread 1");
             final Deadlock obj2 = new Deadlock("Thread 2");

             Runnable runA = new Runnable() {

                    public void run() {
                           obj1.checkOther(obj2);
                    }
             };

    Thread thread = new Thread(runA, "A");
    thread.start();

    try { Thread.sleep(200);
    } catch (InterruptedException x) { x.printStackTrace(); }

    Runnable runB = new Runnable() {
      
      public void run() { obj2.checkOther(obj1); }
    };

    Thread threadB = new Thread(runB, "B");
    threadB.start();

    try { Thread.sleep(5000);
    } catch (InterruptedException x) { x.printStackTrace(); }

    threadPrint("finished sleeping");

    threadPrint("about to interrupt() threadA");
    thread.interrupt();

    try { Thread.sleep(1000);
    } catch (InterruptedException x) { x.printStackTrace(); }

    threadPrint("about to interrupt() threadB");
    threadB.interrupt();

    try { Thread.sleep(1000);
    } catch (InterruptedException x) { x.printStackTrace(); }

    threadPrint("did that break the deadlock?");
  }
}

L’exemple de trace que l’on pourra avoir dans les logs Weblogic lors de l’apparition du dead lock.

<7 avr. 2010 21 h 05 CEST> <

DEADLOCK DETECTED:
==================

[deadlocked thread] A:
---------------------
Thread 'A' is waiting to acquire lock 'Deadlock@339cb8' that is held by thread 'B'

Stack trace:
------------
        Deadlock.action(Deadlock.java:24)
        Deadlock.checkOther(Deadlock.java:17)
        Deadlock$1.run(Deadlock.java:50)
        java.lang.Thread.run(Thread.java:619)

[deadlocked thread] B:
---------------------
Thread 'B' is waiting to acquire lock 'Deadlock@339cb6' that is held by thread 'A'

Stack trace:
------------
        Deadlock.action(Deadlock.java:24)
        Deadlock.checkOther(Deadlock.java:17)
        Deadlock$2.run(Deadlock.java:62)
        java.lang.Thread.run(Thread.java:619)

[deadlocked thread] A:
---------------------
Thread 'A' is waiting to acquire lock 'Deadlock@33eb7c' that is held by thread 'B'

Stack trace:
------------
        Deadlock.action(Deadlock.java:24)
        Deadlock.checkOther(Deadlock.java:17)
        Deadlock$1.run(Deadlock.java:50)
        java.lang.Thread.run(Thread.java:619)

[deadlocked thread] B:
---------------------
Thread 'B' is waiting to acquire lock 'Deadlock@33eb7a' that is held by thread 'A'

Stack trace:
------------
        Deadlock.action(Deadlock.java:24)
        Deadlock.checkOther(Deadlock.java:17)
        Deadlock$2.run(Deadlock.java:62)
        java.lang.Thread.run(Thread.java:619)

Avec comme status de l’instance Failed interdisant tout requêtage.



FUITE CONNEXION JDBC

Une fuite de connexion d’un pool JDBC est causée par un code JAVA faisant appel au pool pour une connexion à la DataBase sans jamais la remettre dans le pool. La conséquence est l’aboutissement à un pool vide avec des échecs de requêtage sur une ressource Exception.

Pour simuler ce type de défaillance, il suffit de commenter la partie libération du code et rejouer le scénario autant de fois qu’il y a de connexion dans le pool JDBC pour aboutir à la fuite.

Exemple de code java défaillant
      try {
           
            Context ic;
            ic = new InitialContext();
     
            DataSource dataSource = (DataSource) ic.lookup(datasource);
            Connection connection = dataSource.getConnection();

            Statement statement = connection.createStatement();             
            result = statement.execute(query);
           
            statement.close();
            // connection.close();

      } catch ( Exception e) { e.printStackTrace(); }     

Métrique du pool en fuite

Exception générée sur une fuite après épuisement du pool.
<7 avr. 2010 19 h 52 CEST>
ppApplicationOverviewPage&WebAppApplicationOverviewPortlethandle=com.bea.console.handles.AppDeploymentHandle%28%22com.bea%3AName%3DTroubleShooting%2CType%3DAppDeployment%22%29
.>
java.sql.SQLException: Internal error: Cannot obtain XAConnection weblogic.common.resourcepool.ResourceLimitException: No resources currently available in pool XE to allocate
to applications, please increase the size of the pool and retry..
        at weblogic.common.resourcepool.ResourcePoolImpl.reserveResourceInternal(ResourcePoolImpl.java:559)
        at weblogic.common.resourcepool.ResourcePoolImpl.reserveResource(ResourcePoolImpl.java:332)
        at weblogic.common.resourcepool.ResourcePoolImpl.reserveResource(ResourcePoolImpl.java:322)
        at weblogic.jdbc.common.internal.ConnectionPool.reserve(ConnectionPool.java:431)
        at weblogic.jdbc.common.internal.ConnectionPool.reserve(ConnectionPool.java:316)
        at weblogic.jdbc.common.internal.ConnectionPoolManager.reserve(ConnectionPoolManager.java:93)
        at weblogic.jdbc.common.internal.ConnectionPoolManager.reserve(ConnectionPoolManager.java:61)
        at weblogic.jdbc.jta.DataSource.getXAConnectionFromPool(DataSource.java:1584)
        at weblogic.jdbc.jta.DataSource.refreshXAConnAndEnlist(DataSource.java:1387)
        at weblogic.jdbc.jta.DataSource.getConnection(DataSource.java:438)
        at weblogic.jdbc.jta.DataSource.connect(DataSource.java:395)
        at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:355)
        at jsp_servlet.__connectionleak._jspService(__connectionleak.java:107)
        at weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
        at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
        at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3594)
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
        at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
        at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2202)
        at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2108)
        at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1432)
        at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)

        at weblogic.jdbc.jta.DataSource.refreshXAConnAndEnlist(DataSource.java:1396)
        at weblogic.jdbc.jta.DataSource.getConnection(DataSource.java:438)
        at weblogic.jdbc.jta.DataSource.connect(DataSource.java:395)
        at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:355)
        at jsp_servlet.__connectionleak._jspService(__connectionleak.java:107)
        at weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
        at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
        at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3594)
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
        at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
        at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2202)
        at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2108)
        at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1432)
        at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)


FUITE MEMOIRE

Une fuite mémoire correspond à un code JAVA qui crée des objets sans jamais les relâcher. Les objets générés étant maintenus par le père défaillant, ils ne sont jamais libérés par les GC.

Pour simuler ce type de comportement, on peut utiliser les sessions Servlet qui stocke les données utilisateur en mémoire le temps de maintien de la session. En gonflant anormalement ces objets, on peut aboutir à une contention mémoire.

Code qui remplit la session de données
      String size = this.getServletConfig().getServletContext().getInitParameter("size");

      byte[] inBytes=new byte[size];
     
       for (int i=0;i
       
             inBytes[i]='A';       
     
       Deflater deflater=new Deflater();
       deflater.setInput(inBytes, 0, inBytes.length);
       deflater.finish();
       byte[] outBytes=new byte[deflater.getTotalOut()];
       deflater.deflate(outBytes);
       
      session = request.getSession(true);
     
        Integer ival = (Integer)session.getAttribute("simplesession.counter");
        if (ival == null)
          ival = new Integer(1);
        else
          ival = new Integer(ival.intValue() + 1);
         
      String sesssionName =  "OutOfMemory" + ival;
            session.setAttribute("simplesession.counter",ival);
      session.setAttribute(sesssionName, deflater);       


 Exception générée sur le manque de ressource mémoire.
<7 avr. 2010 20 h 19 CEST> <[ServletContext@28362368[app:TroubleShooting module:TroubleShooting path:/TroubleShooting spec-version:null]] Root caus
e of ServletException.
java.lang.OutOfMemoryError: allocLargeObjectOrArray - Object size: 10000016, Num elements: 10000000
        at jsp_servlet.__outofmemory._jspService(__outofmemory.java:81)
        at weblogic.servlet.jsp.JspBase.service(JspBase.java:35)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
        at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
        Truncated. see log file for complete stacktrace
> 

Via l’outil memory leak de Jrockit on pourra analyser l’origine de la fuite mémoire.




OUTIL DE SIMULATION

Vous pouvez utiliser la WebApplication TroubleShooting.war pour simuler ces différentes défaillance et observer le comportement de la plate-forme.



Pour détecter des contentions de Threads on peut utiliser l’option Weblogic StuckThreadMaxTime. Cette option permet de définir un temps au bout duquel on considère qu’un thread a pris trop de temps pour s’exécuter.

Un thread peut prendre du temps pour deux raisons :

ü  Soit, il exécute un code trop long (boucle, etc … ) consommateur de CPU.
ü  Soit, il attend une réponse d’un composant externe au thread (un lock d’un autre thread ou une ressource distante).

La seule façon d’investiguer sur ces problèmes est d’en être informé et d’avoir des informations à analyser.

PARAMETRAGE

Le paramétrage se fait via la console Weblogic ou un scripte WLST sur chaque instance.

Consoleà${domaine}àEnvironmentàServersà${instance}àConfigurationàTuning


Stuck Thread Max Time
Le temps au bout duquel on considère que le thread prend trop de temps.
Stuck Thread Timer Interval
L’intervalle de temps pour vérifier que les threads n’ont pas dépassé le temps indiqué dans le 1er paramétré.

Le paramétrage par défaut est de 10 minutes. Pour fixer le temps au bout duquel on considère qu’une requête prend trop de temps, on peut prendre le scénario le plus long et doubler ce temps comme seuil d’alerte.

ALERTE

Pour être alerté sur des Stuck, on pourra monitorer les MBean des WorkManager des applications pour relever le nombre de thread en blocage.

WorkManagerRuntime : com.bea:ServerRuntime=${server},Name=${name},ApplicationRuntime=${ressource name},Type=WorkManagerRuntime
Attribut : StuckThreadCount

ANALYSE

Weblogic détecte les Thread Stuck et le notifie dans son log en indiquant le temps de blocage, l’URL responsable et le code JAVA en cours d’exécution. L’analyse étant de décrypter la stack JAVA.

Exemple d’un log Weblogic sur un StuckThread
####<23 juil. 2009 03 h 14 VET> <[ACTIVE] ExecuteThread: '72' for queue: 'weblogic.kernel.Default (self-tuning)'> <> <> <> <1248335056672> <[STUCK] ExecuteThread: '64' for queue: 'weblogic.kernel.Default (self-tuning)' has been busy for "44" seconds working on the request "weblogic.servlet.internal.ServletRequestImpl@b5839e[
GET /TestFreez/Freez.jsp HTTP/1.1
Accept: */*
Referer: http://localhost:7001/console/console.portal?_nfpb=true&_pageLabel=WebAppApplicationTestingPage&handle=com.bea.console.handles.AppDeploymentHandle%28%22com.bea%3AName%3DTestFreez%2CType%3DAppDeployment%22%29
Accept-Language: fr
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648)
Connection: Keep-Alive

]", which is more than the configured time (StuckThreadMaxTime) of "30" seconds. Stack trace:
Thread-79 "[STUCK] ExecuteThread: '64' for queue: 'weblogic.kernel.Default (self-tuning)'" {
    java.lang.Thread.sleep(Thread.java:???)
    jsp_servlet.__freez._jspService(__freez.java:61)
    weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
    weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:224)
    weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:108)
    weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:198)
    weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
    weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3468)
    weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:308)
    weblogic.security.service.SecurityManager.runAs(Unknown Source)
    weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2116)
    weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2038)
    weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1372)
    weblogic.work.ExecuteThread.execute(ExecuteThread.java:198)
    weblogic.work.ExecuteThread.run(ExecuteThread.java:165)
}

> 

CORRECTION

On ne peut pas libérer le thread en blocage (interdit par la JVM et le serveur d’applications). La seule solution et de supprimer la cause du blocage ou d’établir un timeout avec retour d’exception en aval. La raison du blocage peut-être :

ü  Une contention de la ressource externe (un lock de base, une ressource distante en difficulté).
ü  Une défaillance du code.

mercredi 7 avril 2010


L’industrialisation de plate-forme passe par une définition d’architecture type (cluster ou non, n tiers, etc … ) et de composant d’infrastructure (Cache Objet, Framework infrastructure [Log4J, etc …] / Framework Composant [Portal, etc …] ) a intégré dans des socles de version associée à du scripting d’installation et de maintenance.


L’objectif étant de définir un contrat normalisé entre les différents acteurs des projets sur la solution mise en place. Cela passe par :

ü  Mise en place de bonne pratique d’utilisation des composants.
ü  Packaging et paramétrage exploitable dans tous les environnements.
ü  Validation en bench sur des composants déjà référencés.
ü  Automatisation des mises en place et exploitation des solutions.
ü  Monitoring outillage et gestion des trouble shooting maitrisés par l’ensemble des acteurs.

DEFINITION

Afin de normaliser la plate-forme, il faut définir une architecture type quelque soit l’application déployée et les besoins de cette application. Cela passe forcément par un frontal HTTP qui a pour rôle de répartir la charge si besoin sur le domaine WLS et d’héberger les pages statiques de l’application (meilleure réparation de charge).

Le paramétrage des ressources en amont et en aval du domaine doit être transparent sur la mise en place de redondance ou de répartition de charge afin de conserver la neutralité de la plate-forme Weblogic (Oracle RAC, LDAP réparti).


Le domaine peut héberger n instances réparties sur m clusters (ou non) déployant une ou plusieurs applications divisées en x tiers d’architecture (Frontal Web ou WS/Couche métier EJB).


La répartition des applications et instances sur les machines et la façon de déployer l’architecture va impacter l’industrialisation de la plate-forme. Il faut pour cela que les applications déployées puissent se conformer aux contraintes de la plate-forme et puissent être sectorisées suivant différents critères afin d’appliquer une règle de déploiement:

Recommandation de développement :

ü  Pages statiques séparées pour déploiement sur le frontal HTTP.
ü  Sérialisation des objets mises en session et déclaration des primitifs clusters dans les descripteurs J2EE.
ü  Définition de timeout sur les flux sortant avec un paramétrage externe pour éviter les contentions.
ü  Utilisation des framework référencés en suivant les recommandations (d’implémentation et de paramétrage).
ü  Packaging unique (EAR normé)
ü  Paramétrage applicatif prenant en compte le multi-instance (properties par instance, etc … )

Composants utilisés :

ü  JMS
ü  LDAP
ü  JDBC
ü  EJB
ü  WS
ü  Type de framework

Typage de l’application :

ü  Criticité                     (important, mineur)
ü  Charge                      (traitement lourd, batch, passe-plat, métier)
ü  Audience                   (internet, intranet, utilisation sur plage horaire, (fréquentation)
ü  Mutualisation            (des composants)
ü  Accès                        (aux mêmes types de ressource)
ü  Type                          (banque/assurance)

Il faut également avoir une souplesse de déploiement des instances afin de mieux gérer les charges induites et donc d’être renseigné sur ceux-ci (monitoring). Dans le cadre d’une mutualisation, on doit prendre en compte le compartimentage des ressources pour gérer les criticistes (mémoire/CPU-Threads/pool).

La répartition des instances sur les machines physiques doit suivre des règles de base afin d’éviter les engorgements de ressource (thread CPU, mémoire, disque)

ü  Ne pas dépasser 70% d’occupation mémoire pour les instances
ü  Ne déployer que des instances WLS sur la machine pour ne pas polluer la consommation des ressources.
ü  Déployer les instances d’administration sur des machines dédiées.
ü  Essayer de dissocier les ‘file system’.
ü  Virtualiser pour compartimenter la ressource CPU

UNE ARCHITECTURE TYPE

La définition d’un type d’architecture et d’application doit amener à une règle d’aiguillage afin de déployer le projet sur le bon environnement (grille de contrainte). Ce typage doit donner lieu à une normalisation de déploiement, d’utilisation des ressources et d’administration de plate-forme industrialisés.

Les besoins d’un projet peuvent être multiples et impactant sur la plate-forme Weblogic à déployer suivant différent critères de criticiste ou d’utilisation de ressources. Il faut donc définir plusieurs types d’architecture Weblogic mettant en place un certain nombre de ressource et de fonctionnalités pour ensuite fournir les éléments d’industrialisation nécessaire a chaque spécificité d’environnement.

Les considérations d’architecture Weblogic sont à plusieurs niveaux de contraintes :

ü  Utilisation d’un cluster ou non et répartition des instances dans le domaine.
ü  Déclaration et utilisation des ressources utilisées par l’infrastructure.
ü  Utilisation de framework ou non (ressource spécifique à déployer et administrer).
ü  Mode de déploiement des projets (contraintes spécifiques).

CLUSTER : Pour les projets critiques, il est souhaitable de définir une architecture redondée via les clusters. Le cluster regroupant les notions de :

ü Failover                 (reprendre les données utilisateur en cas de crash)
ü LoadBalancing       (répartition de la charge sur plusieurs ressources (instance/CPU/mémoire))
ü Scalability           (étendre les ressources en cas d’un accroissement de charge)

Pour l’utilisation de certaines ressources comme JMS ou EJB, framework, il est fortement recommandé, voir nécessaire d’utilisé le cluster Weblogic afin de rendre les ressources accessibles quelque soit le nœud du cluster utilisé (vue unique de la ressource)

L’impact d’un cluster Weblogic concerne la mise en place de l’environnement le paramétrage et le déploiement des ressources.

NON CLUSTER : Dans le cas où le cluster n’est pas nécessaire, on conservera cette notion de multiinstance pour garantir un service 24/7. Nous n’aurons plus que la notion de failover. Le loadbalancing sera toujours assuré par le frontal HTTP, mais de façon statique. Ce type d’architecture ne pourra donc pas héberger d’application utilisant JMS (ou EJB).

FRAMEWORK: Pour les applications utilisant un framework, il faudra déclarer des domaines spécifiques déclarants les ressources associées (domaine spécifique avec pré paramétrage de ressource et d’application). Il est préférable d’utiliser ces domaines en mode cluster, car mettant en jeux des mécanismes type JMS et Singleton Service.

DEPLOIEMENT : Le mode de déploiement peut également impacter sur l’architecture à mettre en place. Certaines applications ne supportant pas le déploiement multi-instance ou un déploiement de plusieurs applications sur une même instance (pour des raisons de paramétrage ou de déploiement générique). On peut ainsi dégager trois types de contraintes de déploiement :

ü Déploiement mono-instance Œ                (une seule instance sur le domaine)
ü Déploiement multi-instance exclusif Ž    (plusieurs instances, mais une application par instance)
ü Déploiement multi-instance inclusif      (pas de dépendance, possibilité de cohabitation)















FRAMEWORK INSFRASTRUCTURE : Certaines applications peuvent nécessiter des composants d’infrastructure spécifique positionnés dans le domaine et communs à toutes les instances. Cela créer donc une dépendance par rapport au domaine (Coherence, Log4J, etc …). Il faudra donc regrouper ces applications sur ces domaines spécifiques afin d’éviter des impactes non maitriser sur le déploiement et l’exécution des projets (problèmes de CLASSPATH ou ressources en conflits).

SPECIFIQUE : certaines applications nécessitent des environnements devant respecter des contraintes métier (bancaire/assurance). Le mélange de ces types d’application ne peut donc pas se faire sous peine d’assumer la charge d’un environnement qui n’a pas lieu d’être (normalisation de paramétrage, contrainte de sécurité, indisponibilité de plate-forme liée à des changements, mise en place de composant incompatible)

COMPARTIMENTE : dans le cas de déploiement mutualisé, les ressources sont partagées entre plusieurs applications (certaines applications étant plus prioritaires que d’autre). Toutes les applications sont  consommatrice de ressource par rapport à une complexité de code ou à un requêtage spécifique (variable ou non dans le temps). Dans le cadre de cette cohabitation d’espace et de temps, il est nécessaire de mettre en place des mécanismes de partitionnement variable afin d’étanchéifier les contextes applicatifs sur la consommation des ressources. Ces mécanismes doivent donc être pris en compte dans l’architecture mise en place.

TYPAGE D’APPLICATION

Plusieurs critères peuvent caractériser une application, et ainsi définir son type de domaine de déploiement. Ces critères sont les suivants :

DEPLOIEMENT : Les applications peuvent avoir des contraintes de déploiements (mono/multi instance, exclusif/inclusif). Il faut donc spécifier le type de déploiement nécessaire.

TYPE : Une application est spécifique par rapport à son domaine (banque/assurance).

CRITICITE : Elle peut être critique ou non.

CHARGE RESSOURCE : Elle peut consommer fortement les ressources par complexité de code ou par charge induite.

FRAMEWORK:  Elle peut utiliser un framework avec des ressources spécifiques.

FRAMEWORK INFRASTRUCTURE : Elle peut utiliser des ressources d’infrastructure à déclarer spécifiquement dans l’environnement BEA (en dehors de tout packaging)

RESSOURCE JMS/EJB : Utilisation de ressources JMS/EJB



Pour monitorer les métriques des instances, on a la possibilité d’activer une extension de la console d’administration.

En Weblogic 10.3.3, vous pouvez avoir accès directement via la console :





En Weblogic de version inférieure, vous devez copier un JAR issu du répertoire de l’installation de Weblogic, de le copier dans le domaine et de redémarrer l’instance d’administration.

cp ${WL_HOME}/server/lib/console-ext/diagnostics-console-extension.jar ${DOMAIN_HOME}/ console-ext/





Cette console permet de visualiser des données MBean server collecté depuis WLDF. Elle offre une vue du domaine complet avec un client riche basé sur SWING. Elle offre un framework pluggable de customisation et supporte le :

ü  Drag-n-Drop.
ü  Customisation des vues.
ü  Graphiques.
ü  Jauges


AUTEUR

Ma photo
Carrières Sur Sein, Yvelines, France
Consultant Oracle (Ancien consultant BEA depuis 2001), je m’occupe des expertises sur les produits Oracle : SOCLE (Weblogic, Coherence, JRockit) SOA (Service Bus, SOA Suite, BPM)
MON CV

LABEL 3D

Blogumulus by Roy Tanck and Amanda Fazani

LABEL CLOUD

MAP

Locations of visitors to this page

AUTRES BLOG

LIVRES

MEMBRES