Java surveiller les sessions Web actives

Je dois implémenter une application Web qui, une fois déployée sur tomcat, peut surveiller les sessions actives de toutes les applications déployées sur le même tomcat.

Supposons que tomcat ait 2 applications qui s’exécutent sous 1) ReportGenerator 2) DataSyncManager. Je dois montrer des sessions actives pour ces 2 applications avec des statistiques ci-dessous.

Seesion # Application Session Start Time 1234 ReportGenerator XXXX 56748 DataSyncManager XXXX 55565 DataSyncManager XXXX 

De plus, j’ai l’obligation de tuer la session à la volée. C’est possible? s’il vous plaît des conseils.

Je sais que c’est quelque chose de semblable à la console d’administration de tomcat / was. Mais je dois l’implémenter en tant qu’application personnalisée avec une fonctionnalité de journalisation et de surveillance personnalisée. Veuillez me conseiller sur quel framework / API je peux utiliser pour capturer les sessions actives sur tomcat et leurs statistiques.

J’ai implémenté cette fonctionnalité avec une approche générique à l’aide d’API standard et de spécifications, sans frameworks ni bibliothèques tiers. Cette solution a été largement utilisée avec de nombreux systèmes de niveau entreprise déployés dans le serveur d’applications glassfish et jboss. Il a également été utilisé avec succès avec weblogic (12c). Cependant, l’approche doit fonctionner dans tout serveur d’applications ou conteneur de servlets prenant en charge la spécification JMX standard.

Le tldr; Cette version consiste à créer deux interfaces de bean JMX et un écouteur de session http. L’une des interfaces de bean JMX crée une instance par application surveillée et est responsable du suivi de toutes les sessions à partir de chaque application surveillée. Elle fournit essentiellement des statistiques sur toutes les sessions de chaque application. L’autre interface de bean JMX crée une instance pour chaque session créée dans chaque application surveillée. L’écouteur de session http surveille les sessions de chaque application et fait deux choses. Informe le premier bean JMX correspondant à cette application des sessions créées / détruites afin que les statistiques soient mises à jour. Enregistre ou annule l’inscription des instances JMX correspondant à une session, à partir du service JMX.

Une fois que tout est configuré, il peut être utilisé depuis un client JMX, tel que jconsole et visualvm, fourni avec jdk. À partir d’un client jmx, il est possible d’afficher toutes les propriétés des beans JMX et d’appeler l’une de leurs méthodes.

Les captures d’écran suivantes proviennent d’une application de test utilisant jconsole.

entrez la description de l'image ici

Ce sont des atsortingbuts de l’instance de bean JMX correspondant à chaque application surveillée.

entrez la description de l'image ici

Ce sont des opérations qui peuvent être exécutées sur la session spécifique sélectionnée.

Si plusieurs applications sont surveillées, plusieurs contextes d’application avec leurs propres structures seront présents, par exemple / TestApplication, / Application2 etc. sous chacune des interfaces de bean jmx.

COMMENT

Initialement, il est nécessaire de créer les deux interfaces de bean JMX ( tutoriel simple ), puis un HttpSessionListener (de nombreux tutoriels en ligne ).

1.La première interface de bean JMX ne sera surveillée qu’une seule fois par application et stockera toutes les informations relatives aux sessions créées à partir de toutes les applications surveillées. Il est essentiellement utilisé pour la persistance. Je ne garde que les données en mémoire, ce qui signifie que les données seront perdues si le serveur tombe en panne, mais il est généralement nécessaire de vérifier les statistiques tant que le serveur est en marche. Si vous souhaitez conserver les données dans un journal ou une firebase database afin de toujours disposer de ces informations, vous pouvez certainement le faire dans le cadre de la mise en œuvre de l’interface.

Donc, cela pourrait être comme suit,

 public interface SessionsMXBean { /** * Get Indicates whether the data should be persisted in memory. */ public boolean getPersistData(); /** * Set Indicates whether the data should be persisted in memory. */ public void setPersistData(boolean value); /** * Get All active sessions that have been persisted. */ public Ssortingng getActiveSessions(); /** * Get All dates of each active session that has been persisted. */ public Ssortingng getDatesOfSessions(); /** * Get The threshold for the number of session, after which persistence will * take place. If -1 all are persisted. */ public int getSessionsThreshold(); /** * Set The threshold for the number of session, after which persistence will * take place. If -1 all are persisted. */ public void setSessionsThreshold(int value); /** * Set The limit of size to be persisted in KB. If -1 then no size limit. */ public void setPersistenceSize(long value); /** * Clears all persisted data. */ public void clearData(); /** * Unregisters this instance */ public void unregisterThis(); } 

Ensuite, vous devez créer une implémentation de cette interface qui contiendra éventuellement ce type de données.

  public class SessionsImpl implements SessionsMXBean { /* here you need to implement the interface and have all kind of objects you require */ public synchronized void incrementSessions() { .... } public synchronized void decrementSessions() { ..... } 

2.La deuxième interface de bean JMX aura une instance pour chaque session créée dans chacune de vos applications surveillées. Cette interface stockera l’object de session et comportera également des méthodes pouvant être appelées à partir d’un client jmx, afin d’invalider ces sessions. Cela peut être comme suit,

 public interface HttpSessionMXBean { /** * Get HTTP Session id */ public Ssortingng getSessionId(); /** * Get the date created */ public Ssortingng getDateCreated(); /** * Get the date created in milliseconds */ public long getMillisCreated(); /** * Get atsortingbutes from http session * * @param attrName Atsortingbute Name * @return java.lang.Ssortingng */ public Ssortingng getAtsortingbute(Ssortingng attrName); /** * Invalidate this session */ public void invalidate(); /** * Unregisters this instance */ public void unregisterThis(); } 

Et encore une fois une implémentation est nécessaire,

 public class HttpSessionMXBeanImpl implements HttpSessionMXBean { .... 

3.Puis vous créez le HttpSessionListener qui créera / supprimera les instances de l’interface 2nd bean et les enregistrera / annulera du service JMX de votre serveur. Cela se produira lorsque les sessions seront créées et invalidées / expirées. Vous aurez donc un auditeur par application qui l’a défini dans son web.xml.

HttpSessionListener

  .... public class MyJMXHTTPSessionListener implements HttpSessionListener { .... private SessionsImpl sesssionsImpl; private Map httpSessionMXBeans @Override public void sessionCreated(HttpSessionEvent se) { //requires synchronized block here with this ie synchronized (this) { /*check if a jmx bean instance of the 1st interface exists otherwise create one*/ if(sessionsImpl==null){ sesssionsImpl= new SesssionsImpl(); /* take care here to create a nice and unique path per instance of the application in order to be nicely presented on the JMX tree of the JMX clients */ Ssortingng id = ("services.jmx.beans:type=Sessions,"+ "realm=" + se.getSession().getServletContext().getContextPath()); sessionManagerMXBean.setId(id); ObjectName objectName = new ObjectName(id); if (ManagementFactory.getPlatformMBeanServer().isRegistered(objectName)) { ManagementFactory.getPlatformMBeanServer(). unregisterMBean(objectName); } ManagementFactory.getPlatformMBeanServer(). registerMBean(sesssionsImpl, objectName); } sesssionsImpl.inrementSessions(); /* create a jmx bean instance of the 2nd interface and register it to the jmx service as already shown using the unique session id and a nice path indicating the 2nd interface jmx beans. */ } @Override public void sessionDestroyed(HttpSessionEvent se) { //requires synchronized block here with this ie synchronized (this) { /*unregister the jmx bean instance of the 2nd interface, remove it from the list and call decrementSessions() on the jmx bean instance corresponding to this app*/ } } } 

Cette fonctionnalité peut être facilement activée à tout moment pour toute application Web si vous définissez le fichier HttpSessionListener dans le fichier web.xml en ajoutant les quelques lignes suivantes,

web.xml

   myservices.myhttpsessionlisteners.MyJMXHTTPSessionListener   

Avez-vous vérifié le projet psi-probe ?

C’est un gestionnaire et moniteur avancé pour Apache Tomcat, créé à partir de Lambda Probe.

La réponse de @ melc offre une excellente solution générique. Si cela ne fonctionne que sur Tomcat, vous pouvez également utiliser une version plus simple:

Dans l’un de vos servlets, implémentez l’interface org.apache.catalina.ContainerServlet (vous pouvez la trouver dans \ lib \ catalina.jar).

 import org.apache.catalina.Context; import org.apache.catalina.Session; import org.apache.catalina.Wrapper; public void setWrapper(Wrapper w) { this.wrapper = w; context = (Context) wrapper.getParent(); // This'll give you all sessions: org.apache.catalina.Session[] sessions = context.getManager().findSessions(); for (int i = 0; i < sessions.length; i++) { System.out.println(sessions[i]); } host = (Host) context.getParent(); // contexts are the list of applications deployed on Tomcat Context[] contexts = (Context[]) host.findChildren(); for (Context context:contexts) { //Or to access session list by application, //call findSessions() on the target context org.apache.catalina.Session[] sessions = context.getManager().findSessions(); } } 

En passant, vous devez définir votre contexte dans context.xml comme privilégié: