You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Spring Actuator的/health端点单独发布到9999端口?

Hey there! Great question—separating the /health endpoint to a dedicated port while keeping other Actuator endpoints on the default management port is totally doable in Spring Boot. Let me walk you through two reliable approaches depending on your Spring Boot version and preferences:

This method spins up a separate lightweight web server just for the /health endpoint, keeping it isolated from other Actuator endpoints. Works for Spring Boot 2.x and 3.x.

Step 1: Configure Application Properties

First, update your application.yml (or application.properties) to exclude /health from the default management server and set up your ports:

server:
  port: 8080 # Your main application port (adjust as needed)

management:
  server:
    port: 8081 # Port for all Actuator endpoints EXCEPT /health
  endpoints:
    web:
      exposure:
        include: "*"
        exclude: "health" # Keep /health off the default management port
  endpoint:
    health:
      enabled: true # Ensure the health endpoint itself is active

Step 2: Add Configuration for the Dedicated Health Server

Create a configuration class to launch a separate web server on port 9999, and proxy the /health endpoint to it:

import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@Configuration
public class HealthPortConfiguration {

    @Bean
    public AnnotationConfigServletWebServerApplicationContext healthServerContext(HealthEndpoint healthEndpoint) {
        // Create a standalone context for the 9999 port server
        AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext();
        
        // Reuse the health endpoint bean from the main application context
        context.getBeanFactory().registerSingleton("healthEndpoint", healthEndpoint);
        
        // Register our proxy controller for the health endpoint
        context.register(HealthProxyConfig.class);
        
        // Set the server port to 9999
        TomcatServletWebServerFactory serverFactory = new TomcatServletWebServerFactory(9999);
        context.setServletWebServerFactory(serverFactory);
        
        // Start the context
        context.refresh();
        return context;
    }

    // Proxy controller that only responds on the 9999 port
    @RestController
    static class HealthProxyController {
        private final HealthEndpoint healthEndpoint;

        public HealthProxyController(HealthEndpoint healthEndpoint) {
            this.healthEndpoint = healthEndpoint;
        }

        @GetMapping("/actuator/health")
        public Health getHealth() {
            // Delegate to the actual health endpoint
            return healthEndpoint.health();
        }
    }

    @Configuration
    static class HealthProxyConfig {
        @Bean
        public HealthProxyController healthProxyController(HealthEndpoint healthEndpoint) {
            return new HealthProxyController(healthEndpoint);
        }
    }
}

What This Does:

  • 8080: Main application, no Actuator endpoints exposed
  • 8081: All Actuator endpoints except /health
  • 9999: Only the /actuator/health endpoint is accessible

Approach 2: Interceptor-Based Port Restriction

If you prefer not to spin up a separate server, you can use a request interceptor to block endpoints based on the incoming port. This works best for Spring Boot 2.x.

Step 1: Base Configuration

Start with this application.yml:

server:
  port: 8080

management:
  server:
    port: 8081
  endpoints:
    web:
      exposure:
        include: "*"

Step 2: Add Interceptor and Extra Server

Create a configuration class to add a port-checking interceptor and launch the 9999 port server:

import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoints;
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoints;
import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Configuration
public class ActuatorPortRestrictionConfig {

    @Bean
    public WebMvcEndpointHandlerMapping webMvcEndpointHandlerMapping(
            ServletEndpoints servletEndpoints,
            ControllerEndpoints controllerEndpoints,
            WebMvcEndpointHandlerMapping.WebMvcEndpointHandlerMappingConfiguration configuration) {
        
        WebMvcEndpointHandlerMapping mapping = new WebMvcEndpointHandlerMapping(
                servletEndpoints, controllerEndpoints, configuration.getPrefix(),
                configuration.getEndpointsByRequestPredicate(),
                configuration.getCorsConfiguration());
        
        // Add interceptor to restrict endpoints by port
        mapping.setInterceptors(new HandlerInterceptor() {
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                String requestURI = request.getRequestURI();
                int localPort = request.getLocalPort();

                // Enforce rules:
                // 9999 port only allows /actuator/health
                if (localPort == 9999) {
                    if (!requestURI.equals("/actuator/health")) {
                        response.sendError(HttpServletResponse.SC_NOT_FOUND);
                        return false;
                    }
                }
                // 8081 port blocks /actuator/health
                else if (localPort == 8081 && requestURI.equals("/actuator/health")) {
                    response.sendError(HttpServletResponse.SC_NOT_FOUND);
                    return false;
                }
                return true;
            }
        });
        
        return mapping;
    }

    // Launch the extra server on port 9999
    @Bean
    public ServletWebServerFactory healthServerFactory() {
        return new TomcatServletWebServerFactory(9999);
    }
}

What This Does:

  • The interceptor checks the incoming port and blocks unauthorized endpoints
  • 9999: Only /actuator/health works; other paths return 404
  • 8081: All Actuator endpoints work except /health
  • 8080: Main application, no Actuator endpoints

内容的提问来源于stack exchange,提问作者Always_Beginner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:41:59