Contents

httpsessionlistener简介

1. 概述

本教程将展示如何注册javax.servlet.http.HttpSessionListener并使用指标  跟踪 Web 应用程序中的活动会话数。

2. 定义监听器

我们可以在web.xml中注册 HTTP Session 监听器:

<web-app ...>
    <listener>
        <listener-class>com.blogdemo.web.SessionListenerWithMetrics</listener-class>
    </listener>
</web-app>

或者,在 Servlet 3 环境中,我们也可以使用@WebListener来注册监听器。在这种情况下,我们需要使用@ServletComponentScan 注解主SpringBootApplication类。

最后,我们还可以通过声明ServletListenerRegistrationBean bean来使用 Java 配置注册监听器:

@Bean
public ServletListenerRegistrationBean<SessionListenerWithMetrics> sessionListenerWithMetrics() {
   ServletListenerRegistrationBean<SessionListenerWithMetrics> listenerRegBean =
     new ServletListenerRegistrationBean<>();
   
   listenerRegBean.setListener(new SessionListenerWithMetrics());
   return listenerRegBean;
}

3. 基本监听器

简单的侦听器将始终跟踪活动会话的数量:

public class SessionListenerWithMetrics implements HttpSessionListener {
    private final AtomicInteger activeSessions;
    public SessionListenerWithMetrics() {
        super();
        activeSessions = new AtomicInteger();
    }
    public int getTotalActiveSession() {
        return activeSessions.get();
    }
    public void sessionCreated(final HttpSessionEvent event) {
        activeSessions.incrementAndGet();
    }
    public void sessionDestroyed(final HttpSessionEvent event) {
        activeSessions.decrementAndGet();
    }
}

创建会话时将触发会话侦听器 - sessionCreated

HttpSession session = request.getSession();

并销毁 - sessionDestroyed

session.invalidate();

这种机制允许从侦听器中检索当前会话计数,但为了具有实时监控和透明度,我们需要额外的逻辑来实际检索值并发布它。

这就是指标库的用武之地——它带有几个开箱即用的报告器,可以轻松发布该指标。

4. 有指标的监听器

因此,我们将利用指标库,而不是推出我们自己的自定义监控解决方案;我们需要将它添加到我们的 pom 中:

<dependency>
    <groupId>com.codahale.metrics</groupId>
    <artifactId>metrics-core</artifactId>
    <version>3.0.1</version>
</dependency>

由于类路径上提供了 metrics core,我们可以使用Counter对象编写相同的HttpSessionListener

public class SessionListenerWithMetrics implements HttpSessionListener {
    private final Counter counterOfActiveSessions;
    public SessionListenerWithMetrics() {
        super();
        counterOfActiveSessions = MetricRegistrySingleton.metrics.counter("web.sessions.active.count");
    }
    public void sessionCreated(final HttpSessionEvent event) {
        counterOfActiveSessions.inc();
    }
    public void sessionDestroyed(final HttpSessionEvent event) {
        counterOfActiveSessions.dec();
    }
}

MetricRegistry - 所有应用程序指标的中央注册表 - 在应用程序范围的静态字段中简单地引用:

public final class MetricRegistrySingleton {
    public static final MetricRegistry metrics = new MetricRegistry();
}

发布此指标并使其易于监控(例如应用程序的标准日志记录系统)非常简单:

Logger logger = LoggerFactory.getLogger("com.blogdemo.monitoring");
Slf4jReporter reporter = Slf4jReporter.forRegistry(metrics).outputTo(logger).
  convertRatesTo(TimeUnit.SECONDS).convertDurationsTo(TimeUnit.MILLISECONDS).build();
reporter.start(5, TimeUnit.MINUTES);