Spring CommandLineRunner结合Actuator:WebApplicationType.NONE控制台应用如何暴露Prometheus指标端点?
Got it, let's break down why this is happening and how to fix it. When you set WebApplicationType.NONE, Spring Boot disables all web-related auto-configuration—including the embedded server that Actuator relies on to expose HTTP endpoints. That's why your metrics endpoints aren't accessible. Here are three solid solutions depending on your needs:
Solution 1: Use JMX Endpoints + Prometheus JMX Exporter (No Web Server Required)
If you want to avoid spinning up any web server entirely, this approach uses JMX to expose metrics, then lets Prometheus scrape them via a dedicated exporter.
Enable JMX endpoints in your application config (
application.propertiesorapplication.yml):# Expose all JMX endpoints (restrict to metrics/prometheus if needed) management.endpoints.jmx.exposure.include=* management.endpoint.metrics.enabled=true management.endpoint.prometheus.enabled=trueSet up the Prometheus JMX Exporter:
- Grab the latest JMX Exporter JAR from Maven Central.
- Create a simple
config.yamlto define metric scraping rules (this example captures all metrics):lowercaseOutputName: true rules: - pattern: '.*' - Start your application with the JMX agent attached:
java -javaagent:./jmx_prometheus_javaagent-<version>.jar=9091:config.yaml -jar your-app.jar
The exporter will run on port 9091, and Prometheus can scrape metrics from
http://localhost:9091/metrics.
Solution 2: Spin Up a Lightweight Web Server for Actuator Endpoints
If you don't mind a minimal web server running just for Actuator, this is the most straightforward approach.
Option A: Force web type while keeping console app behavior
Adjust your main application class to explicitly enable servlet web support, even if you want a console-focused app:
@SpringBootApplication public class ConsoleApp implements CommandLineRunner { public static void main(String[] args) { new SpringApplicationBuilder(ConsoleApp.class) .web(WebApplicationType.SERVLET) // Force servlet web environment .run(args); } @Override public void run(String... args) throws Exception { // Your periodic task logic here (pair with @EnableScheduling if using @Scheduled) } }
Option B: Exclude unnecessary web config
If you want to avoid loading full Spring MVC/Flux, exclude those auto-config classes:
@SpringBootApplication(exclude = {WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class}) public class ConsoleApp implements CommandLineRunner { // ... rest of your code }
Then configure Actuator to expose HTTP endpoints:
management.endpoints.web.exposure.include=prometheus,metrics management.server.port=8081 # Use a separate port to avoid conflicts management.server.servlet.context-path=/actuator
Now you can access Prometheus metrics at http://localhost:8081/actuator/prometheus.
Solution 3: Push Metrics to Prometheus PushGateway
If you prefer your console app to actively send metrics to Prometheus (instead of being scraped), use Micrometer's PushGateway integration.
Add PushGateway dependencies (Maven example):
<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency> <dependency> <groupId>io.prometheus</groupId> <artifactId>simpleclient_pushgateway</artifactId> </dependency>Configure PushGateway in your app config:
management.metrics.export.prometheus.pushgateway.enabled=true management.metrics.export.prometheus.pushgateway.base-url=http://your-pushgateway-host:9091 management.metrics.export.prometheus.pushgateway.job=your-console-app-name management.metrics.export.prometheus.pushgateway.push-rate=60s # Push metrics every minute
Your app will now send metrics directly to the PushGateway, and Prometheus can scrape the gateway instead of your app.
内容的提问来源于stack exchange,提问作者Jakub Bręk

