




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第SpringBootAdmin使用及心跳檢測(cè)原理分析目錄介紹使用Server端Client端心跳檢測(cè)/健康檢測(cè)原理原理調(diào)試準(zhǔn)備客戶(hù)端發(fā)起POST請(qǐng)求服務(wù)端定時(shí)輪詢(xún)
介紹
SpringBootAdmin是一個(gè)Github上的一個(gè)開(kāi)源項(xiàng)目,它在SpringBootActuator的基礎(chǔ)上提供簡(jiǎn)潔的可視化WEBUI,是用來(lái)管理SpringBoot應(yīng)用程序的一個(gè)簡(jiǎn)單的界面,提供如下功能:
顯示name/id和版本號(hào)
顯示在線狀態(tài)
Logging日志級(jí)別管理
JMXbeans管理
Threads會(huì)話和線程管理
Trace應(yīng)用請(qǐng)求跟蹤
應(yīng)用運(yùn)行參數(shù)信息,如:
Java系統(tǒng)屬性
Java環(huán)境變量屬性
內(nèi)存信息
Spring環(huán)境屬性
SpringBootAdmin包含服務(wù)端和客戶(hù)端,按照以下配置可讓SpringBootAdmin運(yùn)行起來(lái)。
使用
Server端
1、pom文件引入相關(guān)的jar包
新建一個(gè)admin-server的SpringBoot項(xiàng)目,在pom文件中引入server相關(guān)的jar包
dependency
groupIdde.codecentric/groupId
artifactIdspring-boot-admin-server/artifactId
version1.5.3/version
/dependency
dependency
groupIdde.codecentric/groupId
artifactIdspring-boot-admin-server-ui/artifactId
version1.5.3/version
/dependency
dependency
groupIdde.codecentric/groupId
artifactIdspring-boot-admin-starter-client/artifactId
version1.5.3/version
/dependency
其中spring-boot-admin-starter-client的引入是讓server本身能夠發(fā)現(xiàn)自己(自己也是客戶(hù)端)。
2、application.yml配置
在application.yml配置如下,除了server.port=8083的配置是server對(duì)外公布的服務(wù)端口外,其他配置是server本身作為客戶(hù)端的配置,包括指明指向服務(wù)端的地址和當(dāng)前應(yīng)用的基本信息,使用@@可以讀取pom.xml的相關(guān)配置。
在下面Client配置的講解中,可以看到下面類(lèi)似的配置。
server:
port:8083
spring:
boot:
admin:
url:http://localhost:8083
info:
name:server
description:@project.description@
version:@project.version@
3、配置日志級(jí)別
在application.yml的同級(jí)目錄,添加文件logback.xml,用以配置日志的級(jí)別,包含的內(nèi)容如下:
xmlversion="1.0"encoding="UTF-8"
configuration
includeresource="org/springframework/boot/logging/logback/base.xml"/
loggername="org.springframework.web"level="DEBUG"/
jmxConfigurator/
/configuration
在此處配置成了DEBUG,這樣可以通過(guò)控制臺(tái)日志查看server端和client端的交互情況。
4、添加入口方法注解
在入口方法上添加@EnableAdminServer注解。
@Configuration
@EnableAutoConfiguration
@EnableAdminServer
publicclassServerApplication{
publicstaticvoidmain(String[]args){
SpringApplication.run(ServerApplication.class,args);
5、啟動(dòng)項(xiàng)目
啟動(dòng)admin-server項(xiàng)目后,可以看到當(dāng)前注冊(cè)的客戶(hù)端,點(diǎn)擊明細(xì),還可以查看其他明細(xì)信息。
Client端
在上述的Server端配置中,server本身也作為一個(gè)客戶(hù)端注冊(cè)到自己,所以client配置同server端配置起來(lái),比較見(jiàn)到如下。
創(chuàng)建一個(gè)admin-client項(xiàng)目,在pom.xml添加相關(guān)client依賴(lài)包。
1、pom.xml添加client依賴(lài)
dependency
groupIdde.codecentric/groupId
artifactIdspring-boot-admin-starter-client/artifactId
version1.5.3/version
/dependency
2、application.yml配置
在application.yml配置注冊(cè)中心地址等信息:
spring:
boot:
admin:
url:http://localhost:8083
info:
name:client
description:@project.description@
version:@project.version@
endpoints:
trace:
enabled:true
sensitive:false
3、配置日志文件
在application.yml的同級(jí)目錄,添加文件logback.xml,用以配置日志的級(jí)別,包含的內(nèi)容如下:
xmlversion="1.0"encoding="UTF-8"
configuration
includeresource="org/springframework/boot/logging/logback/base.xml"/
loggername="org.springframework.web"level="DEBUG"/
jmxConfigurator/
/configuration
配置為DEBUG的級(jí)別,可以輸出和服務(wù)器的通信信息,以便我們?cè)诤罄m(xù)心跳檢測(cè),了解SpringBootAdmin的實(shí)現(xiàn)方式。
4、啟動(dòng)Admin-Client應(yīng)用
啟動(dòng)客戶(hù)端項(xiàng)目,在服務(wù)端監(jiān)聽(tīng)了客戶(hù)端的啟動(dòng),并在頁(yè)面給出了消息提示,啟動(dòng)后,服務(wù)端的界面顯示如下:(兩個(gè)客戶(hù)端都為UP狀態(tài))
以上就可以使用SpringBootAdmin的各種監(jiān)控服務(wù)了,下面談一談客戶(hù)端和服務(wù)端怎么樣做心跳檢測(cè)的。
心跳檢測(cè)/健康檢測(cè)原理
原理
在SpringBootAdmin中,Server端作為注冊(cè)中心,它要監(jiān)控所有的客戶(hù)端當(dāng)前的狀態(tài)。要知道當(dāng)前客戶(hù)端是否宕機(jī),剛發(fā)布的客戶(hù)端也能夠主動(dòng)注冊(cè)到服務(wù)端。
服務(wù)端和客戶(hù)端之間通過(guò)特定的接口通信(/health接口)通信,來(lái)監(jiān)聽(tīng)客戶(hù)端的狀態(tài)。因?yàn)榭蛻?hù)端和服務(wù)端不能保證發(fā)布順序。
有如下的場(chǎng)景需要考慮:
客戶(hù)端先啟動(dòng),服務(wù)端后啟動(dòng)
服務(wù)端先啟動(dòng),客戶(hù)端后啟動(dòng)
服務(wù)端運(yùn)行中,客戶(hù)端下線
客戶(hù)端運(yùn)行中,服務(wù)端下線
所以為了解決以上問(wèn)題,需要客戶(hù)端和服務(wù)端都設(shè)置一個(gè)任務(wù)監(jiān)聽(tīng)器,定時(shí)監(jiān)聽(tīng)對(duì)方的心跳,并在服務(wù)器及時(shí)更新客戶(hù)端狀態(tài)。
上文的配置使用了客戶(hù)端主動(dòng)注冊(cè)的方法。
調(diào)試準(zhǔn)備
為了理解SpringBootAdmin的實(shí)現(xiàn)方式,可通過(guò)DEBUG和查看日志的方式理解服務(wù)器和客戶(hù)端的通信(心跳檢測(cè))
在pom.xml右鍵spring-boot-admin-server和spring-boot-admin-starter-client,Maven-DownLoadSourcesandDocumentation
在logback.xml中設(shè)置日志級(jí)別為DEBUG
客戶(hù)端發(fā)起POST請(qǐng)求
客戶(hù)端相關(guān)類(lèi)
RegistrationApplicationListener
ApplicationRegistrator
在客戶(hù)端啟動(dòng)的時(shí)候調(diào)用RegistrationApplicationListener的startRegisterTask,該方法每隔registerPeriod=10_000L,(10秒:默認(rèn))向服務(wù)端POST一次請(qǐng)求,告訴服務(wù)器自身當(dāng)前是有心跳的。
RegistrationApplicationListener
@EventListener
@Order(Ordered.LOWEST_PRECEDENCE)
publicvoidonApplicationReady(ApplicationReadyEventevent){
if(event.getApplicationContext()instanceofWebApplicationContextautoRegister){
startRegisterTask();
publicvoidstartRegisterTask(){
if(scheduledTask!=null!scheduledTask.isDone()){
return;
scheduledTask=taskScheduler.scheduleAtFixedRate(newRunnable(){
@Override
publicvoidrun(){
registrator.register();
},registerPeriod);
LOGGER.debug("Scheduledregistrationtaskforevery{}ms",registerPeriod);
ApplicationRegistrator
publicbooleanregister(){
booleanisRegistrationSuccessful=false;
Applicationself=createApplication();
for(StringadminUrl:admin.getAdminUrl()){
try{
@SuppressWarnings("rawtypes")ResponseEntityMapresponse=template.postForEntity(adminUrl,
newHttpEntity(self,HTTP_HEADERS),Map.class);
if(response.getStatusCode().equals(HttpStatus.CREATED)){
if(registeredIpareAndSet(null,response.getBody().get("id").toString())){
LOGGER.info("Applicationregistereditselfas{}",response.getBody());
}else{
LOGGER.debug("Applicationrefresheditselfas{}",response.getBody());
isRegistrationSuccessful=true;
if(admin.isRegisterOnce()){
break;
}else{
if(unsuccessfulAttempts.get()==0){
LOGGER.warn(
"Applicationfailedtoregistereditselfas{}.Response:{}.FurtherattemptsareloggedonDEBUGlevel",
self,response.toString());
}else{
LOGGER.debug("Applicationfailedtoregistereditselfas{}.Response:{}",self,
response.toString());
}catch(Exceptionex){
if(unsuccessfulAttempts.get()==0){
LOGGER.warn(
"Failedtoregisterapplicationas{}atspring-boot-admin({}):{}.FurtherattemptsareloggedonDEBUGlevel",
self,admin.getAdminUrl(),ex.getMessage());
}else{
LOGGER.debug("Failedtoregisterapplicationas{}atspring-boot-admin({}):{}",self,
admin.getAdminUrl(),ex.getMessage());
if(!isRegistrationSuccessful){
unsuccessfulAttempts.incrementAndGet();
}else{
unsuccessfulAttempts.set(0);
returnisRegistrationSuccessful;
在主要的register()方法中,向服務(wù)端POST了Restful請(qǐng)求,請(qǐng)求的地址為/api/applications
并把自身信息帶了過(guò)去,服務(wù)端接受請(qǐng)求后,通過(guò)sha-1算法計(jì)算客戶(hù)單的唯一ID,查詢(xún)hazelcast緩存數(shù)據(jù)庫(kù),如第一次則寫(xiě)入,否則更新。
服務(wù)端接收處理請(qǐng)求相關(guān)類(lèi)
RegistryController
@RequestMapping(method=RequestMethod.POST)
publicResponseEntityApplicationregister(@RequestBodyApplicationapplication){
ApplicationapplicationWithSource=Application.copyOf(application).withSource("http-api")
.build();
LOGGER.debug("Registerapplication{}",applicationWithSource.toString());
ApplicationregisteredApp=registry.register(applicationWithSource);
returnResponseEntity.status(HttpStatus.CREATED).body(registeredApp);
}
ApplicationRegistry
publicApplicationregister(Applicationapplication){
Assert.notNull(application,"Applicationmustnotbenull");
Assert.hasText(application.getName(),"Namemustnotbenull");
Assert.hasText(application.getHealthUrl(),"Health-URLmustnotbenull");
Assert.isTrue(checkUrl(application.getHealthUrl()),"Health-URLisnotvalid");
Assert.isTrue(
StringUtils.isEmpty(application.getManagementUrl())
||checkUrl(application.getManagementUrl()),"URLisnotvalid");
Assert.isTrue(
StringUtils.isEmpty(application.getServiceUrl())
||checkUrl(application.getServiceUrl()),"URLisnotvalid");
StringapplicationId=generator.generateId(application);
Assert.notNull(applicationId,"IDmustnotbenull");
Application.Builderbuilder=Application.copyOf(application).withId(applicationId);
Applicationexisting=getApplication(applicationId);
if(existing!=null){
//CopyStatusandInfofromexistingregistration.
builder.withStatusInfo(existing.getStatusInfo()).withInfo(existing.getInfo());
Applicationregistering=builder.build();
Applicationreplaced=store.save(registering);
if(replaced==null){
LOGGER.info("NewApplication{}registered",registering);
publisher.publishEvent(newClientApplicationRegisteredEvent(registering));
}else{
if(registering.getId().equals(replaced.getId())){
LOGGER.debug("Application{}refreshed",registering);
}else{
LOGGER.warn("Application{}replacedbyApplication{}",registering,replaced);
returnregistering;
HazelcastApplicationStore(緩存數(shù)據(jù)庫(kù))
在上述更新?tīng)顟B(tài)使用了publisher.publishEvent事件訂閱的方式,接受者接收到該事件,做應(yīng)用的業(yè)務(wù)處理,在這塊使用這種方式個(gè)人理解是為了代碼的復(fù)用性,因?yàn)榉?wù)端定時(shí)輪詢(xún)客戶(hù)端也要更新客戶(hù)端在服務(wù)器的狀態(tài)。
pulishEvent設(shè)計(jì)到的類(lèi)有:
StatusUpdateApplicationListener-onClientApplicationRegistered
StatusUpdater–updateStatus
這里不詳細(xì)展開(kāi),下文還會(huì)提到,通過(guò)日志,可以查看到客戶(hù)端定時(shí)發(fā)送的POST請(qǐng)求:
服務(wù)端定時(shí)輪詢(xún)
在服務(wù)器宕機(jī)的時(shí)候,服務(wù)器接收不到請(qǐng)求,此時(shí)服務(wù)器不知道客戶(hù)端是什么狀態(tài),(當(dāng)然可以說(shuō)服務(wù)器在一定的時(shí)間里沒(méi)有收到客戶(hù)端的信息,就認(rèn)為客戶(hù)端掛了,這也是一種處理方式),在SpringBootAdmin中,服務(wù)端通過(guò)定時(shí)輪詢(xún)客戶(hù)端的/health接口來(lái)對(duì)客戶(hù)端進(jìn)行心態(tài)檢測(cè)。
這里設(shè)計(jì)到主要的類(lèi)為:
StatusUpdateApplicationListene
@EventListener
publicvoidonApplicationReady(ApplicationReadyEventevent){
if(event.getApplicationContext()instanceofWebApplicationContext){
startStatusUpdate();
publicvoidstartStatusUpdate(){
if(scheduledTask!=null!scheduledTask.isDone()){
return;
scheduledTask=taskScheduler.scheduleAtFixedRate(newRunnable(){
@Override
publicvoidrun(){
statusUpdater.updateStatusForAllApplications();
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025【專(zhuān)項(xiàng)貸款借款合同】個(gè)人借款合同
- 2025-2030年中國(guó)消炎防曬隔離霜行業(yè)市場(chǎng)深度調(diào)研及前景趨勢(shì)與投資研究報(bào)告
- 2025-2030年中國(guó)海藻粉行業(yè)市場(chǎng)現(xiàn)狀供需分析及投資評(píng)估規(guī)劃分析研究報(bào)告
- 2025-2030年中國(guó)沙利度胺行業(yè)市場(chǎng)現(xiàn)狀供需分析及投資評(píng)估規(guī)劃分析研究報(bào)告
- 2025-2030年中國(guó)氧化鋁陶瓷基板行業(yè)市場(chǎng)現(xiàn)狀供需分析及投資評(píng)估規(guī)劃分析研究報(bào)告
- 2025-2030年中國(guó)橡膠基膠行業(yè)市場(chǎng)現(xiàn)狀供需分析及投資評(píng)估規(guī)劃分析研究報(bào)告
- 2025-2030年中國(guó)榴蓮粉行業(yè)市場(chǎng)現(xiàn)狀供需分析及投資評(píng)估規(guī)劃分析研究報(bào)告
- 2025-2030年中國(guó)棋盤(pán)行業(yè)市場(chǎng)現(xiàn)狀供需分析及投資評(píng)估規(guī)劃分析研究報(bào)告
- 2025-2030年中國(guó)柴油發(fā)電機(jī)行業(yè)市場(chǎng)深度分析及發(fā)展趨勢(shì)與投資戰(zhàn)略研究報(bào)告
- 2025-2030年中國(guó)板牙行業(yè)市場(chǎng)市場(chǎng)現(xiàn)狀供需分析及投資評(píng)估規(guī)劃分析研究報(bào)告
- 《阿莫西林的生物合成》課件
- 2024年新疆拜城縣事業(yè)單位公開(kāi)招聘村務(wù)工作者筆試題帶答案
- 江蘇省海安中學(xué)、金陵中學(xué)、宿遷中學(xué)三校2024-2025學(xué)年高三年級(jí)下學(xué)期4月聯(lián)考測(cè)試 化學(xué)試卷(含答案)
- 2025年企業(yè)管理專(zhuān)業(yè)測(cè)試試題及答案
- 2024年江蘇省灌南縣事業(yè)單位公開(kāi)招聘醫(yī)療衛(wèi)生崗筆試題帶答案
- 2025年上海車(chē)展報(bào)告(乘用車(chē)篇)
- 租地合同補(bǔ)充協(xié)議格式
- 果戈里介紹課件
- 四川省瀘州市2025屆高三第三次教學(xué)質(zhì)量診斷性考試地理試題(含答案)
- 小學(xué)音樂(lè)(聆聽(tīng))小小少年教案設(shè)計(jì)
- 人教版八年級(jí)物理下冊(cè)《大氣壓強(qiáng)》壓強(qiáng) 教學(xué)課件
評(píng)論
0/150
提交評(píng)論