SpringBootAdmin build Tutorial 9: microservice development Zookeeper registry integration SpringBootAdmin

Posted by rdub on Mon, 07 Mar 2022 23:46:28 +0100

In the previous article, we learned how to integrate SpringBootAdmin for monitoring and other operations by using Consul registration discovery in microservices. In this article, we learn how to integrate SpringBootAdmin in Zookeeper registry.

Introduction to Zookeeper

ZooKeeper is a software project of Apache Software Foundation. It provides open source distributed configuration services, synchronization services and naming registration for large-scale distributed computing.
ZooKeeper's architecture achieves high availability through redundant services.
The design goal of Zookeeper is to encapsulate those complex and error prone distributed consistency services, form an efficient and reliable primitive set, and provide users with a series of simple and easy-to-use interfaces.
A typical distributed data consistency solution. Based on it, distributed applications can realize functions such as data publish / subscribe, load balancing, naming service, distributed coordination / notification, cluster management, Master election, distributed lock and distributed queue.
Zookeeper tutorial Zookeeper tutorial
It is recommended that those unfamiliar with Zookeeper first take a look at the tutorial, installation and download.

This environment is on Windows, so it is mainly Windows.

Zookeeper installation and configuration tutorial

Windows starts zk service. Double click zkserver cmd
If there is a flash back, you should pay attention here,
zoo. The configuration of CFG needs to be changed. It may be the problem of the local environment. Change it to \ and do not remove dataLogDir.

# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
dataDir=E:\\tools\\apache-zookeeper-3.6.3-bin\\data
# the port at which the clients will connect

Then start. The default port is 2181

Zookeeper integrates SpringBootAdmin

Spring Cloud integrates Zookeeper. Please see the official website: Spring Cloud Zookeeper

Create a SpringBoot project and add dependencies such as Zookeeper.

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 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.3.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>spring-boot-admin-sample-zookeeper</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-admin-sample-zookeeper</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <!-- spring-cloud If the version appears with springboot Please check the version inconsistency https://spring.io/projects/spring-cloud#overview-->
        <spring-cloud.version>Hoxton.SR8</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
        </dependency>

        <!-- spring-boot-admin Server-->
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-server</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>io.projectreactor.netty</groupId>
                    <artifactId>reactor-netty</artifactId>
                </exclusion>
            </exclusions>
            <version>2.3.0</version>
        </dependency>

        <dependency>
            <groupId>io.projectreactor.netty</groupId>
            <artifactId>reactor-netty</artifactId>
            <version>0.9.10.RELEASE</version>
        </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>

        <!-- end::dependency-eureka[] -->
        <dependency>
            <groupId>org.jolokia</groupId>
            <artifactId>jolokia-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-context</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>
        </dependencies>
    </dependencyManagement>

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

yml configuration:

spring:
  application:
    name: zookeeper-example
  cloud:
    config:
      enabled: false
    zookeeper:
      connect-string: localhost:2181
      discovery:
        metadata:
          management.context-path: /foo
          health.path: /ping
          user.name: admin
          user.password: admin
  profiles:
    active:
      - secure
management:
  endpoints:
    web:
      exposure:
        include: "*"
      path-mapping:
        health: /ping
      base-path: /foo
  endpoint:
    health:
      show-details: ALWAYS
server:
  port: 8083
---
spring:
  profiles: insecure

---
spring:
  profiles: secure
  security:
    user:
      name: "admin"
      password: "admin"

Startup class configuration

Add the following note:

@EnableDiscoveryClient
@EnableAdminServer

@SpringBootApplication
@EnableDiscoveryClient
@EnableAdminServer
public class SpringBootAdminSampleZookeeperApplication {

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


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

        private final AdminServerProperties adminServer;

        public SecurityPermitAllConfig(AdminServerProperties adminServer) {
            this.adminServer = adminServer;
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests((authorizeRequests) -> authorizeRequests.anyRequest().permitAll())
                    .csrf((csrf) -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                            .ignoringRequestMatchers(
                                    new AntPathRequestMatcher(this.adminServer.path("/instances"),
                                            HttpMethod.POST.toString()),
                                    new AntPathRequestMatcher(this.adminServer.path("/instances/*"),
                                            HttpMethod.DELETE.toString()),
                                    new AntPathRequestMatcher(this.adminServer.path("/actuator/**"))));
        }

    }

    @Profile("secure")
    @Configuration(proxyBeanMethods = false)
    public static class SecuritySecureConfig extends WebSecurityConfigurerAdapter {

        private final AdminServerProperties adminServer;

        public SecuritySecureConfig(AdminServerProperties adminServer) {
            this.adminServer = adminServer;
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
            successHandler.setTargetUrlParameter("redirectTo");
            successHandler.setDefaultTargetUrl(this.adminServer.path("/"));

            http.authorizeRequests((authorizeRequests) -> authorizeRequests
                    .antMatchers(this.adminServer.path("/assets/**")).permitAll()
                    .antMatchers(this.adminServer.path("/login")).permitAll().anyRequest().authenticated())
                    .formLogin((formLogin) -> formLogin.loginPage(this.adminServer.path("/login"))
                            .successHandler(successHandler))
                    .logout((logout) -> logout.logoutUrl(this.adminServer.path("/logout")))
                    .httpBasic(Customizer.withDefaults())
                    .csrf((csrf) -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                            .ignoringRequestMatchers(
                                    new AntPathRequestMatcher(this.adminServer.path("/instances"),
                                            HttpMethod.POST.toString()),
                                    new AntPathRequestMatcher(this.adminServer.path("/instances/*"),
                                            HttpMethod.DELETE.toString()),
                                    new AntPathRequestMatcher(this.adminServer.path("/actuator/**"))));
        }

    }

}

After the configuration is successful, start zk, and then start the project. If you can access it normally and get the instance, the integration is successful.
The startup configuration is also the same, such as log configuration, mailbox configuration, remember login and so on. You can try it yourself.
Complete example code, GitHub: SpringBootAmdinDemo
If you have any questions, please discuss below and study together.

Topics: Java Spring Spring Boot Zookeeper