spring-boot-admin為我們基于spring-boot的基礎(chǔ)數(shù)據(jù)安全端口提供了基礎(chǔ)的可視化監(jiān)控功能充坑。還可以通過spring-boot-admin的server程序?qū)pring-boot程序提供簡單的實時管理(例如修改日志輸出級別)卸伞。
通過官方的英文指導(dǎo)文檔和網(wǎng)上一些技術(shù)博客僵控,可以很方便的學(xué)習(xí)spring-boot-admin的集成宛琅。根據(jù)個人的學(xué)習(xí)過程簡單整理了一下道川,希望對想要學(xué)習(xí)的童鞋有所幫助蚣录。
個人習(xí)慣割择,搭建demo的過程中采用了maven來構(gòu)建,在父pom中統(tǒng)一配置spring-boot萎河、spring-cloud以及spring-boot-admin相關(guān)組件的版本荔泳,所以在子模塊中,引入依賴時不會顯示指明版本虐杯。
以下是父pom中的的主要配置
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath/>
</parent>
<properties>
<java.version>1.8</java.version>
<admin.version>1.5.4</admin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${admin.version}</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server</artifactId>
<version>${admin.version}</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui</artifactId>
<version>${admin.version}</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui-hystrix</artifactId>
<version>${admin.version}</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui-turbine</artifactId>
<version>${admin.version}</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui-login</artifactId>
<version>${admin.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
一玛歌、spring-boot + spring-boot-admin 集成基礎(chǔ)
1.1、利用spring-boot-starter-actuator創(chuàng)建安全端點
添加maven依賴
首先擎椰,我們創(chuàng)建一個admin-client作為spring-boot-admin的客戶端程序支子。該程序依賴如下兩個依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
application.properties文件配置
我們設(shè)置內(nèi)嵌tomcat監(jiān)聽端口為8090
spring.application.name=admin-client
server.port=8090
#關(guān)閉安全控制
management.security.enabled=false
啟動類配置
@SpringBootApplication
public class AdminClient {
public static void main(String[] args) {
SpringApplication.run(AdminClient.class, args);
}
}
測試效果
直接啟動main方法,可以看到日志中有如下幾行記錄达舒,里面有spring-boot-starter-actuator為我們暴露的信息
2017-10-22 16:59:22.572 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/loggers/{name:.*}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.LoggersMvcEndpoint.get(java.lang.String)
2017-10-22 16:59:22.573 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/loggers/{name:.*}],methods=[POST],consumes=[application/vnd.spring-boot.actuator.v1+json || application/json],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.LoggersMvcEndpoint.set(java.lang.String,java.util.Map<java.lang.String, java.lang.String>)
2017-10-22 16:59:22.573 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/loggers || /loggers.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-10-22 16:59:22.579 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/health || /health.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(javax.servlet.http.HttpServletRequest,java.security.Principal)
2017-10-22 16:59:22.581 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/mappings || /mappings.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-10-22 16:59:22.583 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/info || /info.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-10-22 16:59:22.584 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/autoconfig || /autoconfig.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-10-22 16:59:22.586 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/heapdump || /heapdump.json],methods=[GET],produces=[application/octet-stream]}" onto public void org.springframework.boot.actuate.endpoint.mvc.HeapdumpMvcEndpoint.invoke(boolean,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.io.IOException,javax.servlet.ServletException
2017-10-22 16:59:22.587 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/configprops || /configprops.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-10-22 16:59:22.591 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/beans || /beans.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-10-22 16:59:22.598 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/trace || /trace.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-10-22 16:59:22.600 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/dump || /dump.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-10-22 16:59:22.601 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/metrics/{name:.*}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint.value(java.lang.String)
2017-10-22 16:59:22.602 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/metrics || /metrics.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-10-22 16:59:22.605 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/auditevents || /auditevents.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public org.springframework.http.ResponseEntity<?> org.springframework.boot.actuate.endpoint.mvc.AuditEventsMvcEndpoint.findByPrincipalAndAfterAndType(java.lang.String,java.util.Date,java.lang.String)
2017-10-22 16:59:22.606 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/env/{name:.*}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint.value(java.lang.String)
2017-10-22 16:59:22.607 INFO 341860 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/env || /env.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
我們簡單訪問health端點地址:http://127.0.0.1:8090/health值朋,可以得到如下程序健康信息結(jié)果
{"status":"UP","diskSpace":{"status":"UP","total":104857595904,"free":55882469376,"threshold":10485760}}
由于端點眾多且與其他框架例如spring-cloud集成時還會增加其他端點叹侄,非常不方便記憶核操作。同時直接訪問的時候返回的數(shù)據(jù)都是JSON格式的字符串昨登,查看不太直觀趾代。所以這就有了spring-boot-admin绘搞,它可以為我們提供這些端點比較直觀的UI界面效果番电,方便我們的運營、運維渔伯、技術(shù)等人員使用糯俗。
1.2尿褪、創(chuàng)建spring-boot-admin服務(wù)端程序admin-server
我們創(chuàng)建admin-server作為spring-boot-admin的server端程序,為該程序添加jar包依賴得湘,該依賴包括自動裝配依賴和UI依賴
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui</artifactId>
</dependency>
配置監(jiān)聽端口核程序名等
spring.application.name=admin-server
server.port=80
創(chuàng)建核配置啟動類
@SpringBootApplication
@EnableAdminServer
public class AdminServer {
public static void main(String[] args) {
SpringApplication.run(AdminServer.class,args);
}
}
@EnableAdminServer注解表示開啟spring-boot-admin-server程序杖玲。直接啟動main方法后,我們訪問http://127.0.0.1淘正,可以看到簡單的界面效果摆马,由于目前沒有客戶端程序所以列表中沒有記錄
接下來我們將之前的admin-client程序集成spring-boot-admin-starter-client,先修改maven依賴
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
其次鸿吆,我們在配置文件中新增如下配置
#設(shè)置admin-server的地址
spring.boot.admin.url=http://127.0.0.1
然后我們啟動admin-client程序囤采,我們可以看看admin-client程序已經(jīng)可以在admin-server程序的UI界面中看到了
點擊Details按鈕,可以看到更多程序的信息惩淳,例如
從圖中我們可以看到內(nèi)存使用的情況蕉毯,這些數(shù)據(jù)都是通過admin-client程序的端點獲取到的信息并展示給我們。信息非常多思犁,更多細節(jié)功能可以自己探索代虾,這里不做贅述。
小結(jié)
從以上簡單的例子中激蹲,我們可以發(fā)現(xiàn)一般的spring-boot程序使用spring-boot-admin作為管理工具需要經(jīng)過如下兩個步驟:
- 1棉磨、需要創(chuàng)建一個spring-boot-admin的server程序。
- 2学辱、為應(yīng)用程序集成spring-boot-admin-stater-client客戶端乘瓤。
- 3、客戶端配置關(guān)閉掉端口的安全控制以及配置上admin-server的URL地址策泣。
- 4衙傀、spring-boot-admin的管理程序必須與客戶端程序必須網(wǎng)絡(luò)可達。
1.3 為admin-server程序添加安全訪問控制
admin-server程序是spring-boot的安全端點管理程序着降,自身的安全也是比不可少的差油,所以我們需要為admin-server程序添加安全訪問控制。官方已經(jīng)提供了對應(yīng)的支持任洞,具體步驟如下:
- 添加maven依賴
admin-server的登錄安全采用的是spring-security來實現(xiàn)的蓄喇,官方為我們提供了UI界面。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui-login</artifactId>
</dependency>
- 配置用戶名核密碼
在配置文件application.properties中添加登錄訪問密碼
security.user.name=user
security.user.password=123456
- 配置WebSecurity安全攔截
最后交掏,我們還需要在admin-server中配置security的攔截配置妆偏,同樣官方也為我們提供了代碼,如下
@Configuration
public static class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// Page with login form is served as /login.html and does a POST on /login
http.formLogin().loginPage("/login.html").loginProcessingUrl("/login").permitAll();
// The UI does a POST on /logout on logout
http.logout().logoutUrl("/logout");
// The ui currently doesn't support csrf
http.csrf().disable();
// Requests for the login page and the static assets are allowed
http.authorizeRequests()
.antMatchers("/login.html", "http://*.css", "/img/", "/third-party/")
.permitAll();
// ... and any other request needs to be authorized
http.authorizeRequests().antMatchers("/").authenticated();
// Enable so that the clients can authenticate via HTTP basic for registering
http.httpBasic();
}
}
重啟程序盅弛,再次訪問時钱骂,就可以看到訪問admin-server需要輸入用戶名和密碼了
二、spring-cloud + spring-boot-admin集成
微服務(wù)盛行的今天挪鹏,基于spring-boot的微服務(wù)框架spring-cloud進入大眾視野见秽,許多大公司也紛紛開始使用該框架,都在嘗試適用于自己平臺的組件讨盒。大家都知道spring-cloud框架程序間是通過微服務(wù)的注冊發(fā)現(xiàn)來實現(xiàn)相互的感知的解取。
spring-boot-admin官方也為我們提供了基于spring-cloud框架的支持。下面我們逐步來實現(xiàn)spring-boot-admin在spring-cloud下的集成使用返顺。
我們需要創(chuàng)建如下三個程序
程序名 | 功能說明 |
---|---|
eureka-server | spring-cloud的eureka實現(xiàn)的注冊中心禀苦。 |
admin-cloud-server | spring-boot-admin的服務(wù)端程序,類似與前面的admin-server遂鹊。 |
admin-cloud-server | spring-boot-admin的客戶端程序振乏,類似與前面的admin-client。 |
2.1 基于spring-cloud的基礎(chǔ)搭建
2.1.1eureka-server創(chuàng)建和配置
我們使用spring-cloud提供的eureka組件搭建一個簡單的注冊中心程序秉扑。搭建非常簡單慧邮。
- 創(chuàng)建eureka-server程序并添加依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
- application.properties文件配置
spring.application.name=eureka-server
server.port=8761
#配置不進行自我注冊核信息拉取
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
#注冊中心地址,其他程序通過次URL進行注冊
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
eureka.instance.instance-id=${spring.cloud.client.ipAddress}:${server.port}
eureka.instance.prefer-ip-address=true
為了方便我們后邊測試舟陆,在application.properties中可以添加如下配置來關(guān)閉掉注冊中心自我保護模式以及剔除客戶端的時間周期
#是否打開自我保護误澳,如果設(shè)置為true,很容易會出現(xiàn)紅色字體的自我保護提示吨娜,不方便測試
eureka.server.enable-self-preservation=false
#清理時間脓匿,默認(rèn)是60*1000毫秒,修改短一點宦赠,保證開發(fā)時陪毡,客戶端失效后,能夠快速剔除客戶端
eureka.server.eviction-interval-timer-in-ms=10000
- 配置啟動類
我們在啟動類上添加注冊中心相關(guān)注解
@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class,args);
}
}
這樣我們的注冊中心就配置好了勾扭,啟動主類即可毡琉。
2.1.2、admin-cloud-server創(chuàng)建和配置
與上一節(jié)中admin-server程序創(chuàng)建流程類似妙色,我們創(chuàng)建spring-boot-admin的服務(wù)端程序admin-cloud-server
- 添加maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui</artifactId>
</dependency>
- application.properties配置文件配置
spring.application.name=admin-cloud-server
server.port=80
#添加eureka注冊信息
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
eureka.instance.instance-id=${spring.cloud.client.ipAddress}:${server.port}
eureka.instance.prefer-ip-address=true
management.security.enabled=false
- 啟動類AdminCloudServer配置
@SpringBootApplication
//注冊到eureka
@EnableDiscoveryClient
//開啟AdminServer
@EnableAdminServer
public class AdminCloudServer {
public static void main(String[] args) {
SpringApplication.run(AdminCloudServer.class, args);
}
}
配置完成后啟動配置桅滋,啟動程序,訪問http://127.0.0.1/,可以看到與上一節(jié)中admin-server相同的界面
2.13丐谋、admin-cloud-client創(chuàng)建和配置
我們創(chuàng)建一個名為admin-cloud-client的spring-boot-admin的客戶端程序芍碧,同時它也是一個spring-cloud程序。
- 添加maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
注意一定要添加spring-boot-starter-actuator
- application.properties配置
spring.application.name=admin-cloud-client
server.port=8090
#注冊中心地址
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
eureka.instance.instance-id=${spring.cloud.client.ipAddress}:${server.port}
eureka.instance.prefer-ip-address=true
#關(guān)閉安全控制
management.security.enabled=false
- 啟動類配置
@SpringBootApplication
@EnableDiscoveryClient
public class AdminCloudClient {
public static void main(String[] args) {
SpringApplication.run(AdminCloudClient.class,args);
}
}
我們啟動該程序号俐,稍后刷新admin-cloud-server的管理頁面泌豆,可以看到如下效果
可以看到,admin-cloud-client程序也出現(xiàn)在了管理列表中
我們查看eureka-server程序的管理頁面http://127.0.0.1:8761吏饿,可以看到admin-cloud-server和admin-cloud-client都在注冊中心列表中
這樣踪危,我們基于spring-cloud注冊中心方式的spring-boot-admin管理程序就搭建好了。
小結(jié)
從原來的單純的spring-boot版本改為當(dāng)前的基于spring-cloud注冊中心方式的版本非常簡單猪落,大致步驟如下:
- 1贞远、首先我們要添加eureka客戶端支持,都需要添加spring-cloud-starter-eureka依賴
- 2笨忌、配置文件中增加eureka注冊中心地址蓝仲。
- 3、啟動來添加eureka客戶端注解@EnableDiscoveryClient來注冊到注冊中心蜜唾。
可以從上面看到杂曲,客戶端不在需要任何spring-boot-admin客戶端的依賴核配置,由于使用了注冊中心袁余,使用起來更加簡單了擎勘。
2.2 基于spring-cloud的擴展監(jiān)控集成
大家都知道spring-cloud做微服務(wù)的一個很重要的特性就是支持hystrix(斷路器),解決系統(tǒng)雪崩還對短路情況進行了統(tǒng)計颖榜,并支持通過安全端點實時輸出棚饵。spring-cloud已經(jīng)提供了hystrix-bashbroad組件UI來動態(tài)顯示單個斷路器的情況,又提供了turbine組件來實現(xiàn)分布式時斷路器的數(shù)據(jù)聚合掩完。雖然原本都提供了UI界面噪漾,但并未進行統(tǒng)一集成,在生產(chǎn)環(huán)境中使用起來不太方便且蓬。
spring-boot-admin不僅添加了spring-cloud的支持欣硼,同時還增加了對spring-cloud擴展端點的UI支持。下面我們逐步改進程序來體驗一下效果恶阴。
實現(xiàn)思路是這樣:我們在admin-cloud-client中添加hystrix(斷路器)功能支持诈胜,并創(chuàng)建一個定時器來讓它訪問一個不可達的地址。然后在admin-cloud-client中集成hystrix以及turbine監(jiān)控的UI冯事。觀察是否能夠達到效果焦匈。
2.2.1、admin-cloud-client改造
首先昵仅,我們增加hystrix和feign依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
并在啟動類采用@EnableCircuitBreaker開啟斷路器自動裝配
@SpringBootApplication
@EnableDiscoveryClient
//開啟斷路器裝配
@EnableCircuitBreaker
//開啟feign client
@EnableFeignClients
public class AdminCloudClient {
public static void main(String[] args) {
SpringApplication.run(AdminCloudClient.class,args);
}
}
創(chuàng)建一個FeignClient缓熟,但是service-id我們配置為不存在的服務(wù)id(test-service)
@FeignClient("test-service")
public interface TestClient {
@RequestMapping("/test")
void test();
}
接下來,我們創(chuàng)建一個定時任務(wù)來調(diào)用FeignClient客戶端訪問test方法,方便稍后看到斷路器變化代碼如下
@Component
//開啟定時任務(wù)
@EnableScheduling
public class HystrixJob {
@Autowired
private TestClient testClient;
@Scheduled(cron = "0/20 * * * * ?")
public void doJob(){
try{
testClient.test();
}catch(Exception e){
e.printStackTrace();
}
}
}
2.2.2够滑、admin-cloud-server改造
為admin-cloud-server程序添加hystrix的ui依賴
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui-hystrix</artifactId>
</dependency>
先啟動admin-cloud-client再啟動admin-cloud-server程序垦写。在控制面板中找到“ADMIN-CLOUD-CLIENT”程序點擊右邊Details按鈕,進入admin-cloud-client程序的管理界面版述,點擊hystrix可以看到斷路器相關(guān)的統(tǒng)計信息
可以看到hystix的UI面板已經(jīng)集成到了spring-boot-admin中梯澜。
接下來我們集成turbine面版UI寞冯,首先我們添加turbine的ui和自動裝配相關(guān)的依賴
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui-turbine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine</artifactId>
</dependency>
上面第一個依賴為我們添加了turbine聚合UI的入口渴析,第二個依賴給程序添加了turbine相關(guān)的端點,這樣程序訪問當(dāng)前程序才能通過訪問自己訪問到turbine端口
接著我們得在admin-cloud-server程序啟動類上添加@EnableTurbine注解開啟turbine支持吮龄,如下
@SpringBootApplication
//注冊到eureka
@EnableDiscoveryClient
//開啟AdminServer
@EnableAdminServer
#開啟turbine
@EnableTurbine
public class AdminCloudServer {
public static void main(String[] args) {
SpringApplication.run(AdminCloudServer.class, args);
}
}
最后俭茧,需要做turbine相關(guān)的配置
spring.boot.admin.turbine.clusters=default
#設(shè)置turbine端點的service-id,由于目前turbine功能已經(jīng)集成到了admin-cloud-server程序中漓帚,所以這里填寫的是該程序注冊到注冊中心的service-Id
spring.boot.admin.turbine.location=admin-cloud-server
turbine.clusterNameExpression=new String("default")
#設(shè)置需要監(jiān)控的serviceId
turbine.app-config=admin-cloud-client
2.2.3母债、效果測試
接下來我們還是依次啟動admin-cloud-client和admin-cloud-server程序。登錄后admin管理頁面尝抖,我們可以看到界面增加了新的Turbine入口毡们,界面如下
點擊該入口,可以看到一個聚合hystrix信息的turbine面板
這樣spring-boot-admin就集成了spring-cloud中turbine組件的功能了昧辽。
注意:spirng-boot-admin服務(wù)端程序在訪問hystrix相關(guān)頁面的時候會報一個錯誤
2017-10-24 15:03:21.435 WARN 493284 --- [p-nio-80-exec-7] o.s.c.n.z.f.post.SendResponseFilter : Error while sending response to client: java.io.IOException: 你的主機中的軟件中止了一個已建立的連接衙熔。
2017-10-24 15:03:21.446 WARN 493284 --- [p-nio-80-exec-7] o.s.c.n.z.filters.post.SendErrorFilter : Error during filtering
com.netflix.zuul.exception.ZuulException: Filter threw Exception
at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:227) ~[zuul-core-1.3.0.jar:1.3.0]
at com.netflix.zuul.FilterProcessor.runFilters(FilterProcessor.java:157) ~[zuul-core-1.3.0.jar:1.3.0]
......
官方也有人提了issue,不過這是zuul的bug,詳情見github
2.3搅荞、基于MQ的hystrix(斷路器)消息收集方式集成
大家都知道hystrix數(shù)據(jù)的收集是通過spring-boot-admin服務(wù)端訪問hystrix端點獲取的红氯,如果在無法訪問http或者我們想要減少http方式的請求時,可以使用MQ來作為消息手機通信方式咕痛。官方推薦使用RabbitMQ痢甘,所以我們需要先安裝RabbitMQ。具體安裝方法這里就不講了茉贡。
2.3.1塞栅、admin-cloud-client改造
spring-cloud提供了hystri的MQ收集工具包,我們在client程序中增加如下兩個依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-hystrix-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
由于采用了RabbitMQ腔丧,我們還需要在application.properties中增加MQ的連接配置
#RabbitMQ的連接配置
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
這樣客戶端的改造就完成了
2.3.2放椰、admin-cloud-server改造
首先,我們在server端添加如下maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine-amqp</artifactId>
</dependency>
該依賴會自動引入spring-cloud-starter-stream-rabbit與spring-cloud-starter-turbine-stream悔据。
其次庄敛,我們刪除掉原來的spring-cloud-starter-turbine依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine</artifactId>
</dependency>
接著我們要改造啟動類,使用 @EnableTurbineStream 替換 @EnableTurbine
@SpringBootApplication
//注冊到eureka
@EnableDiscoveryClient
//開啟AdminServer
@EnableAdminServer
//@EnableTurbine
@EnableTurbineStream
public class AdminCloudServer {
public static void main(String[] args) {
SpringApplication.run(AdminCloudServer.class, args);
}
}
接著科汗,application.properties中刪除掉之前的如下配置
turbine.clusterNameExpression=new String("default")
#設(shè)置需要監(jiān)控的serviceId
turbine.app-config=admin-cloud-client
除此之外藻烤,我們要配置MQ獲取到數(shù)據(jù)后暴露到哪一個端口,假設(shè)我們將數(shù)據(jù)暴露在8088端口,配置如下
# 這是turbine即暴露監(jiān)控數(shù)據(jù)的端口怖亭,必須跟server.port不同
turbine.stream.port=8088
最后涎显,我們還需要將之前的spring.boot.admin.turbine.location的值admin-cloud-server改為URL的的方式,指向當(dāng)前程序的8088端口兴猩,如下
spring.boot.admin.turbine.location=http://localhost:${turbine.stream.port}/
2.2.3期吓、效果測試
注意: 如果spring.boot.admin.turbine.location不更改為url,會報如下錯誤,因為端點端口并未暴露到程序監(jiān)聽的80端口倾芝,而是暴露到了turbine.stream.port所配置的8088端口
Unable to connect to Command Metric Stream 'api/turbine/stream?cluster=default'.Error: {"isTrusted":true}
同樣讨勤,我們依次啟動admin-cloud-client和admin-cloud-server,在打開server端的turbine面板晨另,我們又可以看到與之前非MQ模式的效果
三潭千、其他功能集成
接下來我們簡單集成核配置兩個基礎(chǔ)功能:客戶端HTTP BASIC認(rèn)證配置與服務(wù)端監(jiān)控郵件通知
3.1、客戶端HTTP BASIC認(rèn)證配置
大家可以看到我們的客戶程序中添加了management.security.enabled并設(shè)置其值為false借尿,目的是關(guān)閉端點的安全訪問刨晴。在生產(chǎn)環(huán)境中,我們的admin-client或者admin-cloud-client可能添加了安全訪問可控制路翻,這個時候訪問端點就需要提供用戶名和密碼了狈癞。
spring-boot-admin支持客戶端程序使用HTTP BASIC的安全認(rèn)證,接下來我們改進一下客戶端基于spring-boot-starter-security搭建的安全訪問控制配置茂契。
我們假設(shè)蝶桶,admin-client或者admin-cloud-client中我們使用spring-boot-starter-security做了HTTP BASIC安全認(rèn)證,配置文件中的密碼配置為
security.user.name=test
security.user.password=123456
client為單純的spring-boot程序
如果是單純使用spring-boot構(gòu)建(非spring-cloud)的程序账嚎,那么我們需要在客戶端配置文件中增加如下配置
spring.boot.admin.client.metadata.user.name=${security.user.name}
spring.boot.admin.client.metadata.user.password=${security.user.password}
client為spring-cloud程序
如果使用了spring-cloud莫瞬,因為我們使用的是沒有spring-boot-admin-starter-client依賴的方式,而是通過eureka來獲取客戶端信息的郭蕉,所以需要按照如下方式配置在元數(shù)據(jù)中
eureka.instance.metadata-map.user.name=${security.user.name}
eureka.instance.metadata-map.user.password=${security.user.password}
這樣spring-boot-admin服務(wù)端程序就可以正常訪問客戶端程序了疼邀。
3.2、客戶端上下線通知
spring-boot-admin作為監(jiān)控管理程序召锈,除了提供實時的程序安全數(shù)據(jù)端口UI監(jiān)控外旁振,官方還提供了spring-boot-admin客戶端程序異常的通知預(yù)警功能。官網(wǎng)提供了八種通知方式涨岁,詳情見官網(wǎng)拐袜,大家可以根據(jù)自己的需求集成不同的通知方式。接下來我們搭建一下使用郵件通知方式的預(yù)警功能梢薪。spring-boot-admin集成郵件通知功能與spring-boot集成郵件發(fā)送功能類似蹬铺。接下來我們逐步集成改進spring-boot-admin服務(wù)端(我們以admin-cloud-server為例)。
添加maven依賴
我們在上一節(jié)中的admin-cloud-server中添加spring-boot郵件相關(guān)依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
修改properties文件配置
我們在application.properties文件中添加如下配置
#郵件通知配置
#郵件服務(wù)器地址
spring.mail.host=smtp.qq.com
#發(fā)送郵件的郵箱地址
spring.mail.username=test0@qq.com
#QQ郵箱授權(quán)碼或163郵箱密碼
spring.mail.password=******
#添加郵件認(rèn)證相關(guān)設(shè)置
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
#需要忽略的狀態(tài)改變通知秉撇,逗號分隔,例如不通知離線到上線的狀態(tài)甜攀,則填寫為OFFLINE:UP
#spring.boot.admin.notify.mail.ignore-changes=
#接收通知的郵箱地址秋泄,逗號分隔
spring.boot.admin.notify.mail.to=test2@qq.com
#需要抄送的郵箱地址,逗號分隔
spring.boot.admin.notify.mail.cc=test1@qq.com
#郵件發(fā)送者,大部分情況與登錄名相同
spring.boot.admin.notify.mail.from=${spring.mail.username}
#郵件主題规阀,默認(rèn)是:#{application.name} (#{application.id}) is #{to.status}
spring.boot.admin.notify.mail.subject=#{application.name} (#{application.id}) is #{to.status}
#郵件內(nèi)容恒序,默認(rèn)是:#{application.name} (#{application.id})\nstatus changed from #{from.status} to #{to.status}\n\n#{application.healthUrl}
spring.boot.admin.notify.mail.text=#{application.name} (#{application.id})\nstatus changed from #{from.status} to #{to.status}
測試效果
還是分別啟動eureka-server、admin-cloud-server谁撼、admin-cloud-client程序歧胁。片刻之后我們重啟admin-cloud-client
可以在windows任務(wù)欄的QQ彈出了admin-client-client狀態(tài)變表更的郵件提示,我們進入郵箱可以看到兩封郵件厉碟,效果如下:
我們點擊一個郵件進去可以看到如下的默認(rèn)郵件內(nèi)容
可以看到郵件詳細內(nèi)容的格式與spring.boot.admin.notify.mail.text參數(shù)配置的格式相同喊巍,所以我們可以通過更改該配置的內(nèi)容格式來定制我們想要的預(yù)警內(nèi)容。
小結(jié)
通過spring-boot-admin集成郵件通知可以更加豐富監(jiān)控程序的功能墨榄。為生產(chǎn)環(huán)境中的安全穩(wěn)定運行又提供了一層有效的保障玄糟。
總結(jié)
spring-boot-admin為我們基于spring-boot開發(fā)的程序(包括spring-cloud)提供了安全端點的基礎(chǔ)監(jiān)控,對有異常狀態(tài)(客戶端狀態(tài)變更為上線袄秩、下線、未知等)支持多種通知方式逢并。為生產(chǎn)環(huán)境的運營維護提供了直觀的UI效果之剧。
當(dāng)然對于當(dāng)前復(fù)雜的生產(chǎn)環(huán)境來說,spring-boot-admin所支持的還是一下小部分砍聊。未來希望能夠看到更多的更開放的監(jiān)控功能的集成(例如zipkin)背稼,并且支持更多自定義的監(jiān)控開發(fā)。
參考資料: