在使用spring session解决分布式session一致性问题的时候,遇到一个问题,完整报错如下
java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration.taskScheduler
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:64) ~[spring-boot-autoconfigure-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:181) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:141) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:117) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:327) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:232) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:705) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:531) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at com.xiaxin.AppSession.main(AppSession.java:26) [classes/:na]
Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.springframework.boot.autoconfigure.session.SessionAutoConfiguration$ServletSessionConfiguration] from ClassLoader [sun.misc.Launcher$AppClassLoader@18b4aac2]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:507) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:404) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:389) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:447) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660) ~[na:1.8.0_102]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:738) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:679) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:647) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1518) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1023) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.addBeanTypeForNonAliasDefinition(BeanTypeRegistry.java:195) ~[spring-boot-autoconfigure-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.addBeanTypeForNonAliasDefinition(BeanTypeRegistry.java:159) ~[spring-boot-autoconfigure-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.addBeanType(BeanTypeRegistry.java:152) ~[spring-boot-autoconfigure-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.updateTypesIfNecessary(BeanTypeRegistry.java:140) ~[spring-boot-autoconfigure-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at java.util.Iterator.forEachRemaining(Iterator.java:116) ~[na:1.8.0_102]
at org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.updateTypesIfNecessary(BeanTypeRegistry.java:135) ~[spring-boot-autoconfigure-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.getNamesForType(BeanTypeRegistry.java:97) ~[spring-boot-autoconfigure-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition.collectBeanNamesForType(OnBeanCondition.java:298) ~[spring-boot-autoconfigure-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:289) ~[spring-boot-autoconfigure-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:278) ~[spring-boot-autoconfigure-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchingBeans(OnBeanCondition.java:189) ~[spring-boot-autoconfigure-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:160) ~[spring-boot-autoconfigure-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-2.1.5.RELEASE.jar:2.1.5.RELEASE]
... 17 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/springframework/security/web/authentication/RememberMeServices
at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_102]
at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_102]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_102]
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) ~[na:1.8.0_102]
at java.net.URLClassLoader.access$100(URLClassLoader.java:73) ~[na:1.8.0_102]
at java.net.URLClassLoader$1.run(URLClassLoader.java:368) ~[na:1.8.0_102]
at java.net.URLClassLoader$1.run(URLClassLoader.java:362) ~[na:1.8.0_102]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_102]
at java.net.URLClassLoader.findClass(URLClassLoader.java:361) ~[na:1.8.0_102]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_102]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_102]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_102]
at java.lang.Class.getDeclaredMethods0(Native Method) ~[na:1.8.0_102]
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) ~[na:1.8.0_102]
at java.lang.Class.getDeclaredMethods(Class.java:1975) ~[na:1.8.0_102]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:489) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]
... 39 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.security.web.authentication.RememberMeServices
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_102]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_102]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_102]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_102]
... 55 common frames omitted
2020-04-06 16:39:07.364 WARN 69364 --- [ main] o.s.boot.SpringApplication : Unable to close ApplicationContext
java.lang.IllegalStateException: Failed to introspect Class [org.springframework.boot.autoconfigure.session.SessionAutoConfiguration$ServletSessionConfiguration] from ClassLoader [sun.misc.Launcher$AppClassLoader@18b4aac2]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:507) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:404) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:389) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:447) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660) ~[na:1.8.0_102]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:738) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:679) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:647) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1518) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:509) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:479) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:600) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:592) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1226) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.boot.SpringApplication.getExitCodeFromMappedException(SpringApplication.java:905) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.getExitCodeFromException(SpringApplication.java:891) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.handleExitCode(SpringApplication.java:877) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:826) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at com.xiaxin.AppSession.main(AppSession.java:26) [classes/:na]
Caused by: java.lang.NoClassDefFoundError: org/springframework/security/web/authentication/RememberMeServices
at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_102]
at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_102]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_102]
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) ~[na:1.8.0_102]
at java.net.URLClassLoader.access$100(URLClassLoader.java:73) ~[na:1.8.0_102]
at java.net.URLClassLoader$1.run(URLClassLoader.java:368) ~[na:1.8.0_102]
at java.net.URLClassLoader$1.run(URLClassLoader.java:362) ~[na:1.8.0_102]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_102]
at java.net.URLClassLoader.findClass(URLClassLoader.java:361) ~[na:1.8.0_102]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_102]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_102]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_102]
at java.lang.Class.getDeclaredMethods0(Native Method) ~[na:1.8.0_102]
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) ~[na:1.8.0_102]
at java.lang.Class.getDeclaredMethods(Class.java:1975) ~[na:1.8.0_102]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:489) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]
... 21 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.security.web.authentication.RememberMeServices
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_102]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_102]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_102]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_102]
... 37 common frames omitted
Process finished with exit code 1
先说一下问题出在哪里:
springboot 2.1.5版本存在问题,根据如上报错可以推断缺少类java.lang.ClassNotFoundException: org.springframework.security.web.authentication.RememberMeServices
解决:
更换springboot的版本,我后来换成2.2.2.RELEASE版本问题得到解决,经过验证2.0.0.RELEASE版本也是没有问题问题的
或者还有别的解决方案,我不知道,也不想深究,时间宝贵,看看其他的技术点
org.springframework.boot
spring-boot-starter-parent
2.2.2.RELEASE
org.springframework.session
spring-session-core
org.springframework.boot
spring-boot-starter-web
com.alibaba
fastjson
1.2.47
org.springframework.session
spring-session-data-redis
org.apache.commons
commons-pool2
yml 自定义配置
server:
port: 8080
redis:
hostname: 192.168.237.137
port: 6379
password: 361116
在添加了所需的依赖项之后,我们可以创建Spring配置。Spring配置负责创建servlet过滤器,该过滤器将HttpSession实现替换为Spring Session支持的实现。为此,添加以下Spring配置:
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class SessionConfig {
@Value("${redis.hostname:localhost}")
String hostName;
@Value("${redis.port:6379}")
int port;
@Value("${redis.password}")
String password;
@Bean
public LettuceConnectionFactory connectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(hostName, port);
redisStandaloneConfiguration.setPassword(password);
return new LettuceConnectionFactory(redisStandaloneConfiguration);
}
// jedis依赖
// @Bean
// public JedisConnectionFactory connectionFactory() {
// JedisConnectionFactory connection = new JedisConnectionFactory();
// connection.setPort(port);
// connection.setHostName(hostName);
// connection.setPassword(password);
// // connection.setDatabase(0);
// return connection;
// }
}
我们的Spring配置创建了一个名为springSessionRepositoryFilter的Spring Bean,它实现了Filter。springSessionRepositoryFilter bean负责将HttpSession替换为由Spring session支持的自定义实现。为了让过滤器发挥作用,Spring需要加载配置类。最后,我们需要确保Servlet容器(即Tomcat)对每个请求都使用springSessionRepositoryFilter。幸运的是,Spring Session提供了一个名为AbstractHttpSessionApplicationInitializer的实用工具类,可以简化这两个步骤。下面是一个示例
public class SessionInitializer extends AbstractHttpSessionApplicationInitializer {
public SessionInitializer() {
super(SessionConfig.class);
}
}
controller
@RestController
@SpringBootApplication
public class TestSessionController {
@Value("${server.port}")
private String serverPort;
@RequestMapping("/")
public String index() {
return serverPort;
}
// 创建session
@RequestMapping("/createSession")
public String createSession(HttpServletRequest request, String nameValue) {
HttpSession session = request.getSession();
session.setAttribute("name", nameValue);
return "success:" + serverPort;
}
// 获取session
@RequestMapping("/getSession")
public Object getSession(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session == null) {
return serverPort + ":" + "没有session";
}
return serverPort + ":" + session.getAttribute("name");
}
}
环境准备:
nginx配置集群
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
upstream backServer {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
server {
listen 80;
server_name www.xiaxin.com;
location / {
proxy_pass http://backServer;
index index.html index.htm;
}
}
}
没有解决分布式sessionb问题之前:
端口为8080的服务器 创建session nginx轮询到8081的服务器时 没有session信息
使用spring session:
创建session在8080服务器上
获取session:8080、8081服务器上都有了session信息、