切换语言为:繁体

ServerHttpObservationFilter 应用案例说明

  • 爱糖宝
  • 2024-06-15
  • 2075
  • 0
  • 0

ServerHttpObservationFilter 是一个继承自 OncePerRequestFilter 的Spring框架过滤器类。这个过滤器的目的是用于观察和记录HTTP请求和响应的相关数据,通常用于监控、日志记录、性能评估等场景。它使用 ObservationRegistry 来注册和存储观察结果,并可以自定义观察约定(ServerRequestObservationConvention)。

业务场景:

在一个大型的分布式系统中,服务之间的调用非常频繁,监控这些服务的性能和行为对于维护整个系统的稳定性和可靠性至关重要。ServerHttpObservationFilter 可以帮助开发者实现以下目标:

  • 性能监控:记录请求处理时间,分析慢请求。

  • 错误跟踪:捕获和记录服务器端的异常,帮助快速定位问题。

  • 安全审计:记录关键请求和响应,用于安全分析和合规性检查。

  • 流量分析:观察请求模式和流量分布,以优化资源分配。

关键处理代码:

以下是 ServerHttpObservationFilter 类的一些关键处理代码:

  1. 构造函数:接收 ObservationRegistry 和 ServerRequestObservationConvention 对象,用于记录观察结果和定义观察细节。

public ServerHttpObservationFilter(ObservationRegistry observationRegistry, ServerRequestObservationConvention observationConvention) {
    this.observationRegistry = observationRegistry;
    this.observationConvention = observationConvention;
}

  1. doFilterInternal 方法:实现过滤器的主要逻辑,创建或获取 Observation 对象,并在请求处理过程中进行观察。

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {
    Observation observation = createOrFetchObservation(request, response);
    try (Observation.Scope scope = observation.openScope()) {
        filterChain.doFilter(request, response);
    } catch (Exception ex) {
        observation.error(unwrapServletException(ex));
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        throw ex;
    } finally {
        // 处理异步请求和观察结束
    }
}

  1. createOrFetchObservation 方法:创建或获取与当前请求关联的 Observation 对象。

private Observation createOrFetchObservation(HttpServletRequest request, HttpServletResponse response) {
    Observation observation = (Observation) request.getAttribute(CURRENT_OBSERVATION_ATTRIBUTE);
    if (observation == null) {
        ServerRequestObservationContext context = new ServerRequestObservationContext(request, response);
        observation = ServerHttpObservationDocumentation.HTTP_SERVLET_SERVER_REQUESTS.observation(this.observationConvention, DEFAULT_OBSERVATION_CONVENTION, () -> context, this.observationRegistry).start();
        request.setAttribute(CURRENT_OBSERVATION_ATTRIBUTE, observation);
    }
    return observation;
}

  1. 异常处理:在 doFilterInternal 方法中,通过 catch 块捕获异常,并使用 Observation 对象记录错误信息。

  2. 请求结束后的处理:在 finally 块中,如果请求不是异步的,结束 Observation 并记录任何异常。

启用方式

1. 创建 ObservationRegistry Bean

ObservationRegistry 是用于注册和存储观察结果的组件。你需要在你的 Spring 配置类中创建它的 Bean:

@Bean
public ObservationRegistry observationRegistry() {
    return new ObservationRegistry();
}

2. 配置 ServerHttpObservationFilter

创建 ServerHttpObservationFilter 的 Bean,并注入 ObservationRegistry。你还可以提供一个自定义的 ServerRequestObservationConvention,用于定义如何命名和标记观察结果:

@Bean
public ServerHttpObservationFilter serverHttpObservationFilter(ObservationRegistry observationRegistry) {
    return new ServerHttpObservationFilter(observationRegistry);
}

3. 注册过滤器

ServerHttpObservationFilter 注册为应用程序的一个过滤器。如果你使用的是 Servlet API,可以在 web.xml 中注册,或者使用 FilterRegistrationBean

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<ServerHttpObservationFilter> serverHttpObservationFilterRegistration(
            ServerHttpObservationFilter serverHttpObservationFilter) {
        FilterRegistrationBean<ServerHttpObservationFilter> registrationBean =
                new FilterRegistrationBean<>(serverHttpObservationFilter);
        registrationBean.addUrlPatterns("/*");
        return registrationBean;
    }
}

4. 使用观察上下文

在应用程序的其他部分,你可能需要访问当前请求的观察上下文。可以使用 ServerHttpObservationFilter 提供的静态方法来获取:

public void someBusinessLogic(HttpServletRequest request) {
    ServerRequestObservationContext observationContext =
            ServerHttpObservationFilter.findObservationContext(request)
                    .orElse(null);
    if (observationContext != null) {
        // 使用 observationContext 进行业务逻辑
    }
}

目的:

ServerHttpObservationFilter 的使用目的在于为基于Spring框架的Web应用程序提供一种机制,以便于捕获和记录HTTP请求和响应的详细信息,从而帮助开发者更好地理解和优化应用程序的行为。通过这种方式,可以提高应用程序的可观测性,增强其稳定性和性能。

0条评论

您的电子邮件等信息不会被公开,以下所有项均必填

OK! You can skip this field.