簡體   English   中英

Java監視活動Web會話

[英]Java monitor active web sessions

我需要實現一個基於Web的應用程序,一旦部署在tomcat上,就可以監視部署在同一個tomcat上的所有應用程序的活動會話。

讓我們說tomcat有2個應用程序運行1)ReportGenerator 2)DataSyncManager。 我需要使用以下統計信息顯示這兩個應用程序的活動會話。

Seesion #   Application    Session Start Time

1234    ReportGenerator     XXXX
56748   DataSyncManager     XXXX
55565   DataSyncManager     XXXX

此外,我有一個要求即時殺死會話。 可能嗎? 請指教。

我知道這是類似tomcat /的管理控制台。 但我需要將其實現為具有自定義日志記錄和監視功能的自定義應用程序。 請告訴我哪些框架/ api可用於捕獲關於tomcat的活動會話及其統計信息。

我使用標准API和規范,沒有第三方框架或庫,使用通用方法實現了此功能。 該解決方案已廣泛用於部署在glassfish應用服務器和jboss中的許多企業級系統。 它也已成功用於weblogic(12c)。 但是,該方法應該適用於支持標准JMX規范的任何應用程序服務器或servlet容器。

tldr; 這個版本的目的是創建兩個JMX bean接口和一個http會話監聽器。 其中一個JMX bean接口為每個受監視的應用程序創建一個實例,並負責跟蹤每個受監視應用程序的所有會話,它基本上提供每個應用程序的所有會話的統計信息。 另一個JMX bean接口為每個受監視的應用程序中創建的每個會話創建一個實例。 http會話偵聽器監視每個應用程序的會話並執行兩項操作。 通知與此應用程序對應的第一個JMX bean有關創建/銷毀的會話,以便更新統計信息。 從JMX服務注冊或取消注冊與會話相對應的JMX實例。

一旦設置好所有內容,就可以使用JMX客戶端,例如jdk和jvk附帶的visualvm。 從jmx客戶端可以查看JMX bean的所有屬性,也可以調用它們的任何方法。

以下屏幕截圖來自使用jconsole的測試應用程序。

在此輸入圖像描述

這些是與每個受監視應用程序對應的JMX bean實例的屬性。

在此輸入圖像描述

這些是可以在所選特定會話上執行的操作。

如果監視多個應用程序,則會出現更多具有自己結構的應用程序上下文,即每個jmx bean接口下的/ TestApplication,/ Application2等。

如何

最初需要創建兩個JMX bean接口( 簡單教程 ),然后創建一個HttpSessionListener( 大量在線教程 )。

1.第一個JMX bean接口每個應用程序只有一個實例受監控,並將存儲與從任何受監控的應用程序創建的會話相關的所有信息。 它基本上用於持久性。 我只將數據保存在內存中,這意味着如果服務器出現故障,數據將會丟失,但通常只要服務器啟動就需要檢查統計數據。 如果要將數據持久保存到日志或數據庫以便始終擁有此信息,您當然可以在接口的實現中執行此操作。

所以這可以如下,

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 bean接口將為每個受監控應用程序中創建的每個會話創建一個實例。 此接口將存儲會話對象,並且還將具有可從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.然后創建HttpSessionListener,它將創建/刪除第二個bean接口的實例,並從服務器的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*/
            }
          }
        }

如果您通過添加以下幾行在web.xml文件中定義HttpSessionListener,則可以隨時為任何Web應用程序輕松激活此功能,

web.xml中

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

你看過psi-probe項目了嗎?

它是Apache Tomcat的高級管理器和監視器,由Lambda Probe派生而來。

@melc的答案提供了一個很好的通用解決方案。 如果它只在Tomcat上運行,你也可以使用更簡單的版本:

在其中一個servlet中實現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定義為特權:

<Context privileged="true">

Tomcat AddOns

Lambda Probe 版本 (以前稱為Tomcat Probe) - 實時監控和管理Apache Tomcat實例的終極工具。 Lambda Probe將通過易於使用且友好的Web界面幫助您可視化有關Apache Tomcat實例的實時信息。

PSI Probe是Apache Tomcat的高級管理器和監視器,從Lambda Probe分支到GitHub。

安裝ApacheTomcat :下載War文件並放在webapp文件夾中,通過將manager-gui角色添加到任何用戶來更改配置文件

<role rolename="manager-gui"/>
<user username="tomcat" password="s3cret" roles="manager-gui"/>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM