当前位置:   article > 正文

奇怪的问题,再次启动jar包会导致bean对象失效?Unknown redis exception Cannot connect, Event executor group is terminated

cannot connect, event executor group is terminated.

大家好,我是烤鸭:

    踩坑实录。一个某次上线导致的问题,并没有改过什么代码,只是重新上了一次包,没上之前从来没出过这个问题。最开始日志的报错信息一直是 NoClassDefFoundError could not initialize class ,发现是 static 初始化 spring bean 失败,导致类没有加载成功。

1.  报错日志

  1. ex.ToString().org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class com.etc.common.utils.SequenceKit
  2. ex.Message,Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class com.etc.common.utils.SequenceKit
  3. ex.StackTrace,org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1006)
  4. ex.Source,java.lang.NoClassDefFoundError: Could not initialize class com.etc.common.utils.SequenceKit

2.  代码复现:

SequenceKit.java

  1. package com.xxx.common.utils;
  2. import java.util.concurrent.atomic.AtomicInteger;
  3. import org.checkerframework.common.value.qual.StaticallyExecutable;
  4. import org.joda.time.DateTime;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import org.springframework.data.redis.core.RedisTemplate;
  8. import com.fasterxml.jackson.core.Versioned;
  9. public class SequenceKit {
  10. private static final Logger logger = LoggerFactory.getLogger(SequenceKit.class);
  11. public static final String TYPE_INCR = "INCR:";
  12. public static final RedisTemplate redisTemplate = SpringContextUtil.getBean("redisTemplate", RedisTemplate.class);
  13. /**
  14. * 根据指定业务前缀生成自增 number
  15. * @return
  16. */
  17. public static String getBusinessSequenceDoc(String key) {
  18. String date = new DateTime().toString("yyyyMMddHHmmss");
  19. logger.info("redisTemplate{}"+redisTemplate);
  20. Long no = redisTemplate.opsForValue().increment(TYPE_INCR+key, 1);
  21. if(no == null ){
  22. logger.info("redis 连接失败{}"+TYPE_INCR+key);
  23. String uuid = UUIDUtil.generate();
  24. return key+ "-" + date + "-" + uuid;
  25. }
  26. return key+ "-" + date + "-" + String.format("%06d", no);
  27. }
  28. }
SpringContextUtil.java
  1. package com.xxx.common.utils;
  2. import org.springframework.beans.BeansException;
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.ApplicationContextAware;
  5. import org.springframework.stereotype.Component;
  6. /**
  7. *
  8. * @ClassName: SpringContextUtil
  9. * @Description: 静态获取Bean
  10. * @author gaogang
  11. * @date 2016年7月12日 下午4:21:26
  12. *
  13. */
  14. @Component
  15. public class SpringContextUtil implements ApplicationContextAware {
  16. /*
  17. * 当前IOC上下文环境
  18. */
  19. private static ApplicationContext applicationContext;
  20. /*
  21. * 设置当前上下文环境,此方法由spring自动装配 (non-Javadoc)
  22. *
  23. * @see
  24. * org.springframework.context.ApplicationContextAware#setApplicationContext
  25. * (org.springframework.context.ApplicationContext)
  26. */
  27. @Override
  28. public void setApplicationContext(ApplicationContext applicationContext)
  29. throws BeansException {
  30. SpringContextUtil.applicationContext = applicationContext;
  31. }
  32. public static ApplicationContext getApplicationContext() {
  33. return applicationContext;
  34. }
  35. /**
  36. *
  37. * @Description 从spring容器获取bean实例</br>
  38. * <font color='red'>注意,这里beanId是spring ioc中bean实例的名字,如果是注解扫描方式,没有特意指定名称,一般为类名,首字母小写(java遵从驼峰命名规则),如果有指定名称,则为指定的bean名称</font>
  39. * @param name lmk name,infact it's name in spring IOC
  40. * @return bean实例
  41. *
  42. * @author wjggwm
  43. * @data 2016年8月25日 下午2:22:16
  44. */
  45. public static Object getBean(String name) throws BeansException {
  46. return getApplicationContext().getBean(name);
  47. }
  48. /**
  49. *
  50. * @Description 从spring容器获取bean实例</br>
  51. * <font color='red'>注意,这里beanId是spring ioc中bean实例的名字,如果是注解扫描方式,没有特意指定名称,一般为类名,首字母小写(java遵从驼峰命名规则),如果有指定名称,则为指定的bean名称</font>
  52. * @param name lmk name,infact it's name in spring IOC
  53. * @param requiredType lmk class类型
  54. * @return bean实例
  55. * @throws BeansException
  56. *
  57. * @author wjggwm
  58. * @data 2017年1月5日 下午5:58:27
  59. */
  60. public static <T> T getBean(String name, Class<T> requiredType) throws BeansException {
  61. return getApplicationContext().getBean(name, requiredType);
  62. }
  63. public static <T> T getBean(Class<T> requiredType) {
  64. return applicationContext.getBean(requiredType);
  65. }
  66. }

3.  问题猜想

静态变量初始化在springbean之前,导致获取不到bean对象,报错。

其实有点想不通,测试环境和线上已经运行那么多天,如果是这个问题,早就应该曝光了。

静态变量的初始化是在调用的时候再赋值,也就是调用这个方法的 getBean的时候,项目早已经启动成功,不存在拿不到bean的情况。

4.  场景模拟

后来想模拟线上的场景,将静态变量 = 一个抛异常的方法,类似下面。确实爆错了,原因找到了,就是这个对象初始化失败。

为了避免这个问题,做了一下修改:

5.  根本原因分析

改完就不会报异常了么。如果场景一样的话,还是会报的。再贴一段同时报错信息的日志。是redis 相关的日志,好像有点意思,都是redis相关的。

  1. 2020-05-20 15:38:54.356 [TID:591.16551.15899603343206723] [DubboServerHandler-20.0.22.51:20886-thread-105] INFO [class:co
  2. m.etc.redis.RedisUtil | method:set | line:177] logInfo==> redis set 异常
  3. org.springframework.data.redis.RedisSystemException: Unknown redis exception; nested exception is java.lang.IllegalStateException: Cannot connect, Event executor group is termin
  4. ated.
  5. at org.springframework.data.redis.FallbackExceptionTranslationStrategy.getFallback(FallbackExceptionTranslationStrategy.java:53)
  6. at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:43)
  7. at org.springframework.data.redis.connection.lettuce.LettuceConnection.convertLettuceAccessException(LettuceConnection.java:257)
  8. at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.convertLettuceAccessException(LettuceStringCommands.java:718)
  9. at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.setEx(LettuceStringCommands.java:227)
  10. at org.springframework.data.redis.connection.DefaultedRedisConnection.setEx(DefaultedRedisConnection.java:252)
  11. at org.springframework.data.redis.core.DefaultValueOperations$4.potentiallyUsePsetEx(DefaultValueOperations.java:230)
  12. at org.springframework.data.redis.core.DefaultValueOperations$4.doInRedis(DefaultValueOperations.java:223)
  13. at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:224)
  14. at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:184)
  15. at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:95)
  16. at org.springframework.data.redis.core.DefaultValueOperations.set(DefaultValueOperations.java:218)
  17. at com.etc.redis.RedisUtil.set(RedisUtil.java:170)
  18. at com.etc.service.credit.EtcCreditApplyRelationServiceImpl.createNewApplyOrder(EtcCreditApplyRelationServiceImpl.java:1089)
  19. at com.etc.service.credit.EtcCreditApplyRelationServiceImpl$$FastClassBySpringCGLIB$$d7d53003.invoke(<generated>)
  20. at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
  21. at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
  22. at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
  23. at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
  24. at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
  25. at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
  26. at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
  27. at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
  28. at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
  29. at com.etc.service.credit.EtcCreditApplyRelationServiceImpl$$EnhancerBySpringCGLIB$$a874bba6.createNewApplyOrder(<generated>)
  30. at com.alibaba.dubbo.common.bytecode.Wrapper33.invokeMethod(Wrapper33.java)
  31. at com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:47)
  32. at com.alibaba.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:76)
  33. at com.alibaba.dubbo.config.invoker.DelegateProviderMetaDataInvoker.invoke(DelegateProviderMetaDataInvoker.java:52)
  34. at com.alibaba.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:56)
  35. at com.alibaba.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:62)
  36. at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)
  37. at com.alibaba.dubbo.monitor.support.MonitorFilter.invoke$original$Mxc753iz(MonitorFilter.java:75)
  38. at com.alibaba.dubbo.monitor.support.MonitorFilter.invoke$original$Mxc753iz$accessor$LYrs6xRu(MonitorFilter.java)
  39. at com.alibaba.dubbo.monitor.support.MonitorFilter$auxiliary$Xy5iiuam.call(Unknown Source)
  40. at org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter.intercept(InstMethodsInter.java:93)
  41. at com.alibaba.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java)
  42. at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)
  43. at com.alibaba.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:42)
  44. at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)
  45. at com.alibaba.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:78)
  46. at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)
  47. at com.alibaba.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:72)
  48. at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)
  49. at com.alibaba.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:131)
  50. at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)
  51. at com.alibaba.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:38)
  52. at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)
  53. at com.alibaba.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:38)
  54. at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)
  55. at com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:103)
  56. at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:96)
  57. at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:172)
  58. at com.alibaba.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:51)
  59. at com.alibaba.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:80)
  60. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
  61. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
  62. at java.lang.Thread.run(Thread.java:748)
  63. Caused by: java.lang.IllegalStateException: Cannot connect, Event executor group is terminated.
  64. at io.lettuce.core.AbstractRedisClient.initializeChannelAsync(AbstractRedisClient.java:254)
  65. at io.lettuce.core.cluster.RedisClusterClient.connectStatefulAsync(RedisClusterClient.java:658)
  66. at io.lettuce.core.cluster.RedisClusterClient.connectStateful(RedisClusterClient.java:635)
  67. at io.lettuce.core.cluster.RedisClusterClient.connectClusterImpl(RedisClusterClient.java:530)
  68. at io.lettuce.core.cluster.RedisClusterClient.connect(RedisClusterClient.java:339)
  69. at org.springframework.data.redis.connection.lettuce.ClusterConnectionProvider.getConnection(ClusterConnectionProvider.java:55)
  70. at org.springframework.data.redis.connection.lettuce.LettuceConnection.doGetAsyncDedicatedConnection(LettuceConnection.java:962)
  71. at org.springframework.data.redis.connection.lettuce.LettuceConnection.getDedicatedConnection(LettuceConnection.java:942)
  72. at org.springframework.data.redis.connection.lettuce.LettuceConnection.getConnection(LettuceConnection.java:903)
  73. at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.getConnection(LettuceStringCommands.java:714)
  74. at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.setEx(LettuceStringCommands.java:225)
  75. ... 53 common frames omitted

