Spring Boot Actuator 学习笔记

概述

Spring Boot Actuator是Spring Boot提供的生产就绪功能模块,它为Spring Boot应用程序提供了很多监控和管理功能。通过Actuator,我们可以查看应用程序的内部状态、健康状况、指标信息、配置详情等。

Actuator提供了RESTful API端点,可以轻松集成到监控系统中,是微服务架构中不可或缺的组件。本教程将详细介绍Actuator的核心功能、配置方法以及在生产环境中的最佳实践。

核心价值与用途

应用监控:实时查看应用健康状况、性能指标(如请求数量、响应时间)、资源使用情况等。

问题诊断:当应用出现问题时,可以通过暴露的端点获取线程转储、堆内存信息、日志级别等,快速定位问题。

运行状况管理:提供就绪和存活状态探针,与 Kubernetes 等容器编排平台无缝集成,用于服务发现和滚动更新。

审计与管理:查看应用配置、环境变量、Bean 定义,甚至可以动态修改日志级别。

核心概念

端点(Endpoints)

端点是Actuator提供的REST API,每个端点都提供特定的功能:

应用配置类端点:显示应用程序的配置信息

指标类端点:显示应用程序的指标信息

操作控制类端点:提供关闭应用程序等操作

暴露方式

HTTP:通过HTTP请求访问端点

JMX:通过JMX MBean访问端点

WebSocket:通过WebSocket连接访问端点

环境准备

Maven依赖

java 复制代码
<dependencies>
    <!-- Spring Boot Actuator -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- 监控指标 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <!-- Micrometer (可选,用于自定义指标) -->
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-registry-prometheus</artifactId>
    </dependency>

    <!-- 安全配置 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
</dependencies>

基础配置

java 复制代码
server:
  port: 8080

management:
  endpoints:
    web:
      exposure:
        # 暴露所有端点
        include: "*"
      base-path: /actuator
  endpoint:
    shutdown:
      enabled: true
    health:
      show-details: when-authorized
  security:
    enabled: true

info:
  app:
    name: @project.name@
    description: @project.description@
    version: @project.version@
    java:
      version: @java.version@

内置端点

健康检查端点

java 复制代码
@RestController
@RequestMapping("/actuator/health")
public class HealthController {

    @Autowired
    private HealthIndicatorRegistry healthIndicatorRegistry;

    @GetMapping
    public Health health() {
        Health.Builder builder = Health.up();

        // 检查数据库连接
        try {
            // 数据库连接检查逻辑
            builder.withDetail("database", "连接正常");
        } catch (Exception e) {
            builder.down().withDetail("database", e.getMessage());
        }

        // 检查外部服务
        try {
            // 外部服务检查逻辑
            builder.withDetail("external-service", "服务正常");
        } catch (Exception e) {
            builder.status("WARN").withDetail("external-service", e.getMessage());
        }

        return builder.build();
    }
}

// 自定义健康指示器
@Component
public class CustomHealthIndicator implements HealthIndicator {

    @Override
    public Health health() {
        // 执行健康检查逻辑
        boolean healthy = checkHealth();

        if (healthy) {
            return Health.up()
                    .withDetail("status", "Custom service is running")
                    .build();
        } else {
            return Health.down()
                    .withDetail("error", "Custom service is down")
                    .build();
        }
    }

    private boolean checkHealth() {
        // 自定义健康检查逻辑
        return true;
    }
}

// 数据库健康指示器
@Configuration
public class DatabaseHealthConfig {

    @Bean
    public DataSourceHealthIndicator dataSourceHealthIndicator(DataSource dataSource) {
        return new DataSourceHealthIndicator(dataSource, "SELECT 1");
    }
}

应用信息端点

java 复制代码
@Configuration
public class InfoConfig {

    @Bean
    public InfoContributor customInfoContributor() {
        return builder -> {
            Map<String, Object> details = new HashMap<>();
            details.put("build", Map.of(
                "artifact", "my-app",
                "name", "My Application",
                "time", new Date().toString(),
                "version", "1.0.0",
                "group", "com.example"
            ));

            details.put("system", Map.of(
                "java.version", System.getProperty("java.version"),
                "os.name", System.getProperty("os.name"),
                "os.arch", System.getProperty("os.arch"),
                "processors", Runtime.getRuntime().availableProcessors()
            ));

            builder.withDetails(details);
        };
    }
}

