使用Java获取Tomcat中活动会话的列表

使用Java获取Tomcat中活动会话的列表,java,tomcat,Java,Tomcat,我正在用Java开发一个项目,在这个项目中,我想要Tomcat中所有活动会话的计数。基于此,我想看看这些用户中有多少是活跃的,并且实际使用该应用程序。没有任何方法可以直接从tomcat获取会话计数。但是,您可以创建并注册会话侦听器,并在创建会话侦听器时增加计数。以下是一个例子: 您应该使用JMX(javamanagemnet扩展)并查询以下内容 jmxObjectName: Catalina:host=localhost,path=/,type=Manager jmxAttributeN

我正在用Java开发一个项目,在这个项目中,我想要Tomcat中所有活动会话的计数。基于此,我想看看这些用户中有多少是活跃的,并且实际使用该应用程序。

没有任何方法可以直接从tomcat获取会话计数。但是,您可以创建并注册会话侦听器,并在创建会话侦听器时增加计数。以下是一个例子:

您应该使用JMX(javamanagemnet扩展)并查询以下内容

jmxObjectName:    Catalina:host=localhost,path=/,type=Manager
jmxAttributeName: activeSessions
您可以使用jconsole访问此数据。要运行jmx,请参阅


使用JMX也有很多好处,因为您还可以获得大量其他数据。您可以将它放入munin插件中,让munin监视它并绘制漂亮的图形以供查看。

“PSI Probe”可能会为您提供帮助:

如果您不需要实际web应用程序中的值,groovy脚本可以帮助:

import javax.management.remote.*
import javax.management.*
import groovy.jmx.builder.*

// Setup JMX connection.
def connection = new JmxBuilder().client(port: 4934, host: '192.168.10.6')
connection.connect()

// Get the MBeanServer.
def mbeans = connection.MBeanServerConnection

def activeBean = new GroovyMBean(mbeans, 'Catalina:type=Manager,host=localhost,context=/')
println "Active sessions: " + activeBean['activeSessions']
如果需要实际会话,可以使用以下方法检索它们:

def sessions = activeBean.listSessionIds().tokenize(' ');

以下是Java 7风格的JMX代码片段(basZero要求的内容以及Janning所描述的具体工作):

当然,如果应用程序上下文字符串未部署在根上下文中,则需要将ObjectName中的根上下文(/)替换为应用程序上下文字符串。
请参见我对Catalina JMX问题的详细解释:

如果您正在tomcat服务器上运行的应用程序中获取统计数据,那么如何在本地获取会话计数。无需通过以下方式启用jmx remote:

public void init(final ServletConfig config) throws ServletException
{
    context = config.getServletContext().getContextPath();
}
//...
private void getSessionStats()
{
    MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
    ObjectName objectName = new ObjectName("Catalina:type=Manager,context="+context+",host=localhost");
    Object activeSessions = mBeanServer.getAttribute(objectName, "activeSessions");
    System.out.println(activeSessions);
}

演示如何确定Java Web应用程序中的活动用户/会话的简单教程

package com.hubberspot.javaee.listener;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class OnlineUsersCounter implements HttpSessionListener {

private static int numberOfUsersOnline;

 public OnlineUsersCounter() {
  numberOfUsersOnline = 0;
 }

 public static int getNumberOfUsersOnline() { 
  return numberOfUsersOnline;
 }

    public void sessionCreated(HttpSessionEvent event) {

     System.out.println("Session created by Id : " + event.getSession().getId());
     synchronized (this) {
   numberOfUsersOnline++;
  }

    }

    public void sessionDestroyed(HttpSessionEvent event) {

     System.out.println("Session destroyed by Id : " + event.getSession().getId());
     synchronized (this) {
   numberOfUsersOnline--;
  }

    }

}
在三种不同的浏览器上运行下面的servlet将提供如下输出:(参见下图)

