SpringBoot admin 2.0 詳解

1、什麼是Spring Boot Admin ?

Spring Boot Admin是一個開源社區項目,用於管理和監控SpringBoot應用程序。 應用程序做爲Spring Boot Admin Client向爲Spring Boot Admin Server註冊(經過HTTP)或使用SpringCloud註冊中心(例如Eureka,Consul)發現。 UI是的Vue.js應用程序,展現Spring Boot Admin Client的Actuator端點上的一些監控。服務端採用Spring WebFlux + Netty的方式。Spring Boot Admin爲註冊的應用程序提供如下功能:php

  • 顯示健康情況
  • 顯示詳細信息,例如
  • JVM和內存指標
  • micrometer.io指標
  • 數據源指標
  • 緩存指標
  • 顯示構建信息編號
  • 關注並下載日誌文件
  • 查看jvm system-和environment-properties
  • 查看Spring Boot配置屬性
  • 支持Spring Cloud的postable / env-和/ refresh-endpoint
  • 輕鬆的日誌級管理
  • 與JMX-beans交互
  • 查看線程轉儲
  • 查看http-traces
  • 查看auditevents
  • 查看http-endpoints
  • 查看計劃任務
  • 查看和刪除活動會話(使用spring-session)
  • 查看Flyway / Liquibase數據庫遷移
  • 下載heapdump
  • 狀態變動通知(經過電子郵件,Slack,Hipchat,......)
  • 狀態更改的事件日誌(非持久性)

2、入門

1. 建立 Spring Boot Admin Server

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.gf</groupId>
    <artifactId>admin-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>admin-server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot-admin.version>2.1.0</spring-boot-admin.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>de.codecentric</groupId>
                <artifactId>spring-boot-admin-dependencies</artifactId>
                <version>${spring-boot-admin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
複製代碼

application.yml

spring:
 application:
 name: admin-server
server:
 port: 8769
複製代碼

啓動類 AdminServerApplication

啓動類加上@EnableAdminServer註解,開啓AdminServer的功能:java

@SpringBootApplication
@EnableAdminServer
public class AdminServerApplication {

    public static void main(String[] args) {
        SpringApplication.run( AdminServerApplication.class, args );
    }

}
複製代碼

2. 建立 Spring Boot Admin Client

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.gf</groupId>
    <artifactId>admin-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>admin-client</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot-admin.version>2.1.0</spring-boot-admin.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>de.codecentric</groupId>
                <artifactId>spring-boot-admin-dependencies</artifactId>
                <version>${spring-boot-admin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

複製代碼

application.yml

  • spring.boot.admin.client.url:要註冊的Spring Boot Admin Server的URL。
  • management.endpoints.web.exposure.include:與Spring Boot 2同樣,默認狀況下,大多數actuator的端口都不會經過http公開,* 表明公開全部這些端點。對於生產環境,應該仔細選擇要公開的端點。
spring:
 application:
 name: admin-client
 boot:
 admin:
 client:
 url: http://localhost:8769
server:
 port: 8768

management:
 endpoints:
 web:
 exposure:
 include: '*'
 endpoint:
 health:
 show-details: ALWAYS
複製代碼

啓動類 AdminClientApplication

@SpringBootApplication
public class AdminClientApplication {

    public static void main(String[] args) {
        SpringApplication.run( AdminClientApplication.class, args );
    }

}
複製代碼

啓動兩個工程,在瀏覽器上輸入localhost:8769 ,瀏覽器顯示的界面以下:git

查看wallboard:github

點擊wallboard,能夠查看admin-client具體的信息,好比內存狀態信息:web

查看spring bean的狀況:redis

查看應用程序運行情況,信息和詳細:spring

還有不少監控信息,多點一點就知道。數據庫

3、集成 Eureka

1. 建立 sc-eureka-server

這是一個 eureka-server 註冊中心。apache

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.gf</groupId>
    <artifactId>sc-admin-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sc-admin-server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot-admin.version>2.1.0</spring-boot-admin.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-server</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jolokia</groupId>
            <artifactId>jolokia-core</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>de.codecentric</groupId>
                <artifactId>spring-boot-admin-dependencies</artifactId>
                <version>${spring-boot-admin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

複製代碼

application.yml

spring:
 application:
 name: sc-eureka-server
server:
 port: 8761
eureka:
 client:
 service-url:
 defaultZone: http://localhost:8761/eureka
 register-with-eureka: false
 fetch-registry: false
management:
 endpoints:
 web:
 exposure:
 include: "*"
 endpoint:
 health:
 show-details: ALWAYS
複製代碼

啓動類 ScEurekaServerApplication

@SpringBootApplication
@EnableEurekaServer
public class ScEurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run( ScEurekaServerApplication.class, args );
    }

}
複製代碼

2. 建立 sc-admin-server

這是一個 Spring Boot Admin Server端。瀏覽器

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.gf</groupId>
    <artifactId>sc-admin-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sc-admin-server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot-admin.version>2.1.0</spring-boot-admin.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-server</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jolokia</groupId>
            <artifactId>jolokia-core</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>de.codecentric</groupId>
                <artifactId>spring-boot-admin-dependencies</artifactId>
                <version>${spring-boot-admin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

複製代碼

application.yml

spring:
 application:
 name: admin-server
server:
 port: 8769
eureka:
 client:
 registryFetchIntervalSeconds: 5
 service-url:
 defaultZone: ${EUREKA_SERVICE_URL:http://localhost:8761}/eureka/
 instance:
 leaseRenewalIntervalInSeconds: 10
 health-check-url-path: /actuator/health

management:
 endpoints:
 web:
 exposure:
 include: "*"
 endpoint:
 health:
 show-details: ALWAYS
複製代碼

啓動類 ScAdminServerApplication

@SpringBootApplication
@EnableAdminServer
@EnableDiscoveryClient
public class ScAdminServerApplication {

    public static void main(String[] args) {
        SpringApplication.run( ScAdminServerApplication.class, args );
    }

}
複製代碼

3. 建立 sc-admin-client

這是一個 Spring Boot Admin client 端。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.gf</groupId>
    <artifactId>sc-admin-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sc-admin-client</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot-admin.version>2.1.0</spring-boot-admin.version>
        <spring-cloud.version>Finchley.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>de.codecentric</groupId>
                <artifactId>spring-boot-admin-dependencies</artifactId>
                <version>${spring-boot-admin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

複製代碼

application.yml

spring:
  application:
    name: sc-admin-client
eureka:
  instance:
    leaseRenewalIntervalInSeconds: 10
    health-check-url-path: /actuator/health

  client:
    registryFetchIntervalSeconds: 5
    service-url:
      defaultZone: ${EUREKA_SERVICE_URL:http://localhost:8761}/eureka/
management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: ALWAYS
server:
  port: 8762
複製代碼

啓動類 ScAdminClientApplication

@SpringBootApplication
@EnableDiscoveryClient
public class ScAdminClientApplication {

    public static void main(String[] args) {
        SpringApplication.run( ScAdminClientApplication.class, args );
    }

}
複製代碼

啓動三個工程,訪問localhost:8769,出現以下界面:

admin 會本身拉取 Eureka 上註冊的 app 信息,主動去註冊。這也是惟一區別以前入門中手動註冊的地方,就是 client 端不須要 admin-client 的依賴,也不須要配置 admin 地址了,一切所有由 admin-server 本身實現。這樣的設計對環境變化很友好,不用改了admin-server後去改全部app 的配置了。

4、集成 Spring Security

Web應用程序中的身份驗證和受權有多種方法,所以Spring Boot Admin不提供默認方法。默認狀況下,spring-boot-admin-server-ui提供登陸頁面和註銷按鈕。咱們結合 Spring Security 實現須要用戶名和密碼登陸的安全認證。

sc-admin-server工程的pom文件須要增長如下的依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
複製代碼

在 sc-admin-server工的配置文件 application.yml 中配置 spring security 的用戶名和密碼,這時須要在服務註冊時帶上 metadata-map 的信息,以下:

spring:
 security:
 user:
 name: "admin"
 password: "admin"
      
eureka:
 instance:
 metadata-map:
      user.name: ${spring.security.user.name}
      user.password: ${spring.security.user.password}
複製代碼

@EnableWebSecurity註解以及WebSecurityConfigurerAdapter一塊兒配合提供基於web的security。繼承了WebSecurityConfigurerAdapter以後,再加上幾行代碼,咱們就能實現要求用戶在進入應用的任何URL以前都進行驗證的功能,寫一個配置類SecuritySecureConfig繼承WebSecurityConfigurerAdapter,配置以下:

@Configuration
public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {

    private final String adminContextPath;

    public SecuritySecureConfig(AdminServerProperties adminServerProperties) {
        this.adminContextPath = adminServerProperties.getContextPath();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setTargetUrlParameter("redirectTo");
        successHandler.setDefaultTargetUrl(adminContextPath + "/");

        http.authorizeRequests()
                //授予對全部靜態資產和登陸頁面的公共訪問權限。
                .antMatchers(adminContextPath + "/assets/**").permitAll()
                .antMatchers(adminContextPath + "/login").permitAll()
                //必須對每一個其餘請求進行身份驗證
                .anyRequest().authenticated()
                .and()
                //配置登陸和註銷
                .formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and()
                .logout().logoutUrl(adminContextPath + "/logout").and()
                //啓用HTTP-Basic支持。這是Spring Boot Admin Client註冊所必需的
                .httpBasic().and();
        // @formatter:on
    }
}
複製代碼

從新訪問 http://localhost:8769/ 會出現登陸界面,密碼是 配置文件中配置好的,帳號 admin 密碼 admin,界面以下:

5、通知

1. 郵件通知

在 Spring Boot Admin 中 當註冊的應用程序狀態更改成DOWN、UNKNOWN、OFFLINE 均可以指定觸發通知,下面講解配置郵件通知。

在sc-admin-server工程pom文件,加上mail的依賴,以下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>
複製代碼

在配置文件application.yml文件中,配置收發郵件的配置:

spring:
 mail:
 host: smtp.163.com
 username: xxxx@163.com
 password: xxxx
 properties:
 mail:
 smtp:
 auth: true
 starttls:
 enable: true
 required: true
 boot:
 admin:
 notify:
 mail:
 from: xxxx@163.com
 to: xxxx@qq.com
複製代碼

配置後,重啓sc-admin-server工程,以後若出現註冊的客戶端的狀態從 UP 變爲 OFFLINE 或其餘狀態,服務端就會自動將電子郵件發送到上面配置的收件地址。

注意 : 配置了郵件通知後,會出現 反覆通知 service offline / up。這個問題的緣由在於 查詢應用程序的狀態和信息超時,下面給出兩種解決方案:

#方法一:增長超時時間(單位:ms)

spring.boot.admin.monitor.read-timeout=20000

#方法二:關閉閉未使用或不重要的檢查點

management.health.db.enabled=false
management.health.mail.enabled=false
management.health.redis.enabled=false
management.health.mongo.enabled=false
複製代碼

2. 自定義通知

能夠經過添加實現Notifier接口的Spring Beans來添加您本身的通知程序,最好經過擴展 AbstractEventNotifier或AbstractStatusChangeNotifier。在sc-admin-server工程中編寫一個自定義的通知器:

@Component
public class CustomNotifier extends AbstractStatusChangeNotifier {
    private static final Logger LOGGER = LoggerFactory.getLogger( LoggingNotifier.class);

    public CustomNotifier(InstanceRepository repository) {
        super(repository);
    }

    @Override
    protected Mono<Void> doNotify(InstanceEvent event, Instance instance) {
        return Mono.fromRunnable(() -> {
            if (event instanceof InstanceStatusChangedEvent) {
                LOGGER.info("Instance {} ({}) is {}", instance.getRegistration().getName(), event.getInstance(),
                        ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus());

                String status = ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus();

                switch (status) {
                    // 健康檢查沒經過
                    case "DOWN":
                        System.out.println("發送 健康檢查沒經過 的通知!");
                        break;
                    // 服務離線
                    case "OFFLINE":
                        System.out.println("發送 服務離線 的通知!");
                        break;
                    //服務上線
                    case "UP":
                        System.out.println("發送 服務上線 的通知!");
                        break;
                    // 服務未知異常
                    case "UNKNOWN":
                        System.out.println("發送 服務未知異常 的通知!");
                        break;
                    default:
                        break;
                }

            } else {
                LOGGER.info("Instance {} ({}) {}", instance.getRegistration().getName(), event.getInstance(),
                        event.getType());
            }
        });
    }
}
複製代碼

源碼下載:github.com/gf-huanchup…

相關文章
相關標籤/搜索