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.


0 commentaires:

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