在 Tomcat 服务器中使用 Redis 服务器部署 Spring 引导应用程序时出错
Error while deploying the Spring Boot app using Redis server in Tomcat server
我有一个基于 Spring boot (2.1.9.RELEASE) 并使用 Redis 的 Web 应用程序服务器(Redis-x64-3.2.100 运行 作为服务)用于会话属性存储
在Eclipse中的部署作为Spring启动应用程序顺利,应用程序可以连接到Redis服务器,我们可以store/retrieve会话属性
但是当我想在Tomcat(第9版)中部署时,我在springframework中遇到了链接到redis api的问题:
Caused by: java.lang.LinkageError: loader constraint violation:
when resolving method "io.reactivex.Flowable.fromPublisher(Lorg/reactivestreams/Publisher;)Lio/reactivex/Flowable;"
the class loader (instance of org/apache/catalina/loader/ParallelWebappClassLoader) of the current class,
org/springframework/core/ReactiveAdapterRegistry$RxJava2Registrar, and the class loader (instance of java/net/URLClassLoader)
for the method's defining class, io/reactivex/Flowable, have different Class objects for the type org/reactivestreams/Publisher used in the signature
鉴于我已经在 Tomcat 服务器中设置了所有必需的配置,在 context.xml:
<ResourceLink name="bean/redisson"
global="bean/redisson"
type="org.redisson.api.RedissonClient" />
<Manager className="org.redisson.tomcat.JndiRedissonSessionManager"
readMode="REDIS"
jndiName="bean/redisson" />
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
<Manager className="org.redisson.tomcat.RedissonSessionManager"
configPath="${catalina.base}/conf/redisson.yaml"
readMode="REDIS" updateMode="DEFAULT" broadcastSessionEvents="false"/>
server.xml的变化:
<Resource name="bean/redisson"
auth="Container"
factory="org.redisson.JndiRedissonFactory"
configPath="${catalina.base}/conf/redisson.yaml"
closeMethod="shutdown"/>
redisson.yaml 包含:
singleServerConfig:
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
password: null
subscriptionsPerConnection: 5
clientName: null
address: "redis://127.0.0.1:6379"
subscriptionConnectionMinimumIdleSize: 1
subscriptionConnectionPoolSize: 50
connectionMinimumIdleSize: 24
connectionPoolSize: 64
database: 0
dnsMonitoringInterval: 5000
threads: 16
nettyThreads: 32
codec: !<org.redisson.codec.FstCodec> {}
transportMode: "NIO"
然后我将 redisson-all-3.11.6.jar 和 redisson-tomcat-9-3.11.6.jar 放在 Tomcat lib 文件夹中
redis 与 Tomcat 兼容性的问题吗?我错过了什么 ?
提前感谢您的帮助。
错误说的很清楚:
Caused by: java.lang.NoSuchMethodError: org.springframework.data.redis.connection.RedisConnection.getConfig(Ljava/lang/String;)Ljava/util/List;
请阅读 java.lang.NoSuchMethodError
这基本上是在告诉您在 运行 时找不到此方法。您必须执行以下步骤:
- 找出哪个库(jar)文件有这个方法,验证方法签名。
- 确保该库是您的 class 路径的一部分,即应该是您的 maven 或 gradle 文件的一部分。
- 检查是否存在冲突。如果您有任何其他 jar 文件也提供相同的 class,即 RedisConnection,那么您必须删除那个多余的 jar 文件。
基本上,错误的出现是因为程序正在调用 RedisConnection class 但无法在 class 中找到 getConfig 方法(相同的签名)。
我的猜测是您有两个相互冲突的库并且调用了错误的库。您必须删除或清理依赖项。
经过长时间的检查,发现 Redis 库和 Tomcat 服务器内部库之间存在冲突
最后,我决定将会话存储切换到 JDBC 并完全丢弃 Redis :
在application.properties文件中
- 设置应用属性spring.session.store-type=jdbc
- 设置应用属性spring.session.jdbc.table-name=SPRING_SESSION
- 设置应用程序 属性 spring.jpa.hibernate.ddl-auto=none(直接从 sql 脚本创建模式)
在schema.sql文件中
添加两个管理会话的表:
CREATE TABLE IF NOT EXISTS SPRING_SESSION (
PRIMARY_ID CHAR(36) NOT NULL,
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
EXPIRY_TIME BIGINT NOT NULL,
PRINCIPAL_NAME VARCHAR(100),
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
);
CREATE UNIQUE INDEX IF NOT EXISTS SPRING_SESSION_IX1 ON MATFRONT.SPRING_SESSION (SESSION_ID);
CREATE INDEX IF NOT EXISTS SPRING_SESSION_IX2 ON MATFRONT.SPRING_SESSION (EXPIRY_TIME);
CREATE INDEX IF NOT EXISTS SPRING_SESSION_IX3 ON MATFRONT.SPRING_SESSION (PRINCIPAL_NAME);
CREATE TABLE IF NOT EXISTS SPRING_SESSION_ATTRIBUTES (
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES BLOB NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES MATFRONT.SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
);
多亏了它,我摆脱了仅用于存储会话数据的额外的整个服务器
我有一个基于 Spring boot (2.1.9.RELEASE) 并使用 Redis 的 Web 应用程序服务器(Redis-x64-3.2.100 运行 作为服务)用于会话属性存储
在Eclipse中的部署作为Spring启动应用程序顺利,应用程序可以连接到Redis服务器,我们可以store/retrieve会话属性
但是当我想在Tomcat(第9版)中部署时,我在springframework中遇到了链接到redis api的问题:
Caused by: java.lang.LinkageError: loader constraint violation:
when resolving method "io.reactivex.Flowable.fromPublisher(Lorg/reactivestreams/Publisher;)Lio/reactivex/Flowable;"
the class loader (instance of org/apache/catalina/loader/ParallelWebappClassLoader) of the current class,
org/springframework/core/ReactiveAdapterRegistry$RxJava2Registrar, and the class loader (instance of java/net/URLClassLoader)
for the method's defining class, io/reactivex/Flowable, have different Class objects for the type org/reactivestreams/Publisher used in the signature
鉴于我已经在 Tomcat 服务器中设置了所有必需的配置,在 context.xml:
<ResourceLink name="bean/redisson"
global="bean/redisson"
type="org.redisson.api.RedissonClient" />
<Manager className="org.redisson.tomcat.JndiRedissonSessionManager"
readMode="REDIS"
jndiName="bean/redisson" />
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
<Manager className="org.redisson.tomcat.RedissonSessionManager"
configPath="${catalina.base}/conf/redisson.yaml"
readMode="REDIS" updateMode="DEFAULT" broadcastSessionEvents="false"/>
server.xml的变化:
<Resource name="bean/redisson"
auth="Container"
factory="org.redisson.JndiRedissonFactory"
configPath="${catalina.base}/conf/redisson.yaml"
closeMethod="shutdown"/>
redisson.yaml 包含:
singleServerConfig:
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
password: null
subscriptionsPerConnection: 5
clientName: null
address: "redis://127.0.0.1:6379"
subscriptionConnectionMinimumIdleSize: 1
subscriptionConnectionPoolSize: 50
connectionMinimumIdleSize: 24
connectionPoolSize: 64
database: 0
dnsMonitoringInterval: 5000
threads: 16
nettyThreads: 32
codec: !<org.redisson.codec.FstCodec> {}
transportMode: "NIO"
然后我将 redisson-all-3.11.6.jar 和 redisson-tomcat-9-3.11.6.jar 放在 Tomcat lib 文件夹中
redis 与 Tomcat 兼容性的问题吗?我错过了什么 ? 提前感谢您的帮助。
错误说的很清楚:
Caused by: java.lang.NoSuchMethodError: org.springframework.data.redis.connection.RedisConnection.getConfig(Ljava/lang/String;)Ljava/util/List;
请阅读 java.lang.NoSuchMethodError
这基本上是在告诉您在 运行 时找不到此方法。您必须执行以下步骤:
- 找出哪个库(jar)文件有这个方法,验证方法签名。
- 确保该库是您的 class 路径的一部分,即应该是您的 maven 或 gradle 文件的一部分。
- 检查是否存在冲突。如果您有任何其他 jar 文件也提供相同的 class,即 RedisConnection,那么您必须删除那个多余的 jar 文件。
基本上,错误的出现是因为程序正在调用 RedisConnection class 但无法在 class 中找到 getConfig 方法(相同的签名)。 我的猜测是您有两个相互冲突的库并且调用了错误的库。您必须删除或清理依赖项。
经过长时间的检查,发现 Redis 库和 Tomcat 服务器内部库之间存在冲突
最后,我决定将会话存储切换到 JDBC 并完全丢弃 Redis :
在application.properties文件中
- 设置应用属性spring.session.store-type=jdbc
- 设置应用属性spring.session.jdbc.table-name=SPRING_SESSION
- 设置应用程序 属性 spring.jpa.hibernate.ddl-auto=none(直接从 sql 脚本创建模式)
在schema.sql文件中
添加两个管理会话的表:
CREATE TABLE IF NOT EXISTS SPRING_SESSION (
PRIMARY_ID CHAR(36) NOT NULL,
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
EXPIRY_TIME BIGINT NOT NULL,
PRINCIPAL_NAME VARCHAR(100),
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
);
CREATE UNIQUE INDEX IF NOT EXISTS SPRING_SESSION_IX1 ON MATFRONT.SPRING_SESSION (SESSION_ID);
CREATE INDEX IF NOT EXISTS SPRING_SESSION_IX2 ON MATFRONT.SPRING_SESSION (EXPIRY_TIME);
CREATE INDEX IF NOT EXISTS SPRING_SESSION_IX3 ON MATFRONT.SPRING_SESSION (PRINCIPAL_NAME);
CREATE TABLE IF NOT EXISTS SPRING_SESSION_ATTRIBUTES (
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES BLOB NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES MATFRONT.SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
);
多亏了它,我摆脱了仅用于存储会话数据的额外的整个服务器