// Git信息贡献者
@Configuration
public class GitInfoConfig {

    @Bean
    public GitInfoContributor gitInfoContributor() {
        return new GitInfoContributor();
    }
}

// 环境信息贡献者
@Configuration
public class EnvironmentInfoConfig {

    @Autowired
    private Environment environment;

    @Bean
    public InfoContributor environmentInfoContributor() {
        return builder -> {
            Map<String, Object> envDetails = new HashMap<>();
            envDetails.put("activeProfiles", Arrays.toString(environment.getActiveProfiles()));
            envDetails.put("defaultProfiles", Arrays.toString(environment.getDefaultProfiles()));

            builder.withDetail("environment", envDetails);
        };
    }
}

指标端点

java 复制代码
@Service
public class MetricsService {

    @Autowired
    private MeterRegistry meterRegistry;

    // 计数器
    private final Counter requestCounter = Counter.builder("http_requests_total")
            .description("Total number of HTTP requests")
            .tags("method", "GET")
            .register(meterRegistry);

    // 计时器
    private final Timer requestTimer = Timer.builder("http_request_duration")
            .description("HTTP request duration")
            .tags("method", "GET")
            .register(meterRegistry);

    // 仪表
    private final Gauge activeUsers = Gauge.builder("active_users", this, MetricsService::getActiveUsers)
            .description("Number of active users")
            .register(meterRegistry);

    public void recordRequest() {
        requestCounter.increment();
    }

    public void recordRequestDuration(long duration) {
        requestTimer.record(Duration.ofMillis(duration));
    }

    private double getActiveUsers() {
        // 获取活跃用户数的逻辑
        return 42.0;
    }
}

// HTTP请求指标
@Configuration
public class HttpMetricsConfig {

    @Bean
    public TimedAspect timedAspect(MeterRegistry meterRegistry) {
        return new TimedAspect(meterRegistry);
    }
}

@RestController
public class SampleController {

    @Autowired
    private MetricsService metricsService;

    @GetMapping("/api/data")
    @Timed(value = "api.data.requests", description = "Time taken to process data requests")
    public String getData() {
        long startTime = System.currentTimeMillis();

        // 记录请求
        metricsService.recordRequest();

        try {
            // 模拟处理时间
            Thread.sleep(100);
            return "Data response";
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return "Error";
        } finally {
            // 记录请求持续时间
            long duration = System.currentTimeMillis() - startTime;
            metricsService.recordRequestDuration(duration);
        }
    }
}

配置属性端点

java 复制代码
@Configuration
public class ConfigPropsConfig {

    @Bean
    public ConfigPropsEndpoint configPropsEndpoint(Collection<ConfigurationPropertiesBean> configPropsBeans) {
        return new ConfigPropsEndpoint(configPropsBeans);
    }
}

// 自定义配置属性
@ConfigurationProperties(prefix = "app.custom")
public class CustomProperties {

    private String name;
    private int value;
    private List<String> items;

    // getters and setters
}

// 端点过滤器
@Configuration
public class EndpointFilterConfig {

    @Bean
    public EndpointFilter<ConfigPropsEndpoint> configPropsFilter() {
        return new EndpointFilter<ConfigPropsEndpoint>() {
            @Override
            public ConfigPropsEndpoint filter(ConfigPropsEndpoint endpoint) {
                // 过滤敏感配置信息
                return endpoint;
            }
        };
    }
}

日志端点

java 复制代码
@Configuration
public class LoggingConfig {

    @Bean
    public LoggingEndpoint loggingEndpoint() {
        return new LoggingEndpoint();
    }
}

// 动态日志级别配置
@RestController
@RequestMapping("/actuator/logging")
public class LoggingController {

    @Autowired
    private LoggingSystem loggingSystem;

    @PostMapping("/level")
    public void setLogLevel(@RequestParam String logger, @RequestParam String level) {
        loggingSystem.setLogLevel(logger, LogLevel.valueOf(level.toUpperCase()));
    }

    @GetMapping("/level")
    public Map<String, Object> getLogLevel(@RequestParam String logger) {
        Map<String, Object> result = new HashMap<>();
        result.put("logger", logger);
        result.put("level", loggingSystem.getLoggerConfiguration(logger));
        return result;
    }
}

自定义端点

基础自定义端点

java 复制代码
@Component
@Endpoint(id = "custom")
public class CustomEndpoint {

    @ReadOperation
    public Map<String, Object> custom() {
        Map<String, Object> result = new HashMap<>();
        result.put("message", "Custom endpoint response");
        result.put("timestamp", System.currentTimeMillis());
        return result;
    }

    @ReadOperation
    public Map<String, Object> customWithParam(@Selector String param) {
        Map<String, Object> result = new HashMap<>();
        result.put("param", param);
        result.put("processed", "Processed: " + param);
        return result;
    }

    @WriteOperation
    public Map<String, Object> updateCustom(@Selector String param, @RequestBody Map<String, Object> body) {
        Map<String, Object> result = new HashMap<>();
        result.put("action", "update");
        result.put("param", param);
        result.put("body", body);
        return result;
    }

    @DeleteOperation
    public Map<String, Object> deleteCustom(@Selector String param) {
        Map<String, Object> result = new HashMap<>();
        result.put("action", "delete");
        result.put("param", param);
        return result;
    }
}

// 带Web扩展的自定义端点
@Component
@WebEndpoint(id = "advanced-custom")
public class AdvancedCustomEndpoint {

    @GetMapping("/details")
    @ReadOperation
    public WebEndpointResponse<Map<String, Object>> getDetails() {
        Map<String, Object> details = new HashMap<>();
        details.put("version", "1.0.0");
        details.put("status", "active");

        return new WebEndpointResponse<>(details, 200);
    }

    @PostMapping("/action")
    @WriteOperation
    public WebEndpointResponse<String> performAction(@RequestBody Map<String, Object> action) {
        // 执行操作逻辑
        return new WebEndpointResponse<>("Action performed successfully", 200);
    }
}

业务指标端点

java 复制代码
@Component
@Endpoint(id = "business-metrics")
public class BusinessMetricsEndpoint {

    @Autowired
    private MeterRegistry meterRegistry;

    @ReadOperation
    public Map<String, Object> businessMetrics() {
        Map<String, Object> metrics = new HashMap<>();

        // 获取业务指标
        Counter orderCounter = meterRegistry.find("orders.total").counter();
        if (orderCounter != null) {
            metrics.put("totalOrders", orderCounter.count());
        }

        Timer orderTimer = meterRegistry.find("orders.processing.time").timer();
        if (orderTimer != null) {
            metrics.put("averageOrderProcessingTime", orderTimer.mean(Duration.ofMillis(1)));
        }

        Gauge activeSessions = meterRegistry.find("sessions.active").gauge();
        if (activeSessions != null) {
            metrics.put("activeSessions", activeSessions.value());
        }

        return metrics;
    }

    @ReadOperation
    public Map<String, Object> businessMetricsByType(@Selector String type) {
        Map<String, Object> metrics = new HashMap<>();
        metrics.put("type", type);

        switch (type.toLowerCase()) {
            case "orders":
                metrics.putAll(getOrderMetrics());
                break;
            case "users":
                metrics.putAll(getUserMetrics());
                break;
            case "revenue":
                metrics.putAll(getRevenueMetrics());
                break;
            default:
                metrics.put("error", "Unknown metric type: " + type);
        }

        return metrics;
    }

    private Map<String, Object> getOrderMetrics() {
        Map<String, Object> metrics = new HashMap<>();
        // 获取订单相关指标
        return metrics;
    }

    private Map<String, Object> getUserMetrics() {
        Map<String, Object> metrics = new HashMap<>();
        // 获取用户相关指标
        return metrics;
    }

    private Map<String, Object> getRevenueMetrics() {
        Map<String, Object> metrics = new HashMap<>();
        // 获取收入相关指标
        return metrics;
    }
}

缓存端点

java 复制代码
@Component
@Endpoint(id = "cache")
public class CacheEndpoint {

    @Autowired
    private CacheManager cacheManager;