package com.hubberspot.javaee;
导入java.io.IOException;
导入java.io.PrintWriter;
导入javax.servlet.ServletException;
导入javax.servlet.annotation.WebInitParam;
导入javax.servlet.annotation.WebServlet;
导入javax.servlet.http.HttpServlet;
导入javax.servlet.http.HttpServletRequest;
导入javax.servlet.http.HttpServletResponse;
导入javax.servlet.http.HttpSession;
导入com.hubberspot.javaee.listener.OnlineUsersCenter;
//@WebServlet批注有一个initParams字段,该字段采用
//在servlet的初始化参数中。
//@WebInitParam注释为
//当前Servlet的初始化参数。
@WebServlet(name=“HelloWorldServlet”,urlPatterns={”/HelloWorldServlet}
,initParams={@WebInitParam(name=“user”,value=“Jonty”)})
公共类HelloWorldServlet扩展了HttpServlet{
受保护空穴狗(
HttpServletRequest请求,
HttpServletResponse
)抛出ServletException、IOException{
response.setContentType(“text/html”);
PrintWriter out=response.getWriter();
//执行sessionCreated方法
HttpSession session=request.getSession();
session.setMaxInactivativeInterval(60);
试一试{
out.println(“”);
out.println(“”);
out.println(“联机用户数:”
+OnlineUsersCenter.getNumberOfUsersOnline()
+ "");
out.println(“”);
out.println(“”);
}最后{
out.close();
}
}
}
程序的输出:

  • Eclipse浏览器->
  • Firefox浏览器->
  • Internet Explorer浏览器->
  • 控制台输出->
  • 更多信息:

    您可以将附加到正在运行的tomcat,并通过curl从相关MBean查询
    activeSessions
    属性

    java -jar agent.jar start [TOMCAT-PID]
    curl 'http://127.0.0.1:8778/jolokia/read/Catalina:context=*,host=*,type=Manager/activeSessions'
    java -jar agent.jar stop [TOMCAT-PID]
    
    这会给你一些

    {  
       "request":{  
          "mbean":"Catalina:context=*,host=*,type=Manager",
          "attribute":"activeSessions",
          "type":"read"
       },
       "value":{  
          "Catalina:context=\/SampleApp,host=localhost,type=Manager":{  
             "activeSessions":1
          }
       },
       "timestamp":1553105659,
       "status":200
    }
    

    还有两种方法需要添加,这两种方法我一直都在使用

    1。VisualVM

    要了解活动会话的数量,可以使用Tomcat的内部统计信息,这些统计信息可以使用JMX(Java管理扩展)访问

    实际上,可以使用分析工具(如或)访问MBeans选项卡上的JMX统计信息,如活动会话数(请参见下面的屏幕截图)

    2。JavaMelody

    您还可以使用JavaEE应用程序监视工具,例如,帮助您在QA和生产环境中监视Java或JavaEE应用程序


    用户是登录的还是访问者?如果您需要任何Tomcat特定的数据,您应该能够从侦听器将HttpSession转换为org.apache.catalina.session.StandardSession。@user,如果这解决了你的问题,那么请接受正确的答案:)谢谢你的评论,但是听众理解会话超时的原因。我不确定你在问什么?如果您使用此方法并将会话本身的引用存储在作为筛选器成员变量的映射中,这是一个非常糟糕的主意(因为会话将无法进行GCed)吗?任何人都可以发布一段代码片段,说明如何通过JMX从JVM本身中检索activeSessions吗?
    package com.hubberspot.javaee;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebInitParam;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import com.hubberspot.javaee.listener.OnlineUsersCounter;
    
    // @WebServlet annotation has a initParams field which takes
    // in initialization parameters for a servlet.
    // @WebInitParam annotation takes in a name and value for the
    // initialization parameters for the current Servlet.
    
    @WebServlet(name = "HelloWorldServlet" , urlPatterns = { "/HelloWorldServlet" }
    , initParams = { @WebInitParam(name = "user" , value = "Jonty") })
    public class HelloWorldServlet extends HttpServlet {
    
     protected void doGet(
       HttpServletRequest request, 
       HttpServletResponse response
       ) throws ServletException, IOException {
    
      response.setContentType("text/html");
    
      PrintWriter out = response.getWriter();
    
      // sessionCreated method gets executed
      HttpSession session = request.getSession();
    
      session.setMaxInactiveInterval(60);
    
      try {
       out.println("<html>");
       out.println("<body>");
       out.println("<h2>Number of Users Online : "
          + OnlineUsersCounter.getNumberOfUsersOnline() 
          + "</h2>");
       out.println("</body>");
       out.println("</html>");
      } finally {
       out.close();
      }
    
     }
    
    }
    
    java -jar agent.jar start [TOMCAT-PID]
    curl 'http://127.0.0.1:8778/jolokia/read/Catalina:context=*,host=*,type=Manager/activeSessions'
    java -jar agent.jar stop [TOMCAT-PID]
    
    {  
       "request":{  
          "mbean":"Catalina:context=*,host=*,type=Manager",
          "attribute":"activeSessions",
          "type":"read"
       },
       "value":{  
          "Catalina:context=\/SampleApp,host=localhost,type=Manager":{  
             "activeSessions":1
          }
       },
       "timestamp":1553105659,
       "status":200
    }