简体   繁体   English

Spring Cloud Gateway服务器启动期间出现问题?

[英]Problem during Spring Cloud Gateway server startup?

I have a simple Spring Cloud microservices system. 我有一个简单的Spring Cloud微服务系统。 I have a Cloud Gateway server in the application. 我在应用程序中有一个Cloud Gateway服务器。 It registers with Eureka, get the address of Config Server and downloads the config for itself. 它在Eureka中注册,获取Config Server的地址并自行下载配置。

This gateway service will be the place of login, and it also finds the right Microservice, what the client is really want to call. 该网关服务将是登录的地方,并且还会找到正确的微服务,即客户真正想要调用的服务。 It is using Redis for session handling and distribution. 它使用Redis进行会话处理和分发。

But during startup, I see this failure: 但是在启动过程中,我看到此失败:

***************************
APPLICATION FAILED TO START
***************************

Description:

The bean 'sessionRepository', defined in class path resource     [org/springframework/boot/autoconfigure/session/RedisReactiveSessionConfiguration$SpringBootRedisWebSessionConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.class] and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding by setting  spring.main.allow-bean-definition-overriding=true

[WARNING] 
java.lang.reflect.InvocationTargetException
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:566)
at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run (AbstractRunMojo.java:558)
at java.lang.Thread.run (Thread.java:834)

Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'sessionRepository' defined in class path resource  [org/springframework/boot/autoconfigure/session/RedisReactiveSessionConfiguration$SpringBootRedisWebSessionConfiguration.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.session.RedisReactiveSessionConfiguration$SpringBootRedisWebSessionConfiguration; factoryMethodName=sessionRepository; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/session/RedisReactiveSessionConfiguration$SpringBootRedisWebSessionConfiguration.class]] for bean 'sessionRepository': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration; factoryMethodName=sessionRepository; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.class]] bound.

at  org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition (DefaultListableBeanFactory.java:894)

Here is the pom.xml for the gateway app: 这是网关应用程序的pom.xml:

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

<artifactId>elszamolas-gateway</artifactId>
<packaging>jar</packaging>

<name>elszamolas-gateway</name>
<description>TAO elszamolas GATEWAY service</description>

<parent>
    <groupId>com.besztercekk.tao</groupId>
    <artifactId>tao-elszamolas</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath>../pom.xml</relativePath>
</parent>


<dependencies>
    <!-- Spring Cloud Gateway service -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>

    <!-- Spring Cloud Eureka client -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <!-- Spring Cloud config client -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-client</artifactId>
    </dependency>

    <!-- Spring Boot reactive web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>

    <!-- Spring Boot share session via Redis -->
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-data-redis</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
    </dependency>

    <!-- Servlet API -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <scope>provided</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>
</project>

And this is its parent pom.xml: 这是其父pom.xml:

<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.besztercekk.tao</groupId>
<artifactId>tao-elszamolas</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>

<name>elszamolas</name>
<description>TAO elszámolás szülő project</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-cloud.version>Greenwich.M3</spring-cloud.version>
    <spring-session.version>1.3.4.RELEASE</spring-session.version>
    <spring-session-core.version>2.1.2.RELEASE</spring-session-core.version>
</properties>

<modules>
    <module>elszamolas-config</module>
    <module>elszamolas-discovery</module>
    <module>elszamolas-gateway</module>
</modules>

<dependencies>

    <!-- Common Spring Boot Dependencies -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

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

    <!-- Spring Security -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    <!-- Java 11 required dependencies -->
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-core</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>2.3.1</version>
    </dependency>
    <dependency>
        <groupId>javax.activation</groupId>
        <artifactId>activation</artifactId>
        <version>1.1.1</version>
    </dependency>
</dependencies>

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

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <release>11</release>
            </configuration>
        </plugin>   
    </plugins>
</build>
</project>

Any help would be very much appreciated. 任何帮助将不胜感激。 I can't really find out why this " sessionRepository " bean is loaded multiple times, from multiple places. 我真的不知道为什么从多个位置多次加载“ sessionRepository ” bean。 Did I mix up the necessary dependencies? 我是否混合了必要的依赖项?

UPDATE: 更新:

I had a closer look on this issue. 我对这个问题进行了仔细研究。 The exception is pretty clear the bean called, it says the bean sessionRepository is defined twice. 很清楚,调用的bean很例外,它说bean sessionRepository被定义了两次。 If you check the classes where they defined, and where they are coming from, you'll find out that one of them is coming from autoconfigurator and the other one is from the Redis session data dependency. 如果检查这些类的定义以及它们的来源,则将发现其中一个来自自动配置器,另一个来自Redis会话数据依赖项。

At this point it pretty much looks like you need to allow the bean overriding, what you can easily do by adding this to bootstrap.yml : 此时,您似乎似乎需要允许Bean覆盖,可以通过将其添加到bootstrap.yml来轻松实现:

spring:
  main:
    allow-bean-definition-overriding: true

But if you do that couple of other exceptions what you'll need to face. 但是,如果您还有其他一些例外,您将需要面对。 There is a point behind the guys made this option false by default. 伙计们默认情况下将此选项设置为false有一点。 Here is a sample exception what you cab get: 这是您的出租车得到的示例异常:

2018-12-20 00:37:22.965 ERROR 3089 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'redisMessageListenerContainer' defined in class path resource     org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.redis.listener.RedisMessageListenerContainer]: Factory method 'redisMessageListenerContainer' threw exception; nested exception is java.lang.IllegalStateException: @Bean method RedisHttpSessionConfiguration.sessionRepository called as bean reference for type [org.springframework.session.data.redis.RedisOperationsSessionRepository] but overridden by non-compatible bean instance of type [org.springframework.session.data.redis.ReactiveRedisOperationsSessionRepository]. Overriding bean of same name declared in: class path resource [org/springframework/boot/autoconfigure/session/RedisReactiveSessionConfiguration$SpringBootRedisWebSessionConfiguration.class]

Please, correct me if I'm wrong. 请,如果我错了,请纠正我。 I'd really appreciate that. 我真的很感激。 But when you need the Spring boot auto configuration feature you just can't use Redis for session storage and distribution to microservices. 但是,当您需要Spring Boot自动配置功能时,就不能使用Redis进行会话存储和分发到微服务。 It is just not working together. 它只是不能一起工作。 It's a bit hard to believe that, because there must be something what you can use in a Spring Boot 2.1.1 application when you really not want to authenticate your user in each and every microservice. 很难相信,因为当您确实不想在每个微服务中对用户进行身份验证时,在Spring Boot 2.1.1应用程序中必须可以使用某些东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM