問題
在若干年前的單體應用時代,我們可以相對輕松地對整個業務項目進行健康檢查、指標監控、配置管理等等項目治理。如今隨着微服務的發展,我們將大型單體應用按業務模型進行划分,以此形成眾多小而自治的微服務,我們品嘗到了微服務的甜頭:異常隔離、獨立部署和發布、服務伸縮、便於協作開發...我們的項目服務更加解耦合,高可用。但與此同時這也給我們帶來了很多挑戰,眾多服務的健康檢查、指標監控問題、配置管理、日志聚合問題、異常排查問題等等。我們急切需要一些工具或者手段來盡可能地解決這些問題,從而讓我們收獲微服務的最大化利益。
來源背景
codecentric的Spring Boot Admin是一個社區項目,用於管理和監視您的Spring Boot®應用程序。這些應用程序在我們的Spring Boot Admin Client中注冊(通過HTTP),或者是通過Spring Cloud®(例如Eureka,Consul)發現的。 UI只是Spring Boot Actuator端點之上的Vue.js應用程序。
功能介紹
Spring Boot Admin提供了很多服務治理方面的功能,利用它能節省我們很多在治理服務方面的時間和精力Spring Boot Admin提供了如下功能(包括但不限於):
- 顯示健康狀態及詳細信息,如JVM和內存指標、數據源指標、緩存指標
- 跟蹤並下載日志文件
- 查看jvm系統-和環境屬性
- 查看Spring啟動配置屬性
- 方便loglevel管理
- 查看線程轉儲
- 視圖http-traces
- 查看http端點
- 查看計划任務
- 查看和刪除活動會話(使用spring-session)
- 狀態更改通知(通過電子郵件、Slack、Hipchat…)
- 狀態變化的事件日志(非持久性)
- ……(and more !)
搭建Spring Boot Admin Server
在編寫本文的時候,Spring Boot Admin的最新版本為: 2.2.2。接下來我將會用此版本來進行演示。
基礎環境:Jdk 11、Maven、IntelliJ IDEA
引入依賴
由於Spring Boot Admin Server可以作為servlet或webflux應用程序運行,因此您需要對此進行決定並添加相應的Spring Boot Starter。在此示例中,我們使用Servlet Web Starter。
<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來引入Spring Boot Admin Server配置:
@Configuration @EnableAutoConfiguration @EnableAdminServer public class SpringBootAdminApplication { public static void main(String[] args) { SpringApplication.run(SpringBootAdminApplication.class, args); } }
此時我們通過瀏覽器訪問:http://localhost:8080 可以看到我們可以訪問到Spring Boot Admin Server的UI界面:
注冊客戶端
Spring boot Admin提供了多種注冊客戶端服務的方式,要在SBA(Spring Boot Admin)服務器上注冊應用程序,您可以直接注冊SBA客戶端或使用Spring Cloud Discovery(例如Eureka,Consul等)。在SBA服務器端,還有一個使用靜態配置的簡單選項。本文將演示直接注冊、使用Zookeeper、使用Kubernetes來注冊發現客戶端服務。
直接注冊方式
引入依賴
使用直接注冊方式,需要在客戶端服務中引入依賴,從而做到直接與SBA服務端通信。
<dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-starter-client</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
根據開頭所述Spring Boot Admin是基於Spring Boot Actuator之上的,所以我們需要引入Spring Boot Actuator相關依賴,關於Spring Boot Actuator,可以參考此篇文章。此外我們需要處理Actuator的安全性,所以引入Spring Security相關依賴。
添加配置
接下來我們在項目配置文件中添加相關配置
spring.boot.admin.client.url=http://localhost:8080 (1)
management.endpoints.web.exposure.include=* (2)
1⃣️:要注冊到其中的Spring Boot Admin Server的URL。
2⃣️:與Spring Boot 2一樣,默認情況下,大多數Actuator(端點)都不通過http公開,在這里我們公開了所有端點。對於生產,您應該仔細選擇要公開的端點。
安全性配置
@Configuration public static class SecurityPermitAllConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().permitAll() .and().csrf().disable(); } }
為了簡潔起見,我們暫時禁用安全性。查看有關如何處理端點的安全性,我會在后續文章中演示。
此時我們同時運行SBA的服務端和客戶端服務,再次訪問http://localhost:8080,可以看到我們的客戶端服務已經注冊進去,並且可以看到客戶端服務的一些信息。
Zookeeper服務發現方式
我們通過一些服務發現組件對客戶端服務進行注冊的時候,我們就可以忽略掉客戶端服務了,即我們不需要在客戶端服務中引入Spring Boot Admin相關依賴,因為服務端可以通過服務發現組件來自動發現客戶端服務。
引入依賴
我們在SBA服務端以及客戶端中引入Zookeeper相關依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-context</artifactId> </dependency> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
添加配置
在SBA服務端項目中添加Zookeeper相關配置
spring: cloud: zookeeper: connect-string: 你的Zookeeper地址 boot: admin: discovery: instances-metadata: sba-register: true
因為Zookeeper中可能存在很多服務,而我們只想發現我們關注的服務,此時我們可以通過上述配置來實現,即我們只發現元數據為sba-register: true
的客戶端服務。
在SBA客戶端中添加Zookeeper相關配置
spring.cloud.zookeeper.connect-string=你的Zookeeper地址
spring.cloud.zookeeper.discovery.metadata.sba-register=true
對應SBA服務端的配置,我們指定了Zookeeper的地址,並且指定了該客戶端服務的注冊元數據為sba-register: true
此時我們同時運行SBA的服務端和客戶端服務,再次訪問SBA服務端地址,可以看到服務端已經通過Zookeeper自動發現客戶端服務,並且可以看到客戶端服務的一些信息。
Kubernetes服務發現方式
如果你是通過基於Kubernetes的容器化部署,Spring Boot Admin也提供了支持,基於Kubernetes的服務發現方式和Zookeeper方式實現大同小異
引入依賴
我們在Spring Boot Admin服務端項目中引入Kubernetes相關依賴
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-kubernetes-discovery</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
Spring Cloud Kubernetes提供使用Kubernetes本機服務的Spring Cloud公共接口實現。此庫的主要目標是促進在Kubernetes中運行的Spring Cloud和Spring Boot應用程序的集成。
添加配置
@SpringBootApplication @EnableAdminServer @EnableDiscoveryClient @EnableScheduling public class AdminApplication { public static void main(String[] args) { SpringApplication.run(AdminApplication.class, args); } }
@EnableDiscoveryClient
注解表示啟用基於Kubernetes的服務發現,@EnableScheduling
注解是必須的,表示定期調用Kubernetes API來刷新正在運行的服務列表,並且僅在啟動時執行一次。由於我們一直希望擁有最新的Pod列表(例如,在擴展應用程序實例數量之后),因此我們需要啟用調度程序來負責監視服務目錄的更改並相應地更新DiscoveryClient實例列表。
Kubenetes權限配置
Spring Boot Admin使用Spring Cloud Kubernetes,它需要額外的特權才能訪問Kubernetes API。我們僅出於開發目的,將cluster-admin設置為ServiceAccount的默認角色。
$ kubectl create clusterrolebinding admin-default --clusterrole=cluster-admin --serviceaccount=default:default
此時我們同時運行SBA的服務端和客戶端服務,再次訪問SBA服務端,可以看到服務端已經通過Kubernetes自動發現客戶端服務,並且可以看到客戶端服務的一些信息。
總結
本文主要介紹了Spring Boot Admin(SBA)的誕生背景已經其帶來的一些功能特性,在這個微服務遍地開花的時代SBA緩解了我們在微服務中遇到的許多棘手的問題。后面本文還用代碼演示了如何在項目中引入並使用SBA。本文只涉及到了SBA的基礎實踐,我會在后續文章中詳細演示更多SBA的高級功能,看看我們能從中受益多少。
本文的示例代碼
SBA-client:https://github.com/cg837718548/sba-client-demo.git
SBA-server:https://github.com/cg837718548/sba-server-demo.git