我们顺着报错类找到源码看一下。

  1. protected <K, V, T extends RedisChannelHandler<K, V>> ConnectionFuture<T> initializeChannelAsync(
  2. ConnectionBuilder connectionBuilder) {
  3. SocketAddress redisAddress = connectionBuilder.socketAddress();
  4. if (clientResources.eventExecutorGroup().isShuttingDown()) {
  5. throw new IllegalStateException("Cannot connect, Event executor group is terminated.");
  6. }
  7. //
  8. }

我们看一下  eventExecutorGroup 的说明。内部操作的线程池。

  1. /**
  2. * Returns the computation pool used for internal operations. Such tasks are periodic Redis Cluster and Redis Sentinel
  3. * topology updates and scheduling of connection reconnection by {@link io.lettuce.core.protocol.ConnectionWatchdog}.
  4. *
  5. * @return the computation pool used for internal operations
  6. */
  7. EventExecutorGroup eventExecutorGroup();

这个判断 就是线程池对应的group是不是关闭了。那我们就看一下哪个地方调用了shutdown方法。有点多,先看默认的Default哪个吧。

一路找下去:

DefaultClientResources.shutdown() ——> AbstractRedisClient.shutdownAsync() ——>LettuceConnectionFactory.destroy()

最终找到了 LettuceConnectionFactory 实现了 DisposableBean.destroy()