    @ReadOperation
    public Map<String, Object> cacheInfo() {
        Map<String, Object> result = new HashMap<>();

        for (String cacheName : cacheManager.getCacheNames()) {
            Cache cache = cacheManager.getCache(cacheName);
            Map<String, Object> cacheInfo = new HashMap<>();
            cacheInfo.put("name", cacheName);
            cacheInfo.put("nativeCache", cache.getNativeCache().getClass().getSimpleName());

            // 如果是Caffeine缓存,获取更多信息
            if (cache.getNativeCache() instanceof com.github.benmanes.caffeine.cache.Cache) {
                com.github.benmanes.caffeine.cache.Cache nativeCache =
                    (com.github.benmanes.caffeine.cache.Cache) cache.getNativeCache();
                cacheInfo.put("estimatedSize", nativeCache.estimatedSize());
            }

            result.put(cacheName, cacheInfo);
        }

        return result;
    }

    @WriteOperation
    public Map<String, Object> clearCache(@Selector String cacheName) {
        Cache cache = cacheManager.getCache(cacheName);
        if (cache != null) {
            cache.clear();
            return Map.of("message", "Cache '" + cacheName + "' cleared successfully");
        } else {
            return Map.of("error", "Cache '" + cacheName + "' not found");
        }
    }

    @ReadOperation
    public Map<String, Object> cacheStats(@Selector String cacheName) {
        Map<String, Object> stats = new HashMap<>();

        Cache cache = cacheManager.getCache(cacheName);
        if (cache != null && cache.getNativeCache() instanceof com.github.benmanes.caffeine.cache.Cache) {
            com.github.benmanes.caffeine.cache.Cache nativeCache =
                (com.github.benmanes.caffeine.cache.Cache) cache.getNativeCache();

            stats.put("cacheName", cacheName);
            stats.put("estimatedSize", nativeCache.estimatedSize());
            // 可以添加更多统计信息
        } else {
            stats.put("error", "Cache statistics not available for '" + cacheName + "'");
        }

        return stats;
    }
}

安全配置

基本安全配置

java 复制代码
@Configuration
@EnableWebSecurity
public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                // 允许公开访问健康检查端点
                .antMatchers("/actuator/health").permitAll()
                // 允许公开访问应用信息端点
                .antMatchers("/actuator/info").permitAll()
                // 其他Actuator端点需要认证
                .antMatchers("/actuator/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            .and()
            .httpBasic(); // 使用HTTP Basic认证
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("admin")
                .password("{noop}admin123")
                .roles("ADMIN");
    }
}

// 基于角色的访问控制
@Configuration
public class RoleBasedSecurityConfig {

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        return http
            .authorizeExchange()
                .pathMatchers("/actuator/health/**").permitAll()
                .pathMatchers("/actuator/info/**").permitAll()
                .pathMatchers("/actuator/metrics/**").hasRole("MONITOR")
                .pathMatchers("/actuator/**").hasRole("ADMIN")
                .anyExchange().authenticated()
            .and()
            .httpBasic()
            .and()
            .build();
    }
}

端点访问控制

java 复制代码
@Configuration
public class EndpointAccessConfig {

    @Bean
    public EndpointRequest.EndpointRequestMatcher endpointRequestMatcher() {
        return EndpointRequest.toAnyEndpoint();
    }

    @Bean
    public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
        return new SecurityEvaluationContextExtension();
    }
}

// 自定义端点访问决策
@Component
public class CustomEndpointAccessDecisionVoter implements AccessDecisionVoter<FilterInvocation> {

    @Override
    public boolean supports(ConfigAttribute attribute) {
        return attribute instanceof SecurityConfig &&
               ("ROLE_ADMIN".equals(attribute.getAttribute()) ||
                "ROLE_MONITOR".equals(attribute.getAttribute()));
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return FilterInvocation.class.isAssignableFrom(clazz);
    }

    @Override
    public int vote(Authentication authentication, FilterInvocation object,
                   Collection<ConfigAttribute> attributes) {

        if (authentication == null) {
            return ACCESS_DENIED;
        }

        // 检查用户是否有访问端点的权限
        for (ConfigAttribute attribute : attributes) {
            if (this.supports(attribute)) {
                String requiredRole = attribute.getAttribute();

                for (GrantedAuthority authority : authentication.getAuthorities()) {
                    if (requiredRole.equals(authority.getAuthority())) {
                        return ACCESS_GRANTED;
                    }
                }
            }
        }

        return ACCESS_DENIED;
    }
}

监控集成

java 复制代码
Prometheus集成
management:
  metrics:
    export:
      prometheus:
        enabled: true
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
java 复制代码
@Configuration
public class PrometheusConfig {

