天天看点

Spring Boot 2.0中的Endpoints实例

原文参考:https://dzone.com/articles/spring-boot-actuator-in-spring-boot-20

Spring Boot Actuator提供了一些actuator endpoint来实现对你的应用程序进行监控和交互,当然,你也可以创建自定义的enpoint.在接下来的部分,我们会创建一个简单的程序,完成以下功能:

使Actuator endpoints 提供程序的git版本信息,jdk版本信息,

对 enpoint的访问增加安全校验

创建一个自定义的endpoint

一、创建project

环境:spring boot 2.0+,java8,maven

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
           

为了让这个例子看起来有点功能,我们创建一个简单的RestController

@RestController
public class HelloActuatorController {

    @RequestMapping(value = "/helloactuator", method= GET)
    public String helloActuator() {
        return "Hello Spring Boot Actuator";
    }

}
           

启动程序,在浏览器输入http://localhost:8080/helloactuator,将会看到"Hello Spring boot Actuator"

二、Spring提供的Endpoint

有了上面的准备,现在,在浏览器输入http://localhost:8080/actuator 就可以看到spring actuator默认提供了哪些内容,返回的内容可以看到Actuator endpoints的大概情况,如果我们需要添加自定义的endpoint时,需要避免命名的冲突。

如上所示,只能看到3个Actuator enpdoinds.为了展示更多的endpoints,需要在application.properties(application.yml)中增加include或exclude的配置,为了能显示所有的endpoints,配置如下

重启应用,这时除了shutdown endpoint之外的Actuator endpoints都是可以使用的。这些endpoints可以参考https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html

三、以info endpoint为例,增加代码的git版本信息

在pom.xml 中添加如下配置

<plugin>
    <groupId>pl.project13.maven</groupId>
    <artifactId>git-commit-id-plugin</artifactId>
    <version>2.2.4</version>
    <executions>
        <execution>
            <id>get-the-git-infos</id>
            <goals>
                <goal>revision</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
        <prefix>git</prefix>
        <verbose>false</verbose>
        <generateGitPropertiesFile>true</generateGitPropertiesFile>
        <generateGitPropertiesFilename>${project.build.outputDirectory}/git.properties</generateGitPropertiesFilename>
        <format>properties</format>
        <gitDescribe>
            <skip>false</skip>
            <always>false</always>
            <dirty>-dirty</dirty>
        </gitDescribe>
    </configuration>
</plugin>
           

maven build之后,会发现在target/classes下多了一个git.properties.

接下来重新启动程序,访问http://localhost:8080/actuator 

{
    "git": {
        "branch": "master",
        "commit": {
            "id": "d7d7202",
            "time": "2018-03-24T13:24:51Z"
        }
    }
}
           

上面显示的信息只有git.properties的一部分,如果想要显示所有的信息,可以在application.properties上增加下面的配置,就可以看到所有的信息了

management.info.git.mode=full
           

四、增加Build信息

和增加git 版本信息的方式一样,我的来增加maven build的信息,只要在项目的META-INFO目录下存在build-info.properties文件,info endpoint就会将build信息显示出来,那怎样产生build-info文件呢?

需要引用spring-boot-maven-plugin插件

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>build-info</goal>
            </goals>
        </execution>
    </executions>
</plugin>
           

重新启动程序,可以看到下面的build 信息

{
    "git": {...}, // 7 items
    "build": {
        "artifact": "myspringactuatorplanet",
        "name": "myspringactuatorplanet",
        "time": "2018-03-24T13:40:03.907109600Z",
        "version": "0.0.1-SNAPSHOT",
        "group": "com.mydeveloperplanet"
    }
}
           

大部分的时候,我们并不希望这些信息被每个人都能访问到,所以需要对endpoind的增加安全校验,为了达到这个目的,首先,需要在pom.xml文件中增加Spring Security的依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
           

添加了上面的依赖之后,重新启动程序在浏览器上访问8080端口的请求,在第一次访问的时候会弹出一个用户登陆的页面,用户名user,密码默认情况下是一串随机码,并在每次启动程序后都会更新,并打印在springboot的启动日志上

Using generated security password: 8da882c3-4bbb-4e71-88c2-13399d9f0724
           

