Spring Boot 2.1.1 - Eureka Discovery & Spring Boot Admin Server - PullRequest
0 голосов
/ 04 декабря 2018

В Spring Boot v1.5.x можно было использовать одну службу, двойную как сервер администрирования Spring Boot и сервер обнаружения Eureka.В Spring Boot 2.x создается впечатление, что Spring Boot Admin Server использует реактивный API-интерфейс Spring (webflux, Netty Server и т. Д.), А Netflix Eureka Discovery Server по-прежнему использует Tomcat.Я хотел бы знать, возможно ли использовать Netty для Eureka Server или каким-либо образом использовать Netty и Tomcat в одном сервисе.Пример кода ниже

import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableAdminServer
@EnableEurekaServer
@SpringBootApplication
public class EurekaSpringBootAdminApplication {

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

Пример кода ниже.

<?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.foo.bar</groupId>
<artifactId>eureka-springadmin-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>eureka-springadmin-service</name>
<description>Demo project for Spring Boot</description>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.1.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.1.1</spring-boot-admin.version>
    <spring-cloud.version>Greenwich.M3</spring-cloud.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>de.codecentric</groupId>
        <artifactId>spring-boot-admin-starter-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</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>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-release-plugin</artifactId>
            <version>2.5.3</version>
        </plugin>
    </plugins>
</build>

<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

ОБНОВЛЕНИЕ: Так что я наконец-то получил это на работу !!Во-первых, давайте посмотрим на pom.xml ниже

<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.1.1</spring-boot-admin.version>
    <spring-cloud.version>Greenwich.M3</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-security</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-webflux</artifactId>
        <exclusions>
            <exclusion>
                <artifactId>spring-boot-starter-reactor-netty</artifactId>
                <groupId>org.springframework.boot</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    <dependency>
        <groupId>io.projectreactor</groupId>
        <artifactId>reactor-core</artifactId>
        <version>3.2.2.RELEASE</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>io.projectreactor.netty</groupId>
        <artifactId>reactor-netty</artifactId>
        <version>0.8.2.RELEASE</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-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>

<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

Выше приведен модифицированный pom.xml.Два изменения были сделаны.Сначала я добавил зависимость spring-boot-starter-webflux, а затем исключил зависимость spring-boot-starter-reactor-netty из spring-boot-starter-webflux.Во-вторых, я вытащил реактор-ядро и реактор-нетто из io.projectreactor.SBA 2.1.1 опирается на реактивные библиотеки, в частности класс HttpClient.Это удовлетворяет все потребности SBA.Eureka Admin Server уже имеет все необходимое для запуска.

Теперь давайте взглянем на .properties для настройки самостоятельного обнаружения и извлечения реестра.

#PROJECT INFORMATION
spring.application.name= Eureka and SBA Service
info.app.name=@project.name@
info.app.description=@project.description@
info.app.version=@project.version@

#SERVER CONFIGURATION
server.port=10761
server.servlet.context-path=/

#MANAGEMENT CONFIGURATION
management.server.port=10769
management.server.servlet.context-path=/admin

##SPRING SECURITY CONFIGURATION
spring.security.user.name=admin
spring.security.user.password=adminadmin

#EUREKA DISCOVERY CONFIGURATION
eureka.instance.hostname=localhost
eureka.client.registry-fetch-interval-seconds=5
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
eureka.client.service-url.defaultZone=http://admin:adminadmin@localhost:10761/eureka

#SPRING BOOT ADMIN CONFIGURATION
spring.boot.admin.discovery.enabled=true
spring.boot.admin.context-path=/spring-admin/

В приведенном выше файле свойств показана Eurekaи конфигурация SBA.Действительно важными элементами являются fetch-registry, register-with-eureka, eureka.client.service-url.defaultZone, spring.boot.admin.discovery.enabled и spring.boot.admin.context-path.

Реквизиты fetch-registry позволяют клиентам регистрироваться не только в Eureka, но и в SBA.Недостатком является то, что служба будет пытаться получить реестр до полного запуска службы.Таким образом, вы увидите исключение при запуске службы.

register-with-eureka , позволяющее службе регистрироваться в Eureka и SBA.

eureka.client.service-url.defaultZone сообщает, где следует зарегистрироваться.В этом случае это с собой.Эту же конфигурацию необходимо применить к любому клиентскому серверу, желающему зарегистрироваться в Eureka и SBA.

spring.boot.admin.discovery.enabled позволяет обнаружение облака для SBA.Если для этого параметра установлено значение true, при выборке реестра SBA не будет регистрировать клиентов.

spring.boot.admin.context-path устанавливает путь контекста для SBA.Это необходимо, чтобы избежать конфликтов URL-адресов с Eureka.

В основном классе приложения убедитесь, что присутствуют следующие аннотации

import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableAdminServer
@EnableDiscoveryClient
@EnableEurekaServer
@SpringBootApplication
public class EurekaSbaApplication{

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

Я также добавил класс конфигурации веб-безопасности, который отключенCSRF, но я уверен, что это действительно необходимо.

ОБНОВЛЕНИЕ:

Я забыл упомянуть, что исключение иногда выдается после успешной регистрации клиента.IllegalStateException генерируется со следующим сообщением: «вызов aysncError () недопустим для запроса с асинхронным состоянием».Я еще не понимаю, почему это происходит, но, похоже, ничего не сломалось.

    2018-12-05 13:33:05.845 ERROR 19424 --- [io-10761-exec-9] o.a.catalina.connector.CoyoteAdapter     : Exception while processing an asynchronous request

java.lang.IllegalStateException: Calling [asyncError()] is not valid for a request with Async state [MUST_DISPATCH]
    at org.apache.coyote.AsyncStateMachine.asyncError(AsyncStateMachine.java:440) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.coyote.AbstractProcessor.action(AbstractProcessor.java:512) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.coyote.Request.action(Request.java:430) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.catalina.core.AsyncContextImpl.setErrorState(AsyncContextImpl.java:382) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:239) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.coyote.AbstractProcessor.dispatch(AbstractProcessor.java:241) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:791) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_172]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_172]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.13.jar:9.0.13]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_172]

1 Ответ

0 голосов
/ 04 декабря 2018

Может исключить Tomcat из ваших зависимостей и добавить Reactor Netty:

 <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    <exclusions>
        <!-- Exclude the Tomcat dependency -->
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

и добавить зависимости Reactor Netty.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-reactor-netty</artifactId>
    <version>{{version-needed}}</version>
</dependency>
...