16 novembre 2009

Chez XebiaLabs, nous nous y connaissons en déploiement automatique d’applications Java EE. L’une des choses les plus surprenantes réside dans le fait que «les fournisseurs de serveurs d’application ne semblent pas faire partie des personnes qui maitrisent le mieux le déploiement d’applications».
Dans un article précédent, nous avons décrit ce que nous considérons comme le déploiement d’application J2EE global. Et force est de constater que:
- Déployer va bien au delà d’un simple déploiement d’un EAR ou d’un WAR.
- La plupart des applications ont également besoin d’autres artéfacts comme par exemple du contenu statique pour le serveur web ou encore des fichiers de configuration, utilisés par le code java, au démarrage.
- Il faut également configurer des ressources JEE comme des Datasources JDBC ou des composants JMS (Queues, Topics, Servers).
- A ceci s’ajoute, bien entendu, la configuration du middleware lui-même: création et configuration de clusters de serveurs d’application ou de virtual hosts d’un serveur Apache.
- L’ordre d’exécution des tâches est important afin de réduire (voire de prévenir) la coupure de service de l’application pendant le déploiement et d’en augmenter la vitesse.
Alors posons nous la question. Que nous proposent les fournisseurs de serveurs d’application dans ce domaine ?
Lire la suite de cet article »
14 octobre 2009
Oracle Coherence est une solution de Data Grid. Elle permet de constituer des grilles de données à l’aide de 4 types de caches:
- Cache distribué: l’ensemble des données est réparti sur les différents nœuds qui composent le cluster Coherence. Afin de garantir une bonne tolérance aux pannes, les données peuvent être sauvegardées sur un ou plusieurs nœuds du cluster. Cette typologie est extrêmement extensible : il suffit d’ajouter des nouveaux nœuds pour augmenter la capacité globale du cache.
- Cache répliqué: l’ensemble des données est répliqué sur l’ensemble des nœuds du cluster. La modification d’une entrée sera propagée à l’ensemble des nœuds. Cette typologie permet d’offrir un accès très rapide en lecture car un seul nœud est sollicité dans l’opération. La contre-partie est que les opérations d’écriture sont lentes et que la taille du cache est indépendante du nombre de nœuds qui composent le cluster.
- Cache local: les données sont conservées exclusivement sur la JVM.
- Near Cache: il permet d’offrir le meilleur des caches de type ‘Répliqué’ (Performance) et de type ‘Distribué’ (Extensibilité) en fournissant un accès rapide aux données accédées le plus fréquemment et le plus récemment. Il est composé de 2 parties:
- le ‘front-cache’ pour les accès locaux, de petite taille, typiquement un cache Local (Local Cache),
- le ‘back-cache’ un cache de plus grande envergure, typiquement un cache distribué (Distributed Cache), qui contient l’ensemble des données avec leurs éventuelles sauvegardes.
Le point fort d’Oracle Coherence est de proposer la même API quelque soit le type de cache. Il est donc possible, par simple configuration, de modifier le type de cache et de l’adapter en fonction des besoins ou de l’environnement: cache local en « Développement », cache distribué en « Intégration », « Near » cache en « Production ».
Lire la suite de cet article »
4 août 2009
L'AOP (Programmation Orientée Aspect) permet au sein d'un programme d'implémenter facilement des problématiques transversales, comme la gestion de transaction, les mécanismes de cache ou la sécurité. Généralement, le traitement de ces opérations est soit local à une méthode, soit sans état. Je vous propose dans cet article de vous montrer comment déclarer des aspects dont le cycle de vie n'est plus celui de la JVM (static) mais fonction d'un pointcut.
L'application témoin
Voici une magnifique application ayant la structure suivante : Application -> Manager -> DAO avec un modèle simple : Caddy -> * Item. Chaque run de l'application ajoute 10 items au Caddy et effectue un paiement. Le test case effectue 5 run().
package fr.
xebia.
aop.
app;
import java.util.Random;
public class Application implements Runnable{
static Random r = new Random();
private CaddyManager manager = new CaddyManager();
public void run() {
for (int i =0 ; i <10; i++) {
manager.addItem(new Item(i,"Item#"+i,r.nextInt(100)));
}
manager.purchase();
manager.clearCaddy();
}
}
Dans la suite de l'article nous allons écrire 2 aspects qui vont nous permettre de :
16 décembre 2008
Je vais vous révéler un secret à propos de notre célèbre Revue de Presse ! Elle est élaborée collectivement par l'ensemble des consultants de Xebia sous Confluence avant d'être publiée sur notre blog. L'utilisation d'un wiki permet de suivre facilement les différentes modifications (contribution, corrections, commentaires). Une fois celle-ci terminée, la page est archivée et une autre est créée, vide, afin de recevoir la prochaine version. La fin de l'année arrive, c'est l'heure de faire les statistiques 2008. L'une des questions que je me pose est "Quelle est la proportion des entrées de la revue de presse entre les différentes catégories (Actualité éditeurs / SSII, Agilité, RIA, SOA, ...) ?"
Solution N°1 : Ouvrir dans le navigateur toutes les pages 'Revue de Presse' une par une et compter les entrées. Une revue de presses par semaine, 52 semaines ... non
Solution N°2 : Utiliser une API. En effet Confluence expose ses principales fonctions par web services. Voici le wsdl. Plus de 7300 lignes, 238 opérations, 50 types. À ce moment-là, j'étais presque prêt à repasser à la solution N°1 quand je suis tombé au détour d'une recherche Google (Google est notre ami à tous !), sur le projet Swizzle...
Lire la suite de cet article »
27 novembre 2008
Mardi, 10 heures
- La production "Allo, le projet, depuis 10 minutes on voit passer des messages 'OutOfMemoryError'. Que fait-on ? "
- Le projet "Augmentez la mémoire de la JVM, doublez-la valeur de l'option -Xmx "
Mardi, 13 heures
- La production "Allo, le projet, depuis 5 minutes on voit encore passer des messages 'OutOfMemoryError'. Que fait-on ? "
- Le projet "Augmentez la mémoire de la JVM, doublez encore la valeur de l'option -Xmx "
Mardi 18 heures
- La production "Allo, le projet, depuis 2 minutes on voit passer encore des messages 'OutOfMemoryError'. Que fait-on ? "
- Le projet "Tut, tut, tut,....."
- La production "Plus d'équipe projet, la nuit va être longue..."
Cette petite scène est un classique, un air de déjà-vu mais que faire ? Si votre application a déjà subi une batterie de tests techniques, augmenter la mémoire est rarement la bonne solution. La scène décrite ci-dessus laisse penser à ce que l'on appelle classiquement une Fuite Mémoire (Memory Leak). En réalité, avec les JVM récentes, la fuite mémoire n'existe pas, je préfère parler d'accumulation d'objets non désirés. Cet article va vous montrer comment débusquer cette accumulation avec les outils jmap, jhat et Eclipse Memory Analyser
jmap
jmap est l'outil qui permet d'effectuer des photographies de la mémoire d'une JVM. Deux options sont particulièrement intéressantes : l'histogramme et le dump.
22 octobre 2008
Développer une application Java, c'est bien. La rendre performante, c'est mieux.
Cependant, qui dit "performance", dit "mesure". En effet, il est nécessaire de pouvoir :
- connaître les paramètres de lancement de la JVM,
- mesurer l'empreinte mémoire et le comportement du Garbage Collector,
Cet article va décrire dans une première partie les différents outils permettant de collecter ces informations en local. La seconde partie se concentre sur les moyens pour obtenir ces mêmes informations à distance.
Lire la suite de cet article »
24 septembre 2008
....ou comment effectuer un traitement régulièrement
Avec l'arrivée de l'api java.util.concurrent dans le JDK 5, la programmation concurrente est à la portée de tous. Auparavant, il fallait :
- soit être un expert des APIs de bas niveau et être prêt à passer des nuits blanches à mettre au point le système,
- soit se tourner vers les serveurs d'applications J2EE et leur implémentation JMS et EJB Message Driven Bean. Dans ce cas-là, la lourdeur de l'API JMS et les contraintes de persistance et de transaction (par défaut) des serveurs JMS viendront mettre à mal au final l'utilisation de traitements parallèles et concurrents.
Dans le cadre d'un de mes projets, j'ai eu besoin d'implémenter le comportement suivant :
- les producteurs, N Threads effectuent une tâche qui entre autres collecte des données.
- le consommateur, 1 Thread collecte ces données pour les agréger.
Dans un premier temps, je me tourne vers une java.util.concurrent.BlockingQueue partagée entre les producteurs et le consommateur. Cette conception fonctionne jusqu'au moment où je me suis aperçu que
- le traitement effectué par mon consommateur pouvait être long et coûteux en ressources : il faut donc éviter d'effectuer le traitement au fil de l'eau et attendre d'avoir un certain nombre de données dans la file.
- les producteurs, suivant la vie de l'application, pouvaient à un instant donné être très nombreux (beaucoup de données en peu de temps) ou au contraire peu nombreux. Dans ce dernier cas, le remplissage de ma file prendrait des heures et je ne pouvais attendre cette condition pour lancer mon traitement.
Lire la suite de cet article »
6 août 2008
Le serveur d'applications Weblogic permet de déclarer des serveurs JMS. À chaque serveur JMS est associé un Persistent Store, emplacement destiné à persister les messages JMS en cas d'interruptions de service entre la publication d'un message et sa consommation. Deux supports possibles :
- File Persistence Store, un répertoire accessible par le serveur Weblogic composé d'un ou plusieurs fichiers de structures binaires (.DAT)
- JDBC Persistence Store, ensemble de tables contenues dans une base de données relationnelle et accessible à travers une 'DataSource'. La structure des tables et leur contenu sont exclusiment gérés par le serveur d'applications.
Le choix de l'un des deux types de stockage est principalement dicté par des contraintes d'architecture et d'exploitation; les avantages de l'un sont les inconvénients de l'autre.
Jusqu'à la version 8 de Weblogic, il était impossible de pouvoir les administrer, en particulier pouvoir les ouvrir, analyser ou dumper leur contenu.
À partir de la version 9, le serveur d'applications propose un outil : weblogic.store.Admin
java -classpath ${WLS_DIR}/servir/lib/weblogic.jar weblogic.store.Admin
Les commandes principales sont : open, dump et compact.
Lire la suite de cet article »
2 juillet 2008
Symptômes
Lors d'un test de performance sur une application J2EE, je note que celle-ci a des soucis de montée en charge. Généralement une ou deux thread dumps peuvent mettre en évidence les points de contentions. Dans mon cas, rien de probant. Je repense alors à l'article publié sur notre blog Chroniques de la performance : À propos de contentions.... Je récupère les sources de l'agent et l'installe sur le serveur d'application, Weblogic 8.1 - JVM 1.4.2. Lancement du tir....
Lire la suite de cet article »
17 avril 2008
"Il faudrait pouvoir changer le nom de la DataSource en fonction des environnements"
"Ouh la la, c'est compliqué, il faut décompresser l'archive de l'application MonApp.ear et les 5 fichiers .war et les 8 fichiers .jar des ejb. Ça prendra 3 semaines minimum, et sans la documentation!"
(La fonctionnalité "plans de déploiement" décrite dans cette article est disponible à partir de WebLogic 9)
Lors de l'article précédent, nous avions montré comment packager un pool de connexions JDBC avec un EAR. Il semble évident que si cette solution est intéressante, elle n'est suffisante pour paramétrer cette application dans différents environnements projets (Recette, Pré-Production ou Production). Il n'est pas envisageable que pour chaque environnement, il faille ouvrir l'archive, modifier le fichier XML avec les nouveaux paramètres et pour finir de la refermer.
L'idée des plans de déploiement est de laisser l'archive telle quelle et de lui associer au moment du déploiement les nouveaux paramètres. Un plan de déploiement est un fichier XML qui reprend l'ensemble des nouveaux paramètres à surcharger.
Lire la suite de cet article »