    @Bean
    public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
        return registry -> registry.config()
                .commonTags("application", "my-app")
                .commonTags("instance", getInstanceId());
    }

    @Bean
    public PrometheusMeterRegistry prometheusMeterRegistry(PrometheusConfig config) {
        return new PrometheusMeterRegistry(config);
    }

    private String getInstanceId() {
        // 获取实例ID的逻辑
        return "instance-1";
    }
}

// 自定义Prometheus指标
@Service
public class PrometheusMetricsService {

    @Autowired
    private MeterRegistry meterRegistry;

    public void recordBusinessMetric(String name, double value, String... tags) {
        Gauge.builder(name, () -> value)
                .description("Business metric: " + name)
                .tags(tags)
                .register(meterRegistry);
    }

    public void incrementCounter(String name, String... tags) {
        Counter.builder(name)
                .description("Counter: " + name)
                .tags(tags)
                .register(meterRegistry)
                .increment();
    }

    public void recordTimer(String name, Duration duration, String... tags) {
        Timer.builder(name)
                .description("Timer: " + name)
                .tags(tags)
                .register(meterRegistry)
                .record(duration);
    }
}

Grafana集成

java 复制代码
@Configuration
public class GrafanaConfig {

    @Bean
    public MeterRegistryCustomizer<MeterRegistry> grafanaMetrics() {
        return registry -> registry.config()
                .commonTags("service", "my-service")
                .commonTags("environment", "production");
    }
}

// Grafana仪表板配置
@Component
@Endpoint(id = "grafana")
public class GrafanaEndpoint {

    @ReadOperation
    public Map<String, Object> getDashboardConfig() {
        Map<String, Object> dashboard = new HashMap<>();

        dashboard.put("title", "Application Metrics Dashboard");
        dashboard.put("description", "Spring Boot Actuator Metrics Dashboard");

        List<Map<String, Object>> panels = new ArrayList<>();

        // JVM内存面板
        Map<String, Object> jvmMemoryPanel = new HashMap<>();
        jvmMemoryPanel.put("title", "JVM Memory");
        jvmMemoryPanel.put("type", "graph");
        jvmMemoryPanel.put("targets", Arrays.asList(
            Map.of("expr", "jvm_memory_used_bytes{area=\"heap\"}", "legendFormat", "Heap Used"),
            Map.of("expr", "jvm_memory_used_bytes{area=\"nonheap\"}", "legendFormat", "Non-Heap Used")
        ));
        panels.add(jvmMemoryPanel);

        // HTTP请求面板
        Map<String, Object> httpRequestsPanel = new HashMap<>();
        httpRequestsPanel.put("title", "HTTP Requests");
        httpRequestsPanel.put("type", "graph");
        httpRequestsPanel.put("targets", Arrays.asList(
            Map.of("expr", "http_server_requests_seconds_count", "legendFormat", "Total Requests"),
            Map.of("expr", "http_server_requests_seconds_sum", "legendFormat", "Request Duration")
        ));
        panels.add(httpRequestsPanel);

        dashboard.put("panels", panels);

        return dashboard;
    }
}

生产环境配置

端点分组

java 复制代码
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,env,configprops
        exclude: shutdown,heapdump
      base-path: /management

  endpoint:
    health:
      show-details: when-authorized
      probes:
        enabled: true

    metrics:
      enabled: true

    env:
      show-values: when-authorized

  group:
    # 监控组 - 只读端点
    monitor:
      include: health,info,metrics
    # 管理组 - 包含写操作端点
    admin:
      include: "*"
      exclude: heapdump

健康探测

java 复制代码
@Configuration
public class HealthProbesConfig {

    @Bean
    public HealthIndicator livenessIndicator() {
        return () -> Health.up()
                .withDetail("liveness", "Application is alive")
                .build();
    }

    @Bean
    public HealthIndicator readinessIndicator() {
        return () -> {
            // 检查应用是否准备好接收流量
            boolean ready = checkReadiness();

            if (ready) {
                return Health.up()
                        .withDetail("readiness", "Application is ready")
                        .build();
            } else {
                return Health.down()
                        .withDetail("readiness", "Application is not ready")
                        .build();
            }
        };
    }

    private boolean checkReadiness() {
        // 检查数据库连接、外部服务等
        return true;
    }
}

性能监控

java 复制代码
@Configuration
public class PerformanceMonitoringConfig {

    @Bean
    public MeterRegistryCustomizer<MeterRegistry> performanceMetrics() {
        return registry -> registry.config()
                .meterFilter(MeterFilter.denyNameStartsWith("jvm"))
                .meterFilter(MeterFilter.denyNameStartsWith("system"))
                .meterFilter(MeterFilter.maximumAllowableMetrics(1000))
                .meterFilter(MeterFilter.maximumAllowableTags("method", "uri", 100));
    }

    @Bean
    public TimedAspect timedAspect(MeterRegistry meterRegistry) {
        return new TimedAspect(meterRegistry,
                new TimedAspectConfig()
                        .setEnabled(true)
                        .setAutoTimeRequests(true)
                        .setPercentiles(new double[]{0.5, 0.95, 0.99}));
    }
}

故障排查

常见问题

1、端点无法访问

检查端点是否已暴露

验证安全配置

确认Base Path配置

2、指标数据不准确

检查MeterRegistry配置

验证指标命名规范

确认时间单位设置

3、健康检查失败

检查依赖服务的状态

验证数据库连接

查看应用日志

4、性能问题

监控端点响应时间

检查指标收集频率

优化端点暴露策略

调试配置

java 复制代码
@Configuration
public class DebugConfig {

    @Bean
    public ApplicationEventListener<ContextRefreshedEvent> debugListener() {
        return event -> {
            ApplicationContext context = event.getApplicationContext();

            // 打印所有端点信息
            Map<String, Object> endpoints = context.getBeansWithAnnotation(Endpoint.class);
            System.out.println("Available Endpoints:");
            endpoints.forEach((name, bean) -> {
                Endpoint endpoint = bean.getClass().getAnnotation(Endpoint.class);
                System.out.println("- " + endpoint.id() + ": " + bean.getClass().getSimpleName());
            });
        };
    }
}

// 端点访问日志
@Configuration
public class EndpointLoggingConfig {

    @Bean
    public FilterRegistrationBean<EndpointLoggingFilter> endpointLoggingFilter() {
        FilterRegistrationBean<EndpointLoggingFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new EndpointLoggingFilter());
        registrationBean.addUrlPatterns("/actuator/*");
        return registrationBean;
    }
}

public class EndpointLoggingFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        long startTime = System.currentTimeMillis();

        try {
            chain.doFilter(request, response);
        } finally {
            long duration = System.currentTimeMillis() - startTime;
            System.out.println("Endpoint " + httpRequest.getRequestURI() +
                    " took " + duration + "ms, status: " + httpResponse.getStatus());
        }
    }
}

最佳实践

1. 端点管理

根据环境选择合适的端点暴露策略

使用端点分组提高安全性

定期检查端点状态

2. 安全配置

实施最小权限原则

使用HTTPS保护端点通信

定期轮换认证凭据

3. 监控策略

定义关键指标和告警阈值

建立监控仪表板

实施自动化监控

4. 性能优化

控制指标收集频率

使用异步端点处理

实施缓存策略

5. 运维集成

与现有监控系统集成

建立自动化部署流程

实施日志聚合和分析

相关推荐
名誉寒冰2 小时前
AI云存储学习笔记:小文件优化 / 大文件分片 / 分享与 AI 搜索
linux·人工智能·笔记·学习
Calebbbbb2 小时前
如何用 GitHub 下载单一目录 / 子目录
笔记·github
嵌入式×边缘AI:打怪升级日志2 小时前
USB设备枚举过程详解:从插入到正常工作
开发语言·数据库·笔记
学习是生活的调味剂2 小时前
在大模型开发中,是否需要先完整学习 TensorFlow,再学 PyTorch?
pytorch·学习·tensorflow·transformers
笨鸟先飞的橘猫2 小时前
mongo权威指南(第三版)学习笔记
笔记·学习
技术小泽2 小时前
java转go速成入门笔记篇(一)
java·笔记·golang
诺狞猫2 小时前
黄山派播放TF卡MP4视频
学习·音视频·思澈·sifli
Noushiki2 小时前
RabbitMQ 进阶 学习笔记2
笔记·学习·rabbitmq
lpfasd1232 小时前
Spring AI 集成国内大模型实战:千问/豆包(含多模态)+ Spring Boot 4.0.1 全攻略
人工智能·spring boot·spring