Skip to content

Spring Boot Admin & Nacos

🏷️ Spring Boot Admin

之前只采用过 Spring Boot Admin Server(简称 SBA Server ) ➕ Spring Boot Admin Client 的方式来访问各服务的 Actuator 暴露的端点。这种方式需要在每个服务中添加 spring-boot-admin-client 依赖并做相应的配置,这就导致在 SBA Server 和具体服务之间产生了耦合。

对此 SBA Server 提供的解决方案是从注册中心获取服务信息,然后再访问服务暴露的端点。国内的项目使用 Nacos 的较多,但可惜官方 Guide 里并没有提供对应的写法。

今天正好准备给一个项目添加监控服务,所以调查了下当前较新版本的 SBA Server 从 Nacos 注册中心获取服务信息的写法。

当前 spring-cloud-alibaba-dependencies 较新的版本是 2021.0.4.0 ,对应的 spring-cloud-dependencies 的版本是 2021.0.4

PS. 之前 spring-cloud-alibaba-dependencies 的版本号使用的是 1.0.0.RELEASE 这样的格式,而 spring-cloud-dependencies 则使用的是比较奇葩的伦敦地铁站的名字 Greenwich.SR1 这样的格式。
估计是因为地铁站名实在是难以理解,所以改成了 2021.0.4 的格式,而 spring-cloud-alibaba-dependencies 为了统一,也改为使用类似的版本号。
感觉这种格式确实好一些,最明显的是能知道是哪年的版本。
而且由于大版本号不再是各自递增,相关的包可以统一采用相同的大版本号(比如上面的 2021.0.4 ),这样开发者就可以很容易的知道哪些版本和哪些版本兼容了。

示例代码

这里使用 Maven 管理版本,其 pom.xml 文件内容如下:

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 https://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.6.11</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>me.liujiajia</groupId>
    <artifactId>app-admin</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SBA Server</name>
    <description>Spring Boot Admin Server.</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot-admin.version>2.6.9</spring-boot-admin.version>
        <spring-cloud.version>2021.0.4</spring-cloud.version>
        <spring-cloud-alibaba.version>2021.0.4.0</spring-cloud-alibaba.version>
    </properties>

    <dependencies>
        <!-- SBA Server -->
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-server</artifactId>
        </dependency>
        <!-- Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Security 启用鉴权时需要添加此依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!-- Actuator 需要监控 SBA Server 服务本身时需添加此依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- Nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!-- 添加 spring-cloud-starter-bootstrap 依赖是为了解决服务启动报错:No spring.config.import property has been defined -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
        <!-- Test -->
        <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>
            <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>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.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>
                <version>2.6.11</version>
            </plugin>
        </plugins>
    </build>

</project>

bootstrap.yml 配置 Nacos 服务地址、命名空间等信息( ${NACOS_NAMESPACE} 的写法支持从环境变量获取对应的值,可以通过在变量名后添加 :default-value 的形式指定默认值,如 ${NACOS_NAMESPACE:test} ):

yaml
spring:
  cloud:
    nacos:
      config:
        namespace: ${NACOS_NAMESPACE}
        server-addr: ${NACOS_SERVER_ADDR}
        file-extension: yml
        group: jiajia
      # 如果希望监控 SBA Server 服务本身,
      # 则需要添加 discovery 配置将自身注册到 Nacos
      discovery:
        namespace: ${NACOS_NAMESPACE}
        server-addr: ${NACOS_SERVER_ADDR}

application.yml 中配置 SBA Server 等信息(也可以将这些配置放到 Nacos 配置中心里):

yaml
management:
  endpoints:
    web:
      exposure:
        include: '*'
  endpoint:
    health:
      show-details: ALWAYS
  server:
    # 由于 Actuator 暴露的内容含有很多敏感信息,
    # 因此产线环境一定要将其设置为同服务接口不一样的端口,
    # 并配合服务的安全设置避免其被外部人员访问
    port: 9999

server:
  # 服务本身的端口(默认为 8080)
  port: 8888

spring:
  application:
    name: app-admin
  boot:
    admin:
      # 添加 instance-auth 配置是因为 SBA Server 启用了用户鉴权
      # 此时访问服务本身暴露的 Actuator 接口同样也需要鉴权
      # 用户密码设置为和 *spring.security.user* 一样即可
      instance-auth:
        enabled: true
        default-user-name: ${ADMIN_USERNAME}
        default-password: ${ADMIN_PASSWORD}
  security:
    # 配置 SBA Server 的登录用户名和密码
    # 若未配置会自动生成用户名(user)和密码(随机字符,会打印在启动的日志中)
    user:
      name: ${ADMIN_USERNAME}
      password: ${ADMIN_PASSWORD}

启动类需要添加 @EnableAdminServer 注解:

java
package me.liujiajia.admin;

import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author 佳佳
 */
@EnableAdminServer
@SpringBootApplication
public class AdminApplication {

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

}

附 1. No spring.config.import property has been defined

若未添加 spring-cloud-starter-bootstrap 依赖,启动时会报如下错误:

Description:

No spring.config.import property has been defined

Action:

Add a spring.config.import=nacos: property to your configuration.
If configuration is not required add spring.config.import=optional:nacos: instead.
To disable this check, set spring.cloud.nacos.config.import-check.enabled=false.

参考链接