2013-11-07 2 views
8

Мне нужно внедрить веб-приложение, которое после развертывания на tomcat может отслеживать активные сеансы всех приложений, развернутых на одном и том же коте.Активные веб-сессии Java-монитора

скажем, у tomcat 2 приложения, выполняющиеся как 1) ReportGenerator 2) DataSyncManager. Мне нужно показать активные сеансы для этих 2 приложений с более низкой статистикой.

Seesion # Application Session Start Time 

1234 ReportGenerator  XXXX 
56748 DataSyncManager  XXXX 
55565 DataSyncManager  XXXX 

Также у меня есть требование убить сеанс на лету. Является ли это возможным? пожалуйста посоветуй.

Я знаю, что это нечто похожее на консоль администратора tomcat/was. Но мне нужно реализовать его как настраиваемое приложение с пользовательской функцией ведения журнала и мониторинга. Пожалуйста, посоветуйте мне, на какой платформе/api я могу использовать, чтобы захватывать активные сеансы на tomcat и их статистику.

+0

Похоже, что tomcat предоставляет средства мониторинга через JMX. Посмотрите http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html – Karthik

ответ

8

Я реализовал эту функциональность с помощью общего подхода с использованием стандартных API и спецификаций, сторонних фреймворков или библиотек. Это решение широко использовалось во многих системах корпоративного уровня, развернутых на сервере приложений и jboss на стеклянных досках. Он также успешно используется с weblogic (12c). Тем не менее, этот подход должен работать в любом сервере приложений или сервлете, поддерживающем стандартную спецификацию JMX.

tldr; - это создание двух интерфейсов компонента JMX и одного прослушивателя сеанса http. Один из интерфейсов компонента JMX создает один экземпляр для каждого контролируемого приложения и отвечает за отслеживание всех сеансов от каждого контролируемого приложения, он в основном обеспечивает статистику всех сеансов для каждого приложения. Другой интерфейс компонента JMX создает один экземпляр для каждого сеанса, созданного в каждом контролируемом приложении. Слушатель сеанса http отслеживает сеансы каждого приложения и выполняет две функции. Сообщает о первом компоненте JMX, соответствующем этому приложению, о сеансах, созданных/уничтоженных, для обновления статистики. Регистрирует или деблокирует экземпляры JMX, соответствующие сеансу, из службы JMX.

Как только все будет установлено, его можно использовать с помощью JMX-клиента, такого как jconsole и visualvm, который поставляется вместе с jdk. Из jmx-клиента можно просмотреть все свойства компонентов JMX, а также вызвать любой из их методов.

Следующие скриншоты из тестового приложения, использующего jconsole.

enter image description here

Эти атрибуты из экземпляра компонента JMX, соответствующего каждому приложению контролируемого.

enter image description here

Эти операции, которые могут быть выполнены на конкретной сессии, выбранной.

Если отслеживается несколько приложений, тогда будет присутствовать больше контекстов приложения со своими собственными структурами, то есть/TestApplication,/Application2 и т. Д. Под каждым из интерфейсов bean-компонента jmx.

КАК

Первоначально необходимо создать два JMX боба интерфейса (simple tutorial), а затем один HttpSessionListener (много учебников онлайн).

1. В первом интерфейсе компонента JMX будет отображаться только один экземпляр для каждого приложения и будет хранить всю информацию, связанную с сеансами, созданными из любого из контролируемых приложений. Он в основном используется для настойчивости. Я сохраняю данные только в памяти, а это означает, что данные будут потеряны, если сервер опустится, но обычно требуется проверять статистику до тех пор, пока сервер не работает. Если вы хотите сохранить данные в журнале или db, чтобы всегда иметь эту информацию, вы можете сделать это в рамках реализации интерфейса.

Так что это может быть следующим,

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 String getActiveSessions(); 

    /** 
    * Get All dates of each active session that has been persisted. 
    */ 
    public String 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(); 
} 

Затем вы должны создать реализацию этого интерфейса, который будет в конечном итоге провести такого рода данных.

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. второй JMX интерфейс боб будет иметь один экземпляр для каждого сеанса, созданного в каждом из ваших отслеживаемых приложений. Этот интерфейс будет хранить объект сеанса и также будет иметь методы, которые могут быть вызваны из клиента jmx, чтобы аннулировать эти сеансы. Это может быть следующим,

public interface HttpSessionMXBean { 

    /** 
    * Get HTTP Session id 
    */ 
    public String getSessionId(); 

    /** 
    * Get the date created 
    */ 
    public String getDateCreated(); 

    /** 
    * Get the date created in milliseconds 
    */ 
    public long getMillisCreated(); 

    /** 
    * Get attributes from http session 
    * 
    * @param attrName Attribute Name 
    * @return java.lang.String 
    */ 
    public String getAttribute(String attrName); 

    /** 
    * Invalidate this session 
    */ 
    public void invalidate(); 

    /** 
    * Unregisters this instance 
    */ 
    public void unregisterThis(); 
} 

И снова требуется реализация,

public class HttpSessionMXBeanImpl implements HttpSessionMXBean { 
.... 

3.Then вы создаете HttpSessionListener, который будет создавать/удалять экземпляры 2-го интерфейса боба и регистрации/Unregister их из службы JMX вашего сервера. Это произойдет, когда сеансы создаются и аннулируются/истек. Таким образом, у вас будет один прослушиватель для каждого приложения, которое определено в его web.xml.

HttpSessionListener

 .... 
     public class MyJMXHTTPSessionListener implements HttpSessionListener { 
     .... 
      private SessionsImpl sesssionsImpl; 
      private Map<String, HttpSessionMXBeanImpl> httpSessionMXBeans 

      @Override 
      public void sessionCreated(HttpSessionEvent se) { 
      //requires synchronized block here with this i.e. 
      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 */ 
         String 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 i.e. 
      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*/ 
      } 
      } 
     } 

Эта функциональность может быть легко активирован в любое время для любого веб-приложения, если определить HttpSessionListener в файле web.xml, добавив следующие несколько строк,

web.xml

<listener> 
    <listener-class> 
    myservices.myhttpsessionlisteners.MyJMXHTTPSessionListener 
    </listener-class> 
</listener> 
+0

Насколько я понимаю, первый JMX MBean, который контролирует ВСЕ созданные сеансы, является необязательным? –

+0

@PrahaladDeshpande Да, если вы не хотите никакой статистики. – melc

+0

@PrahaladDeshpande однако будут практические проблемы, например, что, если вы хотите подсчитать сеансы в контролируемом приложении, которое имеет 100 или 1000 одновременных пользователей. Невозможно подсчитать все экземпляры 'HttpSessionMXBean', поэтому в этом случае вам потребуется значение с уровня приложения' SessionsMXBean'. В общем, это действительно полезно. – melc

2

@ Ответ от melc предлагает ag reat generic solution. Если это только собирается работать на Tomcat можно также использовать более простой вариант:

В одном из сервлетов реализует интерфейс org.apache.catalina.ContainerServlet (Вы можете найти его в < Tomcat путь установки > \ 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(); 
    } 
} 

Кстати, вы должны определить свой контекст в context.xml привилегированными:

<Context privileged="true"> 
3

ли вы проверить проект psi-probe?

Это расширенный менеджер и монитор для Apache Tomcat, раздвоенный из лямбда-зонда.

Смежные вопросы