可见默认的安全校验是对所有的http请求有效的,那现在假设我们只想用户验证的方式只作用于部分endpoint上,比如对springboot自带的endpoint起作用,而我们自定义的helloactuator不起作用,该怎么做呢?

根据spring的文档,我们需要新增一个配置类

@Configuration
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests()
      .anyRequest().hasRole("ADMIN")
      .and()
      .httpBasic();
  }
}
           

现在,只有Actuator endpoints需要验证了,这里需要提醒的是,上面的配置只作用于Actuator endpoints,我原以为EndpointRequest.toAnyEndpoint包含http://localhost:8080/actuator.但其实不是的,因为它并没有被当做是一个真正的endpoint。这个问题在springboot早已经存在,详细信息可以参考https://github.com/spring-projects/spring-boot/issues/12353.

现在的密码是每次启动springboot的时候自动生成的,可以通过增加userDetaisServise来避免,当然这种操作只是为了演示的方便,请不要适用到生产环境中。

@Bean
@Override
public UserDetailsService userDetailsService() {
	UserDetails user =
			User.withDefaultPasswordEncoder()
					.username("user")
					.password("password")
					.roles("ADMIN")
					.build();
	return new InMemoryUserDetailsManager(user);
}
           

现在Actuator endpoints就可以通过username=user password=password进行访问了。

五、关于Health Endpoint

在默认情况下Health endpoint不会显示详细信息,这些信息通过spring自带的healthindicators进行解析收集,但默认情况下我们只能看到下面的数据。

{
    "status": "UP"
}
           

为了能展示自带的healthindicators所收集的信息,需要在application.properties增加如下的配置,这样,所有通过healthindicators生成的信息都能被展示出来。

management.endpoint.health.show-details=when-authorized
           

这个值默认为never,表示不会展示任何health indicators收集的信息,现在设为when-authorized,让有权限的用户访问时显示health信息。

重新运行程序,访问请求http://localhost:8080/actuator/health 将会看到下面的信息

{
    "status": "UP",
    "details": {
        "diskSpace": {
            "status": "UP",
            "details": {
                "total": 408943587328,
                "free": 75006865408,
                "threshold": 10485760
            }
        }
    }
}
           

 我们也可以创建自定义的health indicators来展示软件的更多信息。创建自定义的health indicators需要实现HealthIndicator接口,下面的例子,我们将会检查当请求触发时,系统时间的分钟数是奇数还是偶数,这样我们可以很容易的测试health indicator状态的改变,当分钟数为偶数的时候,indicator返回UP状态,如果是奇数返回DOWN状态。所以,我们自定义类OddOrEvenMinuteHealthCheck的代码如下所示。

@Component
public class OddOrEvenMinuteHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        int errorCode = 0;
        LocalTime now = LocalTime.now();
        if (now.getMinute() % 2 != 0) {
            errorCode = 1;
        }
        if (errorCode != 0) {
            return Health.down().withDetail("Error Code", errorCode).build();
        }
        return Health.up().build();
    }
}
           

重新启动springboot,访问http://localhost:8080/actuator/health,将会多出下面的信息

"oddOrEvenMinute": {
  "status": "UP"
},
           

 在一个分钟数为奇数的时间点访问,这时status变为DOWN

"oddOrEvenMinute": {
    "status": "DOWN",
    "details": {
        "Error Code": 1
    }
},
           

HeathIndicator提供的状态DOWN,OUT_OF_SERVICE,UP,UNKNOWN,我们也可以增加我们自定义的状态码,比如,我们可以增加ODD和EVEN状态,只要在新增的状态码加到application.properties中,如下所以

management.health.status.order=DOWN, OUT_OF_SERVICE, UNKNOWN, ODD, EVEN, UP
           

最后,需要在OddOrEvenMinuteHealthCheck修改对应的状态即可

if (errorCode != 0) {
    return Health.status("ODD").withDetail("Error Code", errorCode).build();
}
return Health.status("EVEN").build();
           

六、总结

这篇文章,我们对spring actuator进行了了解,知道怎么样启用Actuator endpoints,如果增加git 版本信息和maven构建信息到info actuator endpoint,以及如何给endpoint增加安全加校验,最后,如何给health enpoint自定义一个health indicators.

继续阅读