千家信息网

SpringBoot Admin怎么用

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章给大家分享的是有关SpringBoot Admin怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。介绍Spring Boot Admin是一个Github上的一
千家信息网最后更新 2026年11月02日SpringBoot Admin怎么用

这篇文章给大家分享的是有关SpringBoot Admin怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

介绍

Spring Boot Admin是一个Github上的一个开源项目,它在Spring Boot Actuator的基础上提供简洁的可视化WEB UI,是用来管理 Spring Boot 应用程序的一个简单的界面,提供如下功能:

  • 显示 name/id 和版本号

  • 显示在线状态

  • Logging日志级别管理

  • JMX beans管理

  • Threads会话和线程管理

  • Trace应用请求跟踪

  • 应用运行参数信息,如:

Java 系统属性

Java 环境变量属性

内存信息

Spring 环境属性

Spring Boot Admin 包含服务端和客户端,按照以下配置可让Spring Boot Admin运行起来。

使用

Server端

1、pom文件引入相关的jar包

新建一个admin-server的Spring Boot项目,在pom文件中引入server相关的jar包

               de.codecentric            spring-boot-admin-server            1.5.3                            de.codecentric            spring-boot-admin-server-ui            1.5.3                            de.codecentric            spring-boot-admin-starter-client            1.5.3        

其中spring-boot-admin-starter-client的引入是让server本身能够发现自己(自己也是客户端)。

2、 application.yml配置

在application.yml配置如下,除了server.port=8083的配置是server 对外公布的服务端口外,其他配置是server本身作为客户端的配置,包括指明指向服务端的地址和当前应用的基本信息,使用@@可以读取pom.xml的相关配置。

在下面Client配置的讲解中,可以看到下面类似的配置。

server:  port: 8083spring:  boot:    admin:      url: http://localhost:8083info:  name: server  description: @project.description@  version: @project.version@

3、配置日志级别

在application.yml的同级目录,添加文件logback.xml,用以配置日志的级别,包含的内容如下:

            

在此处配置成了DEBUG,这样可以通过控制台日志查看server端和client端的交互情况。

4、添加入口方法注解

在入口方法上添加@EnableAdminServer注解。

@Configuration@EnableAutoConfiguration@EnableAdminServerpublic class ServerApplication {    public static void main(String[] args) {        SpringApplication.run(ServerApplication.class, args);    }}

5、启动项目

启动admin-server项目后,可以看到当前注册的客户端,点击明细,还可以查看其他明细信息。

Client端

在上述的Server端配置中,server本身也作为一个客户端注册到自己,所以client配置同server端配置起来,比较见到如下。

创建一个admin-client项目,在pom.xml添加相关client依赖包。

1、pom.xml添加client依赖

            de.codecentric            spring-boot-admin-starter-client            1.5.3        

2、application.yml配置

在application.yml配置注册中心地址等信息:

spring:  boot:    admin:      url: http://localhost:8083info:  name: client  description: @project.description@  version: @project.version@endpoints:  trace:    enabled: true    sensitive: false

3、配置日志文件

在application.yml的同级目录,添加文件logback.xml,用以配置日志的级别,包含的内容如下:

            

配置为DEBUG的级别,可以输出和服务器的通信信息,以便我们在后续心跳检测,了解Spring Boot Admin的实现方式。

4、启动Admin-Client应用

启动客户端项目,在服务端监听了客户端的启动,并在页面给出了消息提示,启动后,服务端的界面显示如下:(两个客户端都为UP状态)

以上就可以使用Spring Boot Admin的各种监控服务了,下面谈一谈客户端和服务端怎么样做心跳检测的。

心跳检测/健康检测原理

原理

在Spring Boot Admin中,Server端作为注册中心,它要监控所有的客户端当前的状态。要知道当前客户端是否宕机,刚发布的客户端也能够主动注册到服务端。

服务端和客户端之间通过特定的接口通信(/health接口)通信,来监听客户端的状态。因为客户端和服务端不能保证发布顺序。

有如下的场景需要考虑:

  • 客户端先启动,服务端后启动

  • 服务端先启动,客户端后启动

  • 服务端运行中,客户端下线

  • 客户端运行中,服务端下线

所以为了解决以上问题,需要客户端和服务端都设置一个任务监听器,定时监听对方的心跳,并在服务器及时更新客户端状态。

上文的配置使用了客户端主动注册的方法。

调试准备

