查找从给定客户端IP创建的活动会话数

有没有办法确定从给定客户端IP地址创建的活动会话数?

标准的Servlet API不提供相应的function。 最好的办法是自己维护MapString是IP地址),如果HttpSession#isNew() ,则检查每个ServletRequest ,并将其与ServletRequest#getRemoteAddr()一起添加到Map ServletRequest#getRemoteAddr() 。 然后,您可以使用Map#values()上的Collections#frequency() Map#values()活动会话的IP地址数量。 您只需要确保在HttpSessionListener#sessionDestroyed()期间从Map中删除HttpSession

这一切都可以在一个实现ServletContextListenerHttpSessionListenerServletRequestListener Listener完成。

这是一个启动示例:

 public class SessionCounter implements ServletContextListener, HttpSessionListener, ServletRequestListener { private static final String ATTRIBUTE_NAME = "com.example.SessionCounter"; private Map sessions = new ConcurrentHashMap(); @Override public void contextInitialized(ServletContextEvent event) { event.getServletContext().setAttribute(ATTRIBUTE_NAME, this); } @Override public void requestInitialized(ServletRequestEvent event) { HttpServletRequest request = (HttpServletRequest) event.getServletRequest(); HttpSession session = request.getSession(); if (session.isNew()) { sessions.put(session, request.getRemoteAddr()); } } @Override public void sessionDestroyed(HttpSessionEvent event) { sessions.remove(event.getSession()); } @Override public void sessionCreated(HttpSessionEvent event) { // NOOP. Useless since we can't obtain IP here. } @Override public void requestDestroyed(ServletRequestEvent event) { // NOOP. No logic needed. } @Override public void contextDestroyed(ServletContextEvent event) { // NOOP. No logic needed. Maybe some future cleanup? } public static SessionCounter getInstance(ServletContext context) { return (SessionCounter) context.getAttribute(ATTRIBUTE_NAME); } public int getCount(String remoteAddr) { return Collections.frequency(sessions.values(), remoteAddr); } } 

web.xml定义它,如下所示:

  com.example.SessionCounter  

您可以在任何servlet中使用它,如下所示:

 SessionCounter counter = SessionCounter.getInstance(getServletContext()); int count = counter.getCount("127.0.0.1"); 

我需要在没有新部署的情况下快速获取此信息。 可以通过更改JSP并添加以下代码段来完成。 (只有具有活动的会话才能获得设置值):

 <% // Set user agent and ip in session session.setAttribute("agent", request.getHeader("user-agent") + "@" + request.getRemoteAddr()); %> 

然后创建一个groovy脚本来查询jmx:

 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 mbean = new GroovyMBean(mbeans, 'Catalina:type=Manager,host=localhost,context=/') println "Active sessions: " + mbean['activeSessions'] def sessions = mbean.listSessionIds().tokenize(' '); def ips = [:]; def agents = [:]; sessions.each { def agentString = mbean.getSessionAttribute(it, "agent"); if(agentString != null) { agent = agentString.tokenize('@'); } else { agent = ['unknown', 'unknown']; } if(agents[agent[0]] == null) { agents[agent[0]] = []; } agents[agent[0]] += [it]; if(ips[agent[1]] == null) { ips[agent[1]] = []; } ips[agent[1]] += it; }; println "Ips" ips = ips.sort { -it.value.size } ips.each { ip, list -> println "${ip}\t${list.value.size}"; //println list; //println ""; } println "" println "Agents" agents = agents.sort { -it.value.size } agents.each { agent, list -> println "${agent}\t${agents[agent].size}"; //println list; //println ""; } 

结果

 Active sessions: 729 Ips unknown 102 68.180.230.118 11 80.213.88.107 11 157.55.39.127 9 81.191.247.166 2 ... Agents Mozilla/5.0 (compatible; MJ12bot/v1.4.5; http://www.majestic12.co.uk/bot.php?+) 117 unknown 102 Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm) 55 Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp) 29 ... 

很好的例子Balus C.我们使用Observer Listener解决了这个问题。 这是一个很好的示例/教程。

http://www.big-oh.net/BigOhSoftwareWeb/content/tutorials/requestObserverListener.jsp

只是觉得它会对其他访客有所帮助。 🙂

编辑:*** 2017年4月**

看起来包含上述来源的http://www.big-oh.net/网站已经死亡。 以下是web.archive.org的来源。 还在github gist中添加了文件引用的网页。 Gist 源及其html预览