Affichage des articles dont le libellé est WORKMANAGER. Afficher tous les articles
Affichage des articles dont le libellé est WORKMANAGER. Afficher tous les articles
mercredi 17 juillet 2013
 
Pour OSB, la gestion de thread dépend des artefacts déployés. Par nature, le Proxy/Business Service fonctionne avec des threads séparés (Inbound/Outbound Request Message Thread) pour dissocier le traitement de la requête de la réponse.
 
 
Dans certains cas la requête attend la réponse (même thread d’exécution). L’exécution sur un seul thread peut provenir :
 
  • D’un transport bloquant (blocking transport).
  • D’un Proxy faisant partie d’une transaction globale.
 
Transports Bloquant
 
 
Dans le cas de Proxy/Business Service, vous pouvez déclarer un WorkManager spécifique et côté Business Service vous pouvez utiliser le Throttling (mécanisme de file mémoire de régulation).
 
Le Proxy Service et Business service (ou Nested Proxy) s’exécute dans le même thread d’exécution, et l’association d’un WorkManager associé à un Proxy ou Business correspond a une affectation sur le thread request ou response côté Inbound ou Outbound (a l’extérieure d’OSB). Le throtlling lui s’applique en interne d’OSB (thread activé).
 
(dans le cas d’un Business Service, le WorkManager ne s’applique que sur la reponse)
 
Dans le cas du WorkManager, pour remonter une erreur dans le cas d’empilement d’appels en blocage externe, vous pouvez utiliser une contrainte. Dans le cas du throttling, l’expiration des requêtes entraine une erreur côté client. Vous pouvez également mettre en place une désactivation automatique des artefacts selon un SLA comme présentée dans ce blog (non-natif au produit) :
 
INBOUND

 
Au sein des messages flow des Proxy Service, vous pouvez définir des appels de service de façons différentes impliquant une gestion de thread particulière pour chaque cas.
 
  • Publish invocation asynchrone (one way) sans attendre la réponse dans le message flow.
  • Callout Invocation multiple synchrone de service dans le message flow.
  • Routing Invocation synchrone ou asynchrone d’un simple business Service en fin de message flow.
 
 
La gestion des threads est utilisée différemment selon les cas sachant que le mode Publish est asynchrone est donc n’attend pas de notification retour du service distant.
 
ROUTING
 
Dans le cas du Routing synchrone (ou publish synchone avec QoS=ExactlyOnce), ce n’est pas un seul thread, mais deux (Request/Response en thread dissocié) qui supporte l’activation du message flow (sauf dans le cas d’une transaction globale déclarée côté client (XAConnectionFactory) et le Proxy en transaction (QoS=ExactlyOnce).
 
La notification retour est déclenchée via le Muxer Weblogic (WLS AsyncResponseHandler callback) qui active un autre thread sur le message flow retour du Proxy Service. De cette façon, le thread Request ne reste pas bloqué sur l’attente de la réponse retour.
 
CALLOUT
 
Dans le cas du Callout, la requête synchrone (Request/Response) est gérée par un seul thread, mais le retour est déclenché par un autre thread de notification activé par le même mécanisme Muxer que le Routing. Il y a donc toujours 2 threads utilisés, mais le Callout n’est supporté que par un seul Thread.
 
PROXY CHAINING
 
Dans le cas où un Proxy Service appel un autre Proxy Service, l’ensemble de l’appel s’exécute sur un même thread d’exécution (Thread Request/Thread Response).
 
WORKMANAGER
 
OSB permet d’associer un WorkManager à un Proxy et Business Service. L’intérêt étant de modifier les contraintes pour déclarer un minimum de thread afin d’éviter les inters blocage lié au mode de threading de l’appel ou un maximum afin d’éviter des saturations de service. On pourrait ainsi définir certains cas d’usage ou règles à appliquer lors de constatations de contention:
 
  • Définir un MinThreadConstraint à 3 ou 5 thread sur un Proxy Service dans le cas où l’on a plusieurs Callout afin de ne pas attendre sur le thread de notification. Même remarque entre inter appel de Proxy Service sur une même instance Weblogic.
  • On pourra utiliser un MaxThreadConstraint pour tuner un Proxy type MDB afin de gérer le throughput de dépilement ou borner les appels d’un service impliqué dans le Proxy.
  • Eviter d’utiliser un même WorkManager pour un Proxy Service et un Business Service dépendant (inter blocage).
 
OUTBOUND

 
Les Outbound (appels sortants) peuvent être régulés par le WorkManager mais également par un mécanisme de file mémoire interne à OSB (Throttling). On pourra dans ce cas définir pour chaque Business une contrainte de requêtage request spécifique.
 
L’intérêt étant de ne pas devoir déclaré autant de WorkManager et de contrainte Max que de Proxy sachant que les contraintes étant globales et que l’affectation d’un WorkManager sur les flux sortants s’applique sur les Proxy (responsable des thread request).
mercredi 13 février 2013

PRINCIPE



La notion de WorkManager permet de gérer la distribution des threads sur le requetâge d’une ressource ou d’une application. Le pool de thread est unique pour l’instance Weblogic et le WorkManager régule la demande de thread sur ce pool fonction de contraintes et politiques.


Afin de monitorer l’allocation de ces threads, il est primordial de tracer l’évolution des métriques du pool de thread et des WorkManager associées aux applications. Il faut cependant connaitre les métriques à capturer et comprendre leur signification. Une petite application test a été développée pour l’occasion afin de découvrir le comportement du WorkManager et de ces métriques associées.

DOMAINE



Un domaine mono instance a été utilisé pour déployer l’application et le client requête cette instance unique pour simuler la charge. Un WorkManager de nom test_workmanager a été déployé sur l’instance avec une contrainte Max.

Lorsque le client requête l’application, celui-ci fait appel au test_workmanager pour récupérer des threads et exécuter la requête client.


MONITORING



Lors des tests, nous allons monitorer les types suivants :

com.bea:ServerRuntime=AdminServer,Name=ThreadPoolRuntime,Type=ThreadPoolRuntime
PendingUserRequestCount
The number of pending user requests in the priority queue. The priority queue contains requests from internal subsystems and users. This is just the count of all user requests.

com.bea:ServerRuntime=AdminServer,Name=test_workmanager,ApplicationRuntime=
Worker,Type=WorkManagerRuntime
PendingRequests
The number of waiting requests in the queue.


com.bea:ServerRuntime=${server},Name=MaxThreadsConstraint-3,Type=MaxThreadsConstraintRuntime
DeferredRequests
Number of requests that are denied a thread for execution because the constraint is exceeded.
ExecutingRequests
Number of requests that are currently executing.

Synthèse
ThreadPoolRuntime=PendingUserRequestCount,QueueLength
WorkManagerRuntime=PendingRequests
MaxThreadsConstraintRuntime=DeferredRequests,ExecutingRequests

MONITORING



Nous allons réaliser des charges successives de 1 à 5 clients simultanés qui appel l’application associé au WorkManager de nom test_workmanager. Ce WorkManager est paramétré avec une contrainte Max à 3 threads.

Nous allons monitorer les paramètres pending sur le pool de thread et sur le WorkManager, ainsi que sur le Mbean de la contrainte du WorkManager.

Le paramètre de Worker et la valeur retournée du singleton de l’application qui nous indique le nombre de requêtes simultané en cours d’exécution.



Flowchart: Alternate Process: 1Sur un test a 1 client, nous pouvons observer que le paramètre Pending du WorkManager représente le nombre de threads en cours d’exécution, et non pas en attente comme nous l’indique la documentation (The number of waiting requests in the queue).
                                                               
Flowchart: Alternate Process: 2Au fur et à mesure que l’on augmente le nombre de clients, le nombre de Worker augmente proportionnellement jusqu’à la valeur maximum définie dans la contrainte.

Flowchart: Alternate Process: 3Arrivés à 4, nous constatons que la métrique Pending du pool de thread augmente. Ce qui correspond bien à des requêtes en attente d’un Threads.

Flowchart: Alternate Process: 4Si le WorkManager ne nous permet pas de dissocier le nombre de requêtes en attente du nombre de requête en cours, le Mbean de la contrainte associée nous permet de faire le distinguo.

TEST MULTI APPLICATION



Ajoutons une 2 e application associée au même WorkManager, avec une deuxième charge client de nom bis. Dans ce cas de figure, nous doublons le nombre de requête sur le WorkManager.

En regard des chiffres ci-dessous, nous pouvons constater que les paramètres attribués au WorkMager sont globalisé sur l’ensemble des applications associées. La contrainte d’un Max à 3 est appliquée sur la somme des requêtes de 2 EJB associé au WorkManager.








mercredi 20 juin 2012

L’objectif de CommonJ est de proposer une interface de développement pour effectuer des traitements en parallèle dans un contexte JEE. Traditionnellement, pour réaliser des traitements en parallèle, il faut créer des Threads distincts pour exécuter chaque traitement hors cette chose est strictement interdite sur un serveur d’application, car trop dangereuse et dévolue au moteur de l’instance.

Un pattern de contournement était d’utiliser un pool MDB et une file JMS pour déclarer des traitements en parallèle (la taille du pool étant le nombre de traitements en parallèle possibles), mais cela impose de déclarer et administrer une file JMS.

Le principe de CommonJ et de s’appuyer sur les WorkManager pour déclarer les Thread et de proposer une interface de développement pour lancer les traitements à déployer sur ces WorkManager.

Il faut donc développer spécifiquement avec l’interface de CommonJ afin de déclarer les traitements à effectuer en parallèle et de récupérer une référence d’un Workmanager que l’on déclarer dans la configuration Weblogic via la console ou via les descripteurs JEE.

Cette API est utilisée en interne de beaucoup de framework éditeur comme Oracle Service Bus mais peut rependu dans les développements classique JEE car peut connu.

DEVELOPPEMENT



Nous allons reprendre un excellent article sur le sujet comme exemple de développement. Cet article montre la façon d’implémenter une méthode de simulation de traduction de mot via une Servlet qui fonctionne soit en série soit en parallèle.


J’ai donc repris ce code exemple dans une Web Application que j’ai appelé CommonjWAR, j’ai créé deux Servlet ServletSequential et ServletParallel issue de AbstractServlet. J’ai modifié ce code pour déclarer non pas 5 actions, mais 100 traitements.

AbstractServlet
private List getClientInput() {
             
   ArrayList arrList = new ArrayList();
   for( int i = 0; i < 100; i++ ) { arrList.add( Integer.toString(i)); }
             
   return arrList;
   // return Arrays.asList(new String[] { "one", "two", "three", "four", "five" } );
}

Le traitement séquentiel est réalise par la Servlet ServletSequential avec une bête boucle.

for (Iterator iter = input.iterator(); iter.hasNext();) {
             
   String source = (String) iter.next();
   Translator translator = new DummyTranslator(source, DELAY);
   translator.translate();
   result.add(translator.getTranslation());
}

Le traitement en parallèle est déclare dans la Servlet ServletParallel qui récupérer via un lookup JNDI une référence à un WorkManager de nom wm/MyWorkManager.


try {
                    
   InitialContext ctx = new InitialContext();
   this.workManager = (WorkManager) ctx.lookup("java:comp/env/wm/MyWorkManager");
                    
} catch (Exception e) { throw new ServletException(e); }

On injecte ensuite les traitements à réaliser sur le WorkManager, on attend la fin de l’ensemble des traitements que l’on re agrège

for (Iterator iter = input.iterator(); iter.hasNext();) {
                    
   String source = (String) iter.next();
   Translator translator = new DummyTranslator(source, 10 * 1000);

   // schedule
   Work work = new WorkTranslatorWrapper(translator);
   WorkItem workItem = this.workManager.schedule(work);
   jobs.add(workItem);
}

System.out.println( System.currentTimeMillis()  + " : All jobs scheduled at : " );
// wait for all jobs to complete
this.workManager.waitForAll(jobs, WorkManager.INDEFINITE);

// extract results
for (Iterator iter = jobs.iterator(); iter.hasNext();) {
                    
   WorkItem workItem = (WorkItem) iter.next();
   Translator translator = (Translator) workItem.getResult();
   result.add(translator.getTranslation());
}

J’ai déclaré dans le web.xml le nom du WorkManager que j’utilise dans mon code.


 <resource-ref>  
   <res-ref-name>wm/MyWorkManager</res-ref-name>  
   <res-type>commonj.work.WorkManager</res-type>  
   <res-auth>Container</res-auth>  
   <res-sharing-scope>Shareable</res-sharing-scope>  
 </resource-ref>  

ENVIRONNEMENT



Pour déployer cette  application, j’ai créé un domaine mono instance en mode production. J’ai déclaré un WorkManager du nom que j’ai déclaré dans le web.xml (wm/MyWorkManager). J’ai ajouté à ce WorkManager une contrainte minimum en concordance avec le nombre de traitements déclaré en parallèle dans mon code, c’est à dire 100.




Je déploie mon application sur cette instance et j’exécute les deux Servet en observant la sortie standard.

Avant activation, nous avons 6 Threads déclaré dans le pool de l’instance.


Activons le traitement en séquentiel.

http://localhost:7001/CommonjWAR/ServletSequential

L’affichage nous montre que les traitements s’effectuent en séquentiel et le temps pour réaliser tous les traitements est de 100*10s. On peut observer que seul le Thread 1 est utilisé pour le traitement.

begin
1339495038734 JOB[0] in 10000 ms on [[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [default]
1339495048735 JOB[1] in 10000 ms on [[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [default]
1339495058735 JOB[2] in 10000 ms on [[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [default]
1339495068735 JOB[3] in 10000 ms on [[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [default]
1339495078735 JOB[4] in 10001 ms on [[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [default]
1339495088736 JOB[5] in 10000 ms on [[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [default]
1339495098736 JOB[6] in 10000 ms on [[ACTIVE] ExecuteThread: '1' for queue:

….

1339495038734 JOB[99] in 10000 ms on [[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [default]
done in 1000045

Nombre de threads après traitement.


(Au bout de 10 minutes, le thread est considéré comme bloqué par Weblogic)

1339495698764 JOB[66] in 10000 ms on [[STUCK] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [default]

Exécutons maintenant ces mêmes traitements, mais via le WorkManager.

http://localhost:7001/CommonjWAR/ServletParallel

begin
1339501775295 : All jobs scheduled at :
1339501775283 JOB[17] in 10000 ms on [[ACTIVE] ExecuteThread: '4' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339501775283 JOB[19] in 10000 ms on [[STANDBY] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339501775283 JOB[14] in 10001 ms on [[ACTIVE] ExecuteThread: '17' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339501775283 JOB[12] in 10001 ms on [[ACTIVE] ExecuteThread: '21' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339501775283 JOB[1] in 10001 ms on [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339501775283 JOB[10] in 10001 ms on [[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339501775283 JOB[3] in 10001 ms on [[ACTIVE] ExecuteThread: '18' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339501775283 JOB[6] in 10001 ms on [[ACTIVE] ExecuteThread: '13' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]


1339501775295 JOB[94] in 10000 ms on [[STANDBY] ExecuteThread: '96' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339501775295 JOB[95] in 10000 ms on [[STANDBY] ExecuteThread: '97' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339501775295 JOB[99] in 10001 ms on [[STANDBY] ExecuteThread: '101' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339501775295 JOB[97] in 10001 ms on [[STANDBY] ExecuteThread: '99' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339501775295 JOB[98] in 10001 ms on [[STANDBY] ExecuteThread: '100' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
done in 10017

L’ensemble des traitements sont exécuté en même temps sur le WorkManager déclaré, et le retour apparaît au bout de 10s qui est le temps unitaire de traitement d’un job. On remarque que chaque traitement a un No de Thread différent.

En observant la taille du pool, on peut voir que la contrainte minimum du WorkManager de 100 Thread a été respectée et qu’il y a plus de 100 threads dans le pool global.


WORKMANAGER EMBEDED



On peut également déclarer le WorkManager dans les descripteurs JEE, ce qui évite une tâche administrative, mais le masque aux administrateurs. Supprimer l’entrée du WorkManager via la console est ajouter le weblogic.xml ci-dessous.

weblogic.xml

 <?xml version="1.0" encoding="UTF-8"?>  
 <wls:weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.3/weblogic-web-app.xsd">  
   <wls:weblogic-version>10.3.6</wls:weblogic-version>  
   <wls:context-root>CommonjWAR</wls:context-root>  
   <wls:work-manager>  
     <wls:name>wm/MyWorkManager</wls:name>  
     <wls:min-threads-constraint>  
       <wls:name>myMinThreadsConstraint</wls:name>  
       <wls:count>100</wls:count>  
     </wls:min-threads-constraint>      
   </wls:work-manager>  
 </wls:weblogic-web-app>  

Re déployer l’application et redémarrer l’instance pour re exécuter la Servlet  ServletParallel

MIN THREADS CONSTRAINT



Regardons maintenant l’impact du paramètre MinThreadsConstraint en diminuant sa valeur de 100 à 10.


   <wls:work-manager>  
     <wls:name>wm/MyWorkManager</wls:name>  
     <wls:min-threads-constraint>  
       <wls:name>myMinThreadsConstraint</wls:name>  
       <wls:count>10</wls:count>  
     </wls:min-threads-constraint>      
   </wls:work-manager>  

En redémarrant et redéployant l’application et activant la Servlet ServletParallel, nous constatons que tous les traitements ne se font pas tous en parallèle et que le temps total d’exécution est supérieur à 10s.

La principale raison est que le WorkManager se base sur un historique pour prendre la décision d’utiliser un Thread du pool global pour exécuter la tâche demandée par l’application associée (éviter trop de traitement en parallèle qui pourrait écroulé la machine). Le fait de définir un minimum permet d’allouer tout de suite des Threads pour desservir la charge voulue.

begin
1339502663859 : All jobs scheduled at :
1339502663857 JOB[0] in 10000 ms on [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339502663857 JOB[2] in 10000 ms on [[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339502663857 JOB[1] in 10000 ms on [[ACTIVE] ExecuteThread: '8' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]


1339502705721 JOB[97] in 10000 ms on [[ACTIVE] ExecuteThread: '21' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339502705720 JOB[96] in 10002 ms on [[ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339502705720 JOB[95] in 10002 ms on [[ACTIVE] ExecuteThread: '15' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339502705721 JOB[98] in 10002 ms on [[ACTIVE] ExecuteThread: '20' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
1339502705722 JOB[99] in 10001 ms on [[ACTIVE] ExecuteThread: '23' for queue: 'weblogic.kernel.Default (self-tuning)'] WorkManager [wm/MyWorkManager]
done in 51879

Afin de populer le pool de Threads dès le départ avec une valeur égale à la contrainte minimum, on peut également ajouter le paramètre suivant aux scriptes de démarrage des instances

-Dweblogic.threadpool.MinPoolSize=100
mardi 31 mars 2009

Cet article décrit le mécanisme d’allocation de Thread dans Weblogic via les WorkManager. Cette spécificité a été introduite en Weblogic 9 et permet de ne plus se préoccuper de ce paramètre en phase de tuning et déploiement en production. Il ajoute également des fonctionnalités de répartition de ressource et de gestion de crise qui facilite et sécurise l’architecture déployée.

CONTRAINTE


L’ancien mode de gestion de thread imposait un pool de taille fixe utilisé par les applications. On avait la possibilité d’utiliser éventuellement plusieurs pools pour compartimenter un environnement mutualisé (plusieurs applications sur une même instance). Les contraintes de ce mode de fonctionnement étaient :


ü  Difficulté de trouver une valeur au pool fonction de la charge de production (risque de sous ou sur utilisation).
ü  Obligation de créer d’autres pools de threads pour compartimenter cette ressource (création de threads inutile, car non mutualisé).
ü  Mas de moyen de gérer les threads bloqués.
ü  Sur dimensionnement de pool dans certains cas d’architecture multi tiers (1 instance portail requêtant 30 instances métier nécessitera 30*nbr threads des instances métiers pour pallier des threads bloqués).
ü  Dans une architecture multi tiers, si un des nœuds de la dernière couche est en contention, c’est la totalité des threads des couches en amont qui est absorbée, car mise en attente dans ce nœud.

PRINCIPE

Le pool de Threads est dynamique (ajout/suppression de threads) et unique sur l’instance. Les requêtes mise en attente sont global au pool. Un monitoring est mise en place pour l’auto-tuning et se déclencher toutes les 2 secondes afin d’analyser les données collecter et modifier le nombre de thread nécessaire pour assurer la charge (pas de code natif utilisé, et pas de prise en compte de la charge CPU). L’algorithme prend en compte la valeur courante, le requêtage actuel et l’historisation du trafic pour décider de modifier le nombre de threads. Si historiquement, le moniteur du pool constate un meilleur trafic avec un nombre important de threads, celui-ci va augmenter le nombre de threads, et inversement.
Globalement, WLS priorise les requêtes fonction :

ü  Des paramètres d’administration définit.
ü  Des métriques Runtime.
ü  Temps d’exécution courant.
ü  Fréquence des requêtes en entrée.

Des changements sont effectués :

ü  Quand le default faire-share est insuffisant.
ü  Quand une règle de priorité est définie.
ü  Quand l’application nécessite un temps de réponse spécifique.
ü  Pour éviter les dead-lock.

Des composants de Work Load Management (WorkManager) gèrent l’allocation et la répartition des Threads sur les applications déployées sur l’instance. Contrairement à l’ancien mode, ces Workmanager sont spécifiques à une application même si elles font référence au Workmanager par défaut (instance différente, mais même paramétrage). Cela permet de suivre la consommation par ressource.


Une politique d’allocation Thread est associée à chaque WorkManager afin de mieux répartir cette ressource sur les applications déployées.

POLITIQUES


Différentes politiques d’allocation de threads sont possibles associées à chaque WorkManager. Ces Workmanager peuvent être associés à une ou plusieurs applications. Deux types de politique sont possibles :


ü  Request class         : basé sur la priorité (dynamique)
ü  Constraints                         : basé sur des contraintes (statique)

Le Workmanager par défaut et paramètre en faire-share à 50 (toutes les applications sont desservies équitablement). La politique par défaut suffit dans la majorité de cas.

Request Classes


Répartition des ressources associées à des priorités (gestion dynamique).


faire-share-request-class          Pourcentage moyen de thread alloué pour desservir la charge sur la ressource (Default : 10 ; Min : 1 ; Max : 1000). Plus la valeur est élevée, plus le nombre de threads dédié sera grand. Ce paramètre est relatif à tous les autres faire-share déclarés sur l’instance. Déclarer deux Workmanager avec 10 et 90 correspond à 10% et 90% des ressources allouées. Un Workmanager déclaré sans faire-share possède un faire faire-share par défaut paramétré à 50. 


response-time-request-class   Temps de réponse désire (en milliseconde Default : 0). Ce paramètre ne s’applique pas au temps d’exécution de chaque requête, mais plutôt a un temps d’attente à ne pas dépasser fonction de la charge. Le calcul est fait sur chaque thread en faisant la différence des temps passés à l’exécution et les temps passés en file d’attente qui ne doivent pas dépasser le temps moyen demandé. Ce paramètre est relatif aux autres Workmanager déclarés sur l’instance. Deux Workmanager paramétrés avec 1000 et 8000 correspondront à une répartition des requêtes en respectant le ratio 1:8


context-request-class         Associer un Workmanager à une information de contexte utilisateur ou groupe.


Constraints


Définir des limitations de ressources sur la capacité (nombre et limite). Ce paramétrage doit être utilisé que dans des cas bien particuliers (il est préférable de laisser faire la réparation par des politiques et l’autotuning). La limitation se fait de façon globale sur l’ensemble d’un même type de WorkManager et non pas par instance de WrokManager.


max-threads-constraint        Taille maximum de nombre de thread à utiliser (Default : -1). (On peut associer la valeur de la contrainte à un pool JDBC Œ. Si la valeur du pool JDBC changer, cela affectera directement la valeur de la contrainte).


min-threads-constraint        Taille minimum de thread alloué. Cela permet de pré allouer des threads au Workmanager.


Capacity                      Une fois la capacité atteinte (nombre de requêtes en attente ou en exécution), les requêtes suivantes sont rejetées avec un code retour 503 en HTTP ou RemoteException.


WorkManager


La définition d’un Workmanager va permettre de composer avec ces différentes politiques d’allocation. Plusieurs Workmanager peuvent partager les mêmes contraintes ou politiques.



L’interaction entre ces différentes ressources sur différents Workmanager peut avoir des comportements différents :

ü  Dans le cas ou on mélange une politique fair-share et response-time, c’est la seconde qui sera favorisée.
ü  Une contrainte minimum peut augmenter l’importance d’une politique faire-share (d’où la préconisation d’utiliser les contraintes de façon précautionneuse).
ü  Une contrainte maximum peut empêcher une politique d’atteindre son but.

Default WorkManager


Un WorkManage est généré à chaque déploiement de ressource. Ce WorkManager s’appuie sur un paramétrage. Il existe plusieurs façons de spécifier le paramétrage.


Par défaut toutes les ressources utilisent le paramétrage du default Workmanager positionné en ‘faire share’. On peut surcharger ce paramétrage en créant un Global Workmanager de nom ‘default’.

Plusieurs raisons pour changer le default :

ü  Quand le paramétrage par défaut n’est pas suffisant (fair share).
ü  Partitionner les applications.
ü  Besoins de temps de réponse spécifique.
ü  Eviter des deadlocks (positionner une contrainte minimum).
ü  Associer la valeur d’un pool JDBC pour allouer les threads en concordance.

On peut également utiliser les paramétrages suivant pour modifier les contraintes du pool de thread sans redéfinir un default WorkManager.

(il est fortement recommandé de modifier le paramètre minimum sous peine d’obtenir des temps dégradés en début de bench)

Paramétrage de JVM
-Dweblogic.threadpool.MinPoolSize=100
-Dweblogic.threadpool.MaxPoolSize=200

config.xml

WLST
  managed=”managed1”
  cd("/Servers/" + managed)
  print "setting attributes for mbean type Server"
  set("SelfTuningThreadPoolSizeMin", "100")
  set("SelfTuningThreadPoolSizeMax", "200")


Voir la documentation
http://download.oracle.com/docs/cd/E11035_01/wls100/schemaref/security/http.www.bea.com.ns.weblogic.920.domain/types/kerneltype.self-tuning-thread-pool-size-max.html
http://download.oracle.com/docs/cd/E11035_01/wls100/schemaref/security/http.www.bea.com.ns.weblogic.920.domain/types/kerneltype.self-tuning-thread-pool-size-min.html


PARAMETRAGE


Trois types de Workmanager :


ü  Default                                  Utilisé par toutes les ressources qui n’ont pas de Workmanager
ü  Global                  Définit via l’administration WLS et visible de toutes les applications.
ü  Application-scoped      Déclaré dans les descripteurs applicatifs, et spécifiques à l’application.

Le Workmanager peut se déclarer dans le domaine, au niveau de l’application et au niveau module.

ü  config.xml                          création via la console d’administration avec la possibilité d’y associer des applications ou des composants applicatifs.
ü  weblogic-application.xml            spécification au niveau EAR
ü  weblogic-ejb-jar.xml/weblogic.xml   spécification au niveau composant
ü  weblogic.xml                        spécification au niveau WebApplication

Avec l’entrée suivante pour les descripteurs J2EE


Et pour le domaine : config.xml


Une fois le Workmanager crée, on peut l’associer à une application avec la primitive  ‘dispatch-policy’.

·         Dans une WebApplication

weblogic.xml

·         Sur un servlet

web.xml

·         Dans un EJB

weblogic-ejb-jar.xml

Détail de création à la console WLS pour un Workmanager global


Détail de création à la console WLS pour un Workmanager global

  
Pour la politique de paramétrage :

ü  Préférer l’utilisation de l’application scope pour le paramétrage afin de facilité de portage (pas besoin de paramétrage au niveau domaine).
ü  Déclarer des contraintes et politique de classe Global si elles sont utilisées par plusieurs Workmanager.

La prise en compte des déclarations peut se positionner à plusieurs endroits du paramétrage. L’ordre de recherche est le suivant :

ü  La recherche se fait en premier dans l’application. Si la ressource est trouvée, elle est prise en compte.
ü  Sinon, la recherche se fait au niveau serveur.
ü  S’il n’y a pas de définition trouvée, alors un Workmanager par défaut est crée avec une politique faire-share à 50. Une valeur null est positionnée pour les contraintes.

Sur la déclaration du Workmanager avec le dispatch-policy la recherche se fait de la même façon que présenter précédemment. Dans le cas où le Workmanager n’est pas trouvé dans les policy, un message est généré dans les logs et le Workmanager par défaut est pris pour l’instanciation.

ANCIEN MODE


On a la possibilité de revenir à l’ancien mode de gestion de  Thread (antérieure à la 9). Pour cela, il suffit de le préciser dans la configuration. Dans ce cas, tous les Workmanager sont remplacés par des pools de threads. La valeur du pool est déduite des contraintes précisées dans les Workmanager. S’il n’y a pas de contrainte définie, la valeur par défaut est prise du default Wrokmanager. Les options contre la surcharge et les contentions ne sont plus disponibles.


Paramètre JAVA
-Dweblogic.Use81StyleExecuteQueues=true

config.xml (préférer ce mode de paramètrage)

MBean
KernelMBean.Use81StyleExecuteQueues to true to disable Self-Tuning

Trace dans les logs en cas d’activation de l’option.
 
 is disabled. An execute queue will be created for
 each WorkManager definition.>

Dans le cas où des pools de threads sont déclarés sur une application à porter sur WLS 9/10, il faut la remplacer par un Workmanager spécifique (pas fait automatiquement).

Ce mode peut être utilisé si l’on ne connait pas l’impact du Workmanager sur une application migré (conserver le mode de fonctionnement).


ALLOCATION THREADS

Weblogic gère son allocation de threads en prenant en compte l’historique de la charge. Le pool de thread démarre à 0 et s’incrémente au fur et à mesure des contraintes de requêtage.

Périodiquement, toutes les 2s un thread de nom IncrementAdvisor est déclenché pour récolter les métriques de performance qui lui permet de mettre en place un auto-tuning. (flag de debug : -Dweblogic.Debug=weblogic.IncrementAdvisor)

Durant la période d’échantillonnage, on calcule le nombre moyen de traitements d’une requête. Toute requête dont le temps de traitement dépasse 7 fois cette moyenne est considérée comme hogged.

L’allocation de thread se décide selon le nombre de thread présent, le throughput  actuel et l’historique de la charge appliqué à un algorithme pour décider s’il faut allouer ou retrancher des threads sur le pool.

Une classe spécifique singleton RequestManager gère le pool de thread.


OVERLOAD PROTECTION

Weblogic à la capacité de détecter, éviter et retrouver un état normale sur des situations critiques. Cela passe par :




ü  Un paramétrage.
ü  Un automonitoring.
ü  Des codes de sortie d’erreur.

Dans le cas où cette situation n’est pas gérée, la plate-forme peut subir de forte dégradation voir une indisponibilité totale. Prenons le cas d’une architecture avec une couche de présentation (Servlet/JSP) et une couche métier (EJB) dans lequel une instance ne fonctionne pas correctement.


Chaque appel de la partie fonte est load balance sur le cluster EJB, mais tombe régulièrement sur l’instance malade. Malgré la non-réponse de cette instance, les requêtes sont mises en attente d’une hypothétique prise en compte. Donc chaque requête client utilisant un thread de la partie front va être mise en attente lors du requêtage du nœud défaillant de la partie back.


Au fur et à mesure des requêtages, c’est l’ensemble des utilisateurs qui vont être bloqué sur la partie front à cause d’un nœud de la partie back alors que le cluster EJB possède encore des instances valides.


En indiquant à l’instance malade qu’il ne faut plus accepté de requêtage en cas de dysfonctionnement, les requâtage en erreur seront rejoués sur les instances valides de la partie back.


De cette façon, on évite à la plate-forme de s’effondrer sur une défaillance d’un de ces éléments. Pour réaliser cela, Weblogic propose les mécanismes d’Overload Portection.

Configuration Weblogic


Dans certains cas de surcharge de capacité, l’acceptation de nouvelle requête peut entrainer une dégradation du système. Il faut donc sous certaines conditions refuser la charge subite en paramétrant Weblogic. L’objectif de ce paramétrage est donc de détecter ces états instables et d’y apporter une action corrective (si possible). Une instance est en difficulté quand :


ü  La limite de requêtage du pool de thread est atteinte.
ü  La limite du nombre de sessions http est atteinte.
ü  La capacité mémoire de la JVM est atteinte (OutOfMemory Exception)
ü  Des threads sont bloqués

Requêtes


Quand le nombre de requêtes en attente atteint son maximum, les requêtes sont rejetées (sauf pour les requêtes d’administration sur channel dédié) :


ü  Pour les Web application
ü  Les requêtes RMI (non transactionnel) en commençant par les requêtes de faible priorité (faible faire-share).

Si la surcharge persiste, les rejets sont propagés aux autres requêtes de plus haute priorité (excepté aux transactions JMS).

On peut repousser la limite par défaut qui est paramétré à 65536 via la console d’administration, ou pour une granularité plus fine utiliser le paramétrage des WorkManager.

Environments à Servers à Threads and select an execute queue


HTTP Session

On peut limiter le nombre de sessions actives :

ü  En cas de problème de sur capacité mémoire.
ü  Restriction d’accès sur un site sous dimensionné.
ü  Compartimentation des ressources sur une instance mutualisée (par utilisateur)

Une fois la limité atteinte, Weblogic rejette les connexions de nouveaux utilisateurs sur l’instance.

ü  Dans le cas d’un cluster, le plug-in redirige l’appel refusé sur une autre instance du cluster.
ü  Dans le cas d’une instance non clustérisé, on peut rediriger l’appel sur une autre instance (à spécifier sur le serveur HTTP par rapport à un retour d’erreur 503 levé par le Servlet Container ou applicativement sur la levée d’exception de type SessionCreationException).

Le paramétrage se fait dans le weblogic.xml


 OutOfMemory

On peut arrêter automatiquement le serveur dans le cas d’un dépassement mémoire de l’instance afin de ne pas dégrader la plate-forme. Ce cas de figure peut intervenir sur :

ü  Une sur consommation mémoire (session trop grande) associée à une charge (dépassement de la capacité établie sur l’instance).
ü  Une fuite mémoire (problème applicatif à corriger).

On peut le paramétrer via la console d’administration WLS ou en entrant les lignes suivantes dans le config.xml.

config.xml

Stuck Threads

Weblogic vérifie régulièrement la présence de threads bloqués. Si tous les threads applicatifs sont bloqués, le serveur change sont statu en FAILED.

Une fois l’alerte levée, on a la possibilité de rendre le Workmanager inactif rendant l’application indisponible, ou d’arrêter l’instance (il n’y a pas de kill de thread). Dans le cas ou l’instance est arrêté, Il faut redémarrer celle-ci pour rétablir la situation. La relance peut s’effectuer via le node manager (avec un retry paramétrable).

·         Global

Un paramétrage global peut être appliqué via la console Weblogic est valide pour le WorkManager par défaut.

EnvironnementàServersàConfigurationàOverload



·         Local

On peut appliquer ce paramètre à un Workmanager qu’on aura déclaré spécifiquement pour une application via la console Weblogic.  Il faudra rajouter dans le descripteur JEE de l’application l’entrée suivant :

weblogic.xml

Self Monitoring

Weblogic définit un nouvel état d’instance pour définir une situation de surcharge OVERLOAD retournée par le MBean ServerRuntimeMBean.getHealthState().           De retour à la normale, le status revient à l’état initial. L’administrateur peut suspendre ou arrêter une instance dans cet état. Celui se déclenche si :

ü  La capacité des Workmanager est dépassée.
ü  Une alerte mémoire est remontée.

Exit CODE


Quand processus Weblogic s’arrête, il retourne code retour  qui peut être utilisé par les scriptes shell ou les agents afin de décider s’il faut redémarrer l’instance.


Exemple de paramétrage


See “WebLogic Server Exit Codes and Restarting After Failure” in Managing Server Startup and Shutdown
For more information, see the attributes of the OverloadProtectionMBean


DEBUG

Positionner le paramètre de JVM suivant

-Dweblogic.Debug=

Avec comme valeur

weblogic.IncrementAdvisor
Logs self-tuning data every 2 seconds
weblogic.workmanagercollection
Logs WorkManager information during deployment
weblogic.wmglobalcomponentsfactory
Logs information about global work managers
weblogic.stuckthreadmanager
Logs information about stuck thread handling
  

MONITORING

Le monitoring des ressources Threads est plus complexe, car répartie entre le pool auto-tune les Workmanager et les objets request class et de constraints. La granularité est donc plus fine qu’en version WLS 8 basée uniquement sur le pool de threads.

METRIQUES

Thread Pool


${instance}àRuntimeServiceMBeanàServerRuntimeàThreadPoolRuntimeMBean

Information sur l’activité du pool
                                                        
CompletedRequestCount
Nombre de requêtage réalise depuis le démarrage de l’instance (prendre la valeur d’avant pour calculer le throughtput)
141415
ExecuteThreadIdleCount
Nombre de threads inoccupé (libre)
0
ExecuteThreadTotalCount
Nombre total de threads dans le pool
15
HoggingThreadCount
Nombre de thread utilisé par des requêtes trop lente
5
MinThreadsConstraintsCompleted

14126
MinThreadsConstraintsPending

0
PendingUserRequestCount
Nombre de requête utilisateur en attente sur le pool de thread du serveur
0
QueueLength
File d’attente des requêtes en utilisateur
0
SharedCapacityForWorkManagers

65536
StandbyThreadCount
Nombre de threads plus utilisé et mise en attente (réserve pour éviter une trop grande activité de création de threads)
9
Throughput

3.5

Le nombre de actif = nombre de inoccupé +  nombre de threads occupé

Workmanager


${instance}àRuntimeServiceMBeanàServerRuntimeà${instance}àApplicationRuntimesà${application}àWorkManagerRuntimesà${nom du workmanager}
Activité de chaque workmanager

ApplicationName
String
TestFreez
CompletedRequests
Long
0
ModuleName
String
null
PendingRequests
Integer
0
StuckThreadCount
Integer
0

Request Class


àRequestClassà${request class}

CompletedCount
Long
0
DeltaFirst
Long
1086
DeltaRepeat
Long
1086
Interval
Double
-1.0
MyLast
Long
0
PendingRequestCount
Integer
0
RequestClassType
String
fairshare
ThreadUseSquares
Long
0
TotalThreadUse
Long
0
VirtualTimeIncrement
Long
0


Max Constraints


àMaxThreadsConstraintRuntimeà${max constraints}

DeferredRequests
Integer
0
ExecutingRequests
Integer
0

Min Constraints


à MinThreadsConstraintRuntimeà${min constraints}

CompletedRequests
Long
0
CurrentWaitTime
Long
0
ExecutingRequests
Integer
0
MaxWaitTime
Long
0
MustRunCount
Integer
0
OutOfOrderExecutionCount
Long
0
PendingRequests
Integer
0


                                          
STARTEGIE


activeThreadCount= ExecuteThreadTotalCount-(ExecuteThreadIdleCount+StandbyThreadCount)

THREAD DUMP

 En Weblogic 8.1 et inférieures, les threads appartiennent au pool de threads et peuvent être identifiées par le nom du pool. En Weblogic 9 et supérieur, il n’y a qu’un pool de nom sel-tuning. Il est donc impossible de distinguer les threads associés aux différents Workmanager.
 This is because threads are shared by all WorkManagers. All execute threads have the term "self-tuning" in their names to indicate that they belong to the common self-tuning pool. The thread names are prepended with their states. The three states that appear in the thread names are:
  1. ACTIVE: The thread is active and is executing work or is ready to pick up work when it arrives.
  2. STANDBY: The thread is removed from the active thread pool and is not picking up work. It can still execute work from the minimum threads constraint work set if the constraint is not met. The self-tuning implementation has removed this thread from the active pool since it is not improving throughput. It can be moved back into the active thread pool if needed later.
  3. STUCK: A thread is stuck executing work for more than the configured stuck thread interval. The thread could be stuck due to a deadlock or a slow responding back end connection.
  

CAS D’UTILISATION


Pool min

Il se peut que l’instance ait des dégradations de temps de réponse quand le nombre de threads du pool atteint 0 (même problématique que les pools JDBC). Pour assurer une disponibilité maximale dès le départ, il est souhaitable de surcharger le Workmanager par défaut ou en déclarer un spécifiquement associé à la ressource afin de paramétrer un nombre de threads minimum (max-threads-constraint).

Un paramètre de JVM a été créé spécifiquement afin de déclarer une valeur minimale au workmanager default.

-Dweblogic.threadpool.MinPoolSize=

deadlock


min-threads-constraint

There are special situations where two servers can deadlock if a WorkManager does not get a minimum number of threads. For example, consider when Server A makes an EJB call to Server B, and Server B in turn makes a callback to Server A as a part of the same request processing. In this case, we know that until Server A responds to the callback from Server B, its original request to Server B will not get serviced. This scenario can be addressed in two ways. Configuring a WorkManager in Server A with a high fair share for callback requests from Server B will ensure that those requests get higher priority than new requests arriving at Server A from clients. In addition, adding a minimum threads constraint clause to the WorkManager will ensure that at least some threads in Server A will be able to pick up callback requests from Server B even when all the threads are busy or deadlocked.

JDBC Pool

Définir un nombre de Thread équivalent au nombre de connexion d’un pool JDBC.


 Dualité de ressource

Deux pools MDB embarquent un connecteur d’accès à une ressource (Moteur C) externe limité en capacité de connexion (50). Le première pool envoi les requêtes et le second récupère la réponse (1 envoi = 1 réponse asynchrone).

Dans le cas où on dimensionne les pools MDB de la même valeur que les ressources C, il peut y avoir saturation de cette ressource.


Une solution et de diviser la taille des pools par 2 afin de ne pas dépasser la somme totale des ressources C. Le problème est qu’en phase nominale, seules 25 requêtes seront possibles.


Pour que les deux pools MDB ne dépassent pas la taille limite de 50 requêtage en conservant la totalité des ressources C, on peut utiliser un WorkManager dédié à ces pools paramétrés à la même valeur que la ressource C, en conservant la taille des pools MDB à la valeur de la ressource C.


La définition de ce WorkManager peut se faire dans les descripteurs J2EE des MDB.
               
Attachement du MDB interrogation au WorkManager

Attachement du MDB notification au WorkManager

Définition du WorkManager



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