为了理解Spring Boot Admin的实现方式,可通过DEBUG 和查看日志的方式理解服务器和客户端的通信(心跳检测)

  • 在pom.xml右键spring-boot-admin-server和spring-boot-admin-starter-client,Maven-> DownLoad Sources and Documentation

  • 在logback.xml中设置日志级别为DEBUG

客户端发起POST请求

客户端相关类

  • RegistrationApplicationListener

  • ApplicationRegistrator

在客户端启动的时候调用RegistrationApplicationListener的startRegisterTask,该方法每隔 registerPeriod = 10_000L,(10秒:默认)向服务端POST一次请求,告诉服务器自身当前是有心跳的。

RegistrationApplicationListener

@EventListener    @Order(Ordered.LOWEST_PRECEDENCE)    public void onApplicationReady(ApplicationReadyEvent event) {        if (event.getApplicationContext() instanceof WebApplicationContext && autoRegister) {            startRegisterTask();        }    }    public void startRegisterTask() {        if (scheduledTask != null && !scheduledTask.isDone()) {            return;        }        scheduledTask = taskScheduler.scheduleAtFixedRate(new Runnable() {            @Override            public void run() {                registrator.register();            }        }, registerPeriod);        LOGGER.debug("Scheduled registration task for every {}ms", registerPeriod);    }

ApplicationRegistrator

 public boolean register() {        boolean isRegistrationSuccessful = false;        Application self = createApplication();        for (String adminUrl : admin.getAdminUrl()) {            try {                @SuppressWarnings("rawtypes") ResponseEntity response = template.postForEntity(adminUrl,                        new HttpEntity<>(self, HTTP_HEADERS), Map.class);                if (response.getStatusCode().equals(HttpStatus.CREATED)) {                    if (registeredId.compareAndSet(null, response.getBody().get("id").toString())) {                        LOGGER.info("Application registered itself as {}", response.getBody());                    } else {                        LOGGER.debug("Application refreshed itself as {}", response.getBody());                    }                    isRegistrationSuccessful = true;                    if (admin.isRegisterOnce()) {                        break;                    }                } else {                    if (unsuccessfulAttempts.get() == 0) {                        LOGGER.warn(                                "Application failed to registered itself as {}. Response: {}. Further attempts are logged on DEBUG level",                                self, response.toString());                    } else {                        LOGGER.debug("Application failed to registered itself as {}. Response: {}", self,                                response.toString());                    }                }            } catch (Exception ex) {                if (unsuccessfulAttempts.get() == 0) {                    LOGGER.warn(                            "Failed to register application as {} at spring-boot-admin ({}): {}. Further attempts are logged on DEBUG level",                            self, admin.getAdminUrl(), ex.getMessage());                } else {                    LOGGER.debug("Failed to register application as {} at spring-boot-admin ({}): {}", self,                            admin.getAdminUrl(), ex.getMessage());                }            }        }        if (!isRegistrationSuccessful) {            unsuccessfulAttempts.incrementAndGet();        } else {            unsuccessfulAttempts.set(0);        }        return isRegistrationSuccessful;    }

在主要的register()方法中,向服务端POST了Restful请求,请求的地址为/api/applications

并把自身信息带了过去,服务端接受请求后,通过sha-1算法计算客户单的唯一ID,查询hazelcast缓存数据库,如第一次则写入,否则更新。

服务端接收处理请求相关类

RegistryController

@RequestMapping(method = RequestMethod.POST)    public ResponseEntity register(@RequestBody Application application) {        Application applicationWithSource = Application.copyOf(application).withSource("http-api")                .build();        LOGGER.debug("Register application {}", applicationWithSource.toString());        Application registeredApp = registry.register(applicationWithSource);        return ResponseEntity.status(HttpStatus.CREATED).body(registeredApp);    }

ApplicationRegistry

public Application register(Application application) {        Assert.notNull(application, "Application must not be null");        Assert.hasText(application.getName(), "Name must not be null");        Assert.hasText(application.getHealthUrl(), "Health-URL must not be null");        Assert.isTrue(checkUrl(application.getHealthUrl()), "Health-URL is not valid");        Assert.isTrue(                StringUtils.isEmpty(application.getManagementUrl())                        || checkUrl(application.getManagementUrl()), "URL is not valid");        Assert.isTrue(                StringUtils.isEmpty(application.getServiceUrl())                        || checkUrl(application.getServiceUrl()), "URL is not valid");        String applicationId = generator.generateId(application);        Assert.notNull(applicationId, "ID must not be null");        Application.Builder builder = Application.copyOf(application).withId(applicationId);        Application existing = getApplication(applicationId);        if (existing != null) {            // Copy Status and Info from existing registration.            builder.withStatusInfo(existing.getStatusInfo()).withInfo(existing.getInfo());        }        Application registering = builder.build();        Application replaced = store.save(registering);        if (replaced == null) {            LOGGER.info("New Application {} registered ", registering);            publisher.publishEvent(new ClientApplicationRegisteredEvent(registering));        } else {            if (registering.getId().equals(replaced.getId())) {                LOGGER.debug("Application {} refreshed", registering);            } else {                LOGGER.warn("Application {} replaced by Application {}", registering, replaced);            }        }        return registering;    }

HazelcastApplicationStore (缓存数据库)

在上述更新状态使用了publisher.publishEvent事件订阅的方式,接受者接收到该事件,做应用的业务处理,在这块使用这种方式个人理解是为了代码的复用性,因为服务端定时轮询客户端也要更新客户端在服务器的状态。

pulishEvent设计到的类有:

  • StatusUpdateApplicationListener->onClientApplicationRegistered

  • StatusUpdater->updateStatus

这里不详细展开,下文还会提到,通过日志,可以查看到客户端定时发送的POST请求:

服务端定时轮询

在服务器宕机的时候,服务器接收不到请求,此时服务器不知道客户端是什么状态,(当然可以说服务器在一定的时间里没有收到客户端的信息,就认为客户端挂了,这也是一种处理方式),在Spring Boot Admin中,服务端通过定时轮询客户端的/health接口来对客户端进行心态检测。

这里设计到主要的类为:

StatusUpdateApplicationListene

@EventListener    public void onApplicationReady(ApplicationReadyEvent event) {        if (event.getApplicationContext() instanceof WebApplicationContext) {            startStatusUpdate();        }    }    public void startStatusUpdate() {        if (scheduledTask != null && !scheduledTask.isDone()) {            return;        }        scheduledTask = taskScheduler.scheduleAtFixedRate(new Runnable() {            @Override            public void run() {                statusUpdater.updateStatusForAllApplications();            }        }, updatePeriod);        LOGGER.debug("Scheduled status-updater task for every {}ms", updatePeriod);    }

StatusUpdater

public void updateStatusForAllApplications() {        long now = System.currentTimeMillis();        for (Application application : store.findAll()) {            if (now - statusLifetime > application.getStatusInfo().getTimestamp()) {                updateStatus(application);            }        }    }public void updateStatus(Application application) {        StatusInfo oldStatus = application.getStatusInfo();        StatusInfo newStatus = queryStatus(application);        boolean statusChanged = !newStatus.equals(oldStatus);        Application.Builder builder = Application.copyOf(application).withStatusInfo(newStatus);        if (statusChanged && !newStatus.isOffline() && !newStatus.isUnknown()) {            builder.withInfo(queryInfo(application));        }        Application newState = builder.build();        store.save(newState);        if (statusChanged) {            publisher.publishEvent(                    new ClientApplicationStatusChangedEvent(newState, oldStatus, newStatus));        }    }

感谢各位的阅读!关于"SpringBoot Admin怎么用"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

客户 服务 客户端 配置 日志 服务器 端的 信息 状态 方式 级别 项目 应用 检测 文件 方法 内容 更新 监听 管理 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技图片 广州紫鲸互联网科技有限公司 互联网科技工作委员会主任 深圳恒合互联网络科技有限公司 科技互联网项目 港股互联网科技股 与互联网科技公司 万易互联网科技有限公司 菲比寻常互联网科技 深圳期待互联网科技 互联网科技股有哪些 互联网之后的科技是什么 哈尔滨屹滨互联网科技有限公司 浙南科技城互联网大厦建设工程 山东星卡互联网科技有限公司官网 图游互联网科技 广州互联网高科技取餐柜 福州德业互联网科技 马化腾互联网科技教学 颐高云石互联网科技 圆梦互联网科技 互联网金融科技委员会 互联网科技实习生岗位职责 互联网金融中的现代科技 崇明区互联网教育科技售后服务 沐思想互联网科技有限公司 每天都有哪些好的互联网科技 互联网风格科技公司名称 下一代互联网重大应用科技园 唐山双旺合互联网科技产业园
0