天天看點

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.

繼續閱讀