微服務的核心思想就是拆分業務,將單個系統按業務邊界切分爲多個可獨立部署的微服務子系統。這樣可以讓系統更容易擴展,更快速的迭代,但必然會導致系統內服務實例數量的大量增加,再加上服務實例可能部署到不同的操作系統和網段,對整個系統進行管理和監控的難度比單系統環境要高出不少。幸運的是,針對Spring Boot技術體系我們有一個開箱即用的系統監控解決方案——Spring Boot Admin,對於中小規模的微服務系統,它幾乎可以提供一切必要的監控需求,而且更重要的是它對於業務系統是非侵入性的,只需要幾行配置就可以將一個基於Spring Boot技術開發的應用納入到監控之中。
Spring Boot Admin分爲兩部分:client和server。client爲被監控端,通過集成Spring Boot Actuator組件暴露出各種監控指標和信息,並註冊到一個server端;server端接受client的註冊,並定時查詢client端提供的監控信息,管理員可以通過server端內置的一個web應用查看client的各項指標和信息。
現在我們就來利用Spring Boot Admin來爲Spring Cloud Demo項目加入服務指標監控的功能。首先來創建一個monitor模塊,作爲Spring Boot Admin的server端,在pom.xml中加入如下配置:
<!--spring-boot-admin-starter-server必須和spring-boot的版本匹配,2.1.X的版本無法在spring boot 2.2.0以上的版本運行-->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
項目啓動類中需要加入一個@EnableAdminServer的註解:
@SpringBootApplication
@EnableAdminServer
public class MonitorApplication {
public static void main(String[] args) {
SpringApplication.run(MonitorApplication.class, args);
}
}
application.yml配置文件只需要加入consul的相關配置即可,用於尋找其它被監控的client。Spring Boot Admin的客戶端有兩種註冊方式,第一種是在被監控的服務客戶端直接引入spring-boot-admin-starter-client,並配置server端的監控地址,主動向server端進行註冊,這種一般用於監控獨立的應用;第二種就是和Spring Cloud體系相匹配的,通過服務註冊中心直接尋找需要被監控的客戶端信息,在我們的demo裏面就是consul,在consul中註冊了的服務會直接成爲Spring Boot Admin的client。
這樣的話,我們demo裏面的服務提供方只需要做很小的改造即可接入Spring Boot Admin的監控體系。主要就是加入Spring Boot Actuator支持,通過該框架來暴露出各種監控指標的,這樣server端才能夠對監控指標進行彙總和圖形化展示。demo的parent項目之前已經添加了Spring Boot Actuator的依賴,但是默認只會暴露出一個/actuator/heath的接口,這對我們的監控來說是遠遠不夠的,所以還需要在每個服務提供方暴露出更多的監控指標。具體來說,就是在配置文件中加入以下Actuator的配置:
#輸出監控指標用於服務監控,暴露的監控指標可根據實際情況調整
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: ALWAYS
#如果要在Spring boot admin中查看日誌,需要指定存儲的文件
logging:
file: ./logs/order-service.log
現在將服務全部啓動,訪問monitor的地址http://localhost:9010,就可以看到Spring boot admin的監控頁面了:
需要注意的是,Spring Boot Admin完全依賴Actuator暴露的接口進行監控,如果沒有實現這些接口,默認就會顯示離線(比如consul實例實際上是在線的)。進入到具體的某個服務,可以看到更多的監控指標,還能夠在線查看日誌和修改logger的日誌級別:
Spring Boot Admin還支持對標題和UI進行部分的定製,具體的配置項,可參考官方文檔
monitor模塊可以收集到應用的一些敏感信息,如果需要暴露到外網進行查看,就必須添加相關的安全措施。我們可以通過spring security框架,快速爲server端添加相應的用戶登錄驗證功能。首先在monitor中加入spring security的依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
然後編寫一個Spring Security的配置類,驗證規則可根據實際情況進行修改:
@Configuration
public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {
private final String adminContextPath;
public SecuritySecureConfig(AdminServerProperties adminServerProperties) {
this.adminContextPath = adminServerProperties.getContextPath();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("redirectTo");
successHandler.setDefaultTargetUrl(adminContextPath + "/");
http.authorizeRequests()
.antMatchers(adminContextPath + "/assets/**").permitAll()
.antMatchers(adminContextPath + "/login").permitAll()
.antMatchers(adminContextPath + "/actuator/health").permitAll()
.anyRequest().authenticated()
.and()
//login登錄頁是spring boot admin ui裏面已經集成了的
.formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and()
.logout().logoutUrl(adminContextPath + "/logout").and()
.httpBasic().and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringAntMatchers(
adminContextPath + "/instances",
adminContextPath + "/actuator/**"
);
}
}
重新啓動後,再次訪問monitor模塊,就需要進行登錄驗證了:
登錄的用戶名和密碼可以在application.yml中配置:
spring:
#允許登錄監控系統的用戶名和密碼
security:
user:
name: admin
password: 123456
需要注意的是,如果沒有使用註冊中心,而是通過spring-boot-admin-starter-client的方式直接向server端註冊的client,還需要加入server端的驗證信息才能成功註冊,類似像這樣:
spring
boot:
admin:
client:
#server端的註冊地址
url: http://localhost:9010
username: admin
password: 123456
instance:
#client的訪問地址前綴,server通過該地址獲取監控信息
service-base-url: http://192.168.1.252:8090
本文的相關代碼可以查看這裏 spring-cloud-demo