SpringCloud2.0入門4-springboot-admin監控


前言

上一節為springboot項目添加springboot-admin監控 學習了基於springboot1.5自己注冊到admin的方法。接下來學習結合Eureka使用以及2.0的改變。

1.5spring-boot-admin集成eureka

我們繼續上一節的項目修改,admin-server依賴修改如下

<dependencies>
    <dependency>
      <groupId>de.codecentric</groupId>
      <artifactId>spring-boot-admin-starter-server</artifactId>
    </dependency>
    <dependency>
      <groupId>de.codecentric</groupId>
      <artifactId>spring-boot-admin-server-ui</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-eureka</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>
    </dependencies>
</dependencyManagement>   

修改啟動類,添加

@EnableDiscoveryClient
@EnableAdminServer

修改配置文件application.properties

server.port=8081
spring.application.name=admin-server
eureka.client.serviceUrl.defaultZone=${EUREKA_SERVICE_URL:http://localhost:8761}/eureka/
management.security.enabled=false

注意,這里的eureka server要提前啟動。具體細節,參見SpringCloud入門1-服務注冊與發現(Eureka)

到這里就結束,可以直接啟動。admin會自己拉取Eureka上注冊的app信息,主動去注冊。這也是唯一區別之前手動注冊的地方,就是client端不需要admin-client的依賴,也不需要配置admin地址了,一切全部由admin-server自己實現。這樣的設計對環境變化很友好,不用改了admin-server后去改所有app的配置了。

spring-boot-admin2.0的巨變

以為2.0比1.5區別不大,也確實不很大。關於client主動注冊的部分沒有變化。

這里,重新學習一遍,並添加上安全登錄功能。

新建一個springboot項目

項目地址:

https://github.com/Ryan-Miao/spring-cloud-demo/tree/master/admin-server

添加spring-boot-admin-server, 最終pom依賴如下


<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.2.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <spring-boot-admin.version>2.0.0</spring-boot-admin.version>
    <spring-cloud.version>Finchley.RC2</spring-cloud.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>de.codecentric</groupId>
      <artifactId>spring-boot-admin-starter-server</artifactId>
    </dependency>
    <!--還沒有發布-->
    <!--<dependency>-->
      <!--<groupId>de.codecentric</groupId>-->
      <!--<artifactId>spring-boot-admin-server-cloud</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-security</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
   <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </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>
    </dependencies>
  </dependencyManagement>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>build-info</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

  <repositories>
    <repository>
      <id>central</id>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <name>aliyun</name>
    </repository>
    <repository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>

注意到里面添加spring cloud eureka的依賴,我們也把admin給注冊到eureka。

這次的配置文件比較復雜

spring:
  application:
    name: admin-server
  profiles:
    active:
      - secure


# tag::configuration-eureka[]
eureka:   #<1>
  instance:
    leaseRenewalIntervalInSeconds: 10
    health-check-url-path: /actuator/health #2.0后actuator的地址發生了變化
  client:
    registryFetchIntervalSeconds: 5
    serviceUrl:
      defaultZone: ${EUREKA_SERVICE_URL:http://localhost:8761}/eureka/

# 2.0開始,actuator默認不開放,所以要設置為開放
management:
  endpoints:
    web:
      exposure:
        include: "*"  #<2>
  endpoint:
    health:
      show-details: ALWAYS
server:
  port: 8081
# end::configuration-eureka[]

---
spring:
  profiles: insecure

---
# admin登錄的用戶名和密碼
spring:
  profiles: secure
  security:
    user:
      name: "user"
      password: "password"

# 注冊給eureka的時候告訴eureka自己的密碼
eureka:
  instance:
    metadata-map:
      "user.name": ${spring.security.user.name}         #These two are needed so that the server
      "user.password": ${spring.security.user.password} #can access the protected client endpoints

首先,我們同時支持兩種安全配置,一種沒有安全認證,一種有。注意到前面的依賴pom里有security的依賴。針對security方案,需要配置用戶名和密碼。

其次,配置了eureka client相關參數,把自己注冊到eureka里。

然后,關於actuator的端點接口,設置為全部開放。

最后,設置我們的用戶名和密碼,並把用戶名和密碼放到eureka里,方便識別。

配置security的安全過濾

最終的啟動類如下


@EnableDiscoveryClient
@EnableAdminServer
@SpringBootApplication
public class AdminServerApplication {

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

    @Profile("insecure")
    @Configuration
    public static class SecurityPermitAllConfig extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().permitAll()//
                .and().csrf().disable();
        }
    }

    @Profile("secure")
    @Configuration
    public static 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");

            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()
                .httpBasic().and()
                .csrf().disable();
            // @formatter:on
        }
    }
}

和之前沒啥不同,唯一的區別是添加了安全認證相關的,即采用secure模式的時候必須輸入用戶名和密碼。

啟動

我們啟動並選擇激活配置環境secure

訪問localhost:8081

登錄

詳細頁

界面確實比1.5好很多啊。

新建一個app來注冊

依舊采用手動注冊的方式,新建一個springboot項目,項目地址

https://github.com/Ryan-Miao/spring-cloud-demo/tree/master/provider-demo

首先,pom依賴要有eureka

<?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>

  <groupId>com.test</groupId>
  <artifactId>provider-demo</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>provider-demo</name>
  <description>Demo project for Spring Boot</description>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.2.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <spring-cloud.version>Finchley.RC2</spring-cloud.version>
    <spring-boot-admin.version>2.0.0</spring-boot-admin.version>
  </properties>

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

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-devtools</artifactId>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger2</artifactId>
      <version>2.7.0</version>
    </dependency>
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger-ui</artifactId>
      <version>2.7.0</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</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>
        <executions>
          <execution>
            <goals>
              <goal>build-info</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

  <repositories>
    <repository>
      <id>central</id>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <name>aliyun</name>
    </repository>
    <repository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>


</project>

注意,配置了eureka,用來注冊。

依賴springfox-swagger2用來展示API。

spring-boot-admin-starter-client才是主動注冊的核心庫,用來發送注冊申請。

需要再次強調了是build

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>build-info</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

這里是為了生成版本信息,提供給spring-boot-admin展示。

provider-demo的配置文件

eureka:
  instance:
    leaseRenewalIntervalInSeconds: 10
    health-check-url-path: /actuator/health
  client:
    registryFetchIntervalSeconds: 5
    serviceUrl:
      defaultZone: ${EUREKA_SERVICE_URL:http://localhost:8761}/eureka/

management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: ALWAYS

server:
  port: 8082

spring:
  application:
    name: provider-demo
  boot:
    admin:
      client:
        url: "http://localhost:8081"
        password: password
        username: user
        instance:
          prefer-ip: true

eureka的配置和admin-server相同,畢竟都是eureka的client嘛。不同的是這里沒有開啟spting security,所以不添加用戶名和密碼信息到meta-data里。

actuator同樣需要暴露全部。

關於spring-boot-admin-client的注冊配置里多了username和password,這個不是自己的,而是admin-server設置的,即前文的里的。

啟動后就可以看到前面的詳細信息了。

巨變在這里

在1.5版本里,我們只要加上eureka注冊,就可以admin-server自動發現所有的app並自己注冊監控了。但這里居然行不通了。我調試了幾個小時,把依賴包翻來覆去研究了好多遍----就是不行!!!

無奈,只好去github把spring-boot-admin的源碼下載下來,找到注冊的代碼開始追蹤。我發現,根本沒有提供任何和eureka注冊中心相關的代碼。看到了spring-boot-admin-server-cloud, 進去看了源碼,這里有關於注冊中心的監聽代碼,也就是admin自動發現app的密碼所在。那我把這個加入dependency不就好了嗎,太年輕。加上后發現找不到版本。我說不應該啊,我有導入dependencyManagement的pom啊。手動指定版本也不行。最后無奈的發現,原來根本沒有發布!!!

⚠️Note: Since Spring Cloud Finchley is not released yet, this version doesn't include Spring Cloud Discovery support

所以,手動注冊吧,騷年。不然你再等等。

結語

通過這一下午的嘗試,追蹤源碼,我發現自己確實挺樂在其中的。然而,這花費了大量的時間和精力。所以,我花費了更多的時間一定要把這次經歷記錄下來,也就是本文了。想說的是,最新的版本果然是坑巨多,慎入!!!如果是作為生產環境的選型,必須跳過這樣的版本。當然,如果是自己個人研究,看新的沒錯。

那么,我到底應不應該學習2.0呢,畢竟1.5也沒學完呢。

學吧,按2.0的學習,工作中還是用1.5. 嗯,就這樣吧。

Miao語

沒有解決不了的bug,只要你用心研究,都可以解決。

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM