Skip to content

修改 Actuator 路径和端口

🏷️ Spring Boot Actuator

spring-boot-starter-actuator 是用来监控系统健康状况的一个很强大的工具,但是默认配置的情况下,路径都是通用的(/actuator),很容易导致泄露系统的重要信息。

可以通过修改监控地址的路径来避免被别人轻易的就访问到,更安全的做法是将其端口同服务的端口区分开,并禁止外网访问。

调查的时候还看到说可以通过设置 management.security.enabledtrue 并配合 Spring Security 来实现通过密码来访问,但是没有成功。貌似是因为 2.x 中取消了这个配置项。security.user.password 配置了也没起作用。

修改 actuator 路径

通过 management.endpoints.web.base-path 可以指定自定义路径。

yml
management:
  endpoints:
    web:
      base-path: /customize-actuator

配合 Spring Boot Admin 工具监控时,Admin 中需要修改 management.context-path 的值以匹配服务的修改。

yml
management:
  context-path: /customize-actuator

修改 actuator 端口

这里 看到可以通过 management.server.port 指定管理的端口。

yml
management:
  server:
    port: 8888

通过指定这个配置项的值可以成功的修改 actuator 的端口号,但是遇到两个意料之外的问题。

1. IllegalStateException

修改了端口号后启动部分应用报如下错误:

IllegalStateException: availableProcessors is already set to [8], rejecting [8]

参考 这篇文章另一篇文章SpringApplication.run 之前添加如下代码即可解决问题。

java
System.setProperty("es.set.netty.runtime.available.processors", "false");

2. UnsatisfiedDependencyException

Quartz 项目中创建 SchedulerFactoryBean 时使用了 DynamicRoutingDataSource 来获取 DataSource ,但是项目启动时报了 UnsatisfiedDependencyException 异常。

java
@Configuration
@RequiredArgsConstructor
public class FebsJobConfigure {

    private final DynamicRoutingDataSource dynamicRoutingDataSource;

    DataSource job = dynamicRoutingDataSource.getDataSource("job");

}

Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'febsJobConfigure' defined in file
......
Parameter 0 of constructor in cc.mrbird.febs.server.job.configure.FebsJobConfigure required a bean of type 'com.baomidou.dynamic.datasource.DynamicRoutingDataSource' that could not be found.

调查了好久终于在 官方仓库 的示例中找到了正确的写法:

java
@Configuration
@RequiredArgsConstructor
public class FebsJobConfigure {

    private final DataSource dataSource;

    DataSource job = ((DynamicRoutingDataSource) dataSource).getDataSource("job");

}

看到了这里就想到之前在调查时看到 DynamicDataSourceAutoConfiguration 中创建 DataSource 的 Bean 时使用了 @ConditionalOnMissingBean 注解,感觉可能是由于这个注解导致某些情况下没有注册 DynamicRoutingDataSource 类型的 Bean 导致的(猜测)。

java
@Bean
@ConditionalOnMissingBean
public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) {
    DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
    dataSource.setPrimary(properties.getPrimary());
    dataSource.setStrategy(properties.getStrategy());
    dataSource.setProvider(dynamicDataSourceProvider);
    dataSource.setP6spy(properties.getP6spy());
    dataSource.setStrict(properties.getStrict());
    return dataSource;
}

总的来说,虽然不知道为什么为出现这个异常,但好在终于解决了。

附 1. quartz.properties

期间,还曾使用 quartz.properties 来创建 SchedulerFactoryBean,将数据库配置保存在 quartz.properties 文件中,也可以成功运行 Quartz,不过配置起来不太方便。

虽然没用到,但是用法和配置的设置还是记录一下。数据是 MySQL,数据库连接池用的 hikari

java
factory.setConfigLocation(new ClassPathResource("/quartz.properties"));

quartz.properties

properties
#============================================================================
# Configure Main Scheduler Properties
#============================================================================

org.quartz.scheduler.instanceName = MyQuartzScheduler
org.quartz.scheduler.instanceId = AUTO

#============================================================================
# Configure ThreadPool
#============================================================================

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 20
org.quartz.threadPool.threadPriority = 5

#============================================================================
# Configure JobStore
#============================================================================

org.quartz.jobStore.misfireThreshold = 12000

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = job
org.quartz.jobStore.tablePrefix = QRTZ_

org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 15000

#============================================================================
# Configure Datasources
#============================================================================

org.quartz.dataSource.job.provider = hikaricp
org.quartz.dataSource.job.driver = com.mysql.cj.jdbc.Driver
org.quartz.dataSource.job.URL = jdbc:mysql://172.0.0.1:3306/quartz_db?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8
org.quartz.dataSource.job.user = user
org.quartz.dataSource.job.password = password
org.quartz.dataSource.job.maxConnections = 5
org.quartz.dataSource.job.validationQuery= select 0

参考

  1. 14. Actuator properties
  2. 关于整合 ES availableProcessors is already 问题分析
  3. 配置 spring-boot-actuator 时候遇到的一些小问题
  4. availableProcessors is already set to [8], rejecting [8]
  5. baomidou / dynamic-datasource-spring-boot-starter
  6. Quartz 配置 Springboot 自带连接池 Hikaricp