看下 DisposableBean 的说明:由要在销毁时释放资源的bean实现的接口。将在单个销毁对象时调用destroy方法。也支持在应用程序生命周期的驱动下,在关机时处理所有单例。

  1. /*
  2. * Copyright 2002-2018 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.beans.factory;
  17. /**
  18. * Interface to be implemented by beans that want to release resources on destruction.
  19. * A {@link BeanFactory} will invoke the destroy method on individual destruction of a
  20. * scoped bean. An {@link org.springframework.context.ApplicationContext} is supposed
  21. * to dispose all of its singletons on shutdown, driven by the application lifecycle.
  22. *
  23. * <p>A Spring-managed bean may also implement Java's {@link AutoCloseable} interface
  24. * for the same purpose. An alternative to implementing an interface is specifying a
  25. * custom destroy method, for example in an XML bean definition. For a list of all
  26. * bean lifecycle methods, see the {@link BeanFactory BeanFactory javadocs}.
  27. *
  28. * @author Juergen Hoeller
  29. * @since 12.08.2003
  30. * @see InitializingBean
  31. * @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName()
  32. * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons()
  33. * @see org.springframework.context.ConfigurableApplicationContext#close()
  34. */
  35. public interface DisposableBean {
  36. /**
  37. * Invoked by the containing {@code BeanFactory} on destruction of a bean.
  38. * @throws Exception in case of shutdown errors. Exceptions will get logged
  39. * but not rethrown to allow other beans to release their resources as well.
  40. */
  41. void destroy() throws Exception;
  42. }

这只是一种猜想,redisTemplate 这个 bean被销毁了(在项目shutdown的过程中)。

6.  再翻日志

再往前翻翻日志,发现启动了项目的时候,前一次的项目并没有停掉,导致新上线的启动失败。

