SpringBoot Admin使用及心跳檢測(cè)原理分析_第1頁(yè)
SpringBoot Admin使用及心跳檢測(cè)原理分析_第2頁(yè)
SpringBoot Admin使用及心跳檢測(cè)原理分析_第3頁(yè)
SpringBoot Admin使用及心跳檢測(cè)原理分析_第4頁(yè)
SpringBoot Admin使用及心跳檢測(cè)原理分析_第5頁(yè)
已閱讀5頁(yè),還剩10頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論