这也怪我,运维说启动成功了,我看日志一直在刷,并没有意识到这个问题。

  1. 2020-05-20 15:36:34.443 [TID:N/A] [main-EventThread] INFO [class:org.apache.curator.framework.state.ConnectionStateManage
  2. r | method:postState | line:237] logInfo==> State change: CONNECTED
  3. 2020-05-20 15:36:53.004 [TID:N/A] [main] INFO [class:io.netty.util.internal.logging.Slf4JLogger | method:info | line:101]
  4. logInfo==> Starting without optional epoll library
  5. 2020-05-20 15:36:53.007 [TID:N/A] [main] INFO [class:io.netty.util.internal.logging.Slf4JLogger | method:info | line:101]
  6. logInfo==> Starting without optional kqueue library
  7. 2020-05-20 15:36:53.361 [TID:N/A] [main] INFO [class:com.etc.service.xxx.WeimobServiceImpl | method:refreshAccessToken
  8. | line:234] logInfo==> 启动刷新任务,开始执行时间:2020-05-20T16:39:16.724
  9. 2020-05-20 15:36:53.961 [TID:N/A] [main] INFO [class:com.etc.config.BeforeStartup | method:onApplicationEvent | line:33]
  10. logInfo==> onApplicationEvent!!!redisUtil=com.etc.redis.RedisUtil@4407b042
  11. 2020-05-20 15:36:54.910 [TID:N/A] [main] INFO [class:org.apache.juli.logging.DirectJDKLog | method:log | line:180]
  12. logInfo==> Starting ProtocolHandler ["http-nio-8096"]
  13. 2020-05-20 15:36:54.916 [TID:N/A] [main] ERROR [class:org.apache.juli.logging.DirectJDKLog | method:log | line:182]
  14. logInfo==> Failed to start connector [Connector[HTTP/1.1-8096]]
  15. org.apache.catalina.LifecycleException: Failed to start component [Connector[HTTP/1.1-8096]]
  16. at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)
  17. at org.apache.catalina.core.StandardService.addConnector(StandardService.java:225)
  18. at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.addPreviouslyRemovedConnectors(TomcatWebServer.java:256)
  19. at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.start(TomcatWebServer.java:198)
  20. at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.startWebServer(ServletWebServerApplicationContext.java:300)
  21. at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:162)
  22. at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553)
  23. at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
  24. at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780)
  25. at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)
  26. at org.springframework.boot.SpringApplication.run(SpringApplication.java:333)
  27. at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277)
  28. at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265)
  29. at com.etc.ApplyServiceApplication.main(ApplyServiceApplication.java:33)
  30. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  31. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  32. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  33. at java.lang.reflect.Method.invoke(Method.java:498)
  34. at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
  35. at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
  36. at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
  37. at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
  38. Caused by: org.apache.catalina.LifecycleException: Protocol handler start failed
  39. at org.apache.catalina.connector.Connector.startInternal(Connector.java:1020)
  40. at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
  41. ... 21 common frames omitted
  42. Caused by: java.net.BindException: Address already in use
  43. at sun.nio.ch.Net.bind0(Native Method)
  44. at sun.nio.ch.Net.bind(Net.java:433)
  45. at sun.nio.ch.Net.bind(Net.java:425)
  46. at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
  47. at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
  48. at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:219)
  49. at org.apache.tomcat.util.net.AbstractEndpoint.start(AbstractEndpoint.java:1151)
  50. at org.apache.coyote.AbstractProtocol.start(AbstractProtocol.java:591)
  51. at org.apache.catalina.connector.Connector.startInternal(Connector.java:1018)
  52. ... 22 common frames omitted
  53. 2020-05-20 15:36:54.921 [TID:N/A] [main] INFO [class:org.apache.juli.logging.DirectJDKLog | method:log | line:180]
  54. logInfo==> Pausing ProtocolHandler ["http-nio-8096"]
  55. 2020-05-20 15:36:54.922 [TID:N/A] [main] INFO [class:org.apache.juli.logging.DirectJDKLog | method:log | line:180]
  56. logInfo==> Stopping service [Tomcat]
  57. 2020-05-20 15:36:54.961 [TID:N/A] [main] INFO [class:org.apache.juli.logging.DirectJDKLog | method:log | line:180]
  58. logInfo==> The stop() method was called on component [StandardServer[-1]] after stop() had already been called. The second call will be ignored.
  59. 2020-05-20 15:36:54.962 [TID:N/A] [main] INFO [class:org.apache.juli.logging.DirectJDKLog | method:log | line:180]
  60. logInfo==> Stopping ProtocolHandler ["http-nio-8096"]
  61. 2020-05-20 15:36:54.962 [TID:N/A] [main] INFO [class:org.apache.juli.logging.DirectJDKLog | method:log | line:180]
  62. logInfo==> Destroying ProtocolHandler ["http-nio-8096"]

这些都是小问题,但是注意到日志里多了一行,有点麻烦的。停止方法被已经被调用了,这次就忽略了。

The stop() method was called on component [StandardServer[-1]] after stop() had already been called. The second call will be ignored。

是运维的停止脚本(kill pid) 导致触发了第一次的stop方法么。如果这样就说的通了,stop的时候,导致调用了 shutdown ,将 redisTemplate 从 工厂移除,从而静态初始化失败。这个也有一个问题,就是为什么 继承 DisposableBean 那么多类,怎么就单独移除了一个 RedistTemplate。

只能强行解释一波了,项目由于某些原因没有停下来(可能是有在执行任务的线程),但是部分类已经触发了 destory 方法,从而导致部分连接池、bean对象失效等问题。

7.  解决方案

运维操作的时候,最好盯着日志,是不是真的停止和启动了。

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号