Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring引导嵌入式tomcat应用程序会话不会失效_Spring_Session_Tomcat_Spring Boot - Fatal编程技术网

Spring引导嵌入式tomcat应用程序会话不会失效

Spring引导嵌入式tomcat应用程序会话不会失效,spring,session,tomcat,spring-boot,Spring,Session,Tomcat,Spring Boot,最近,我们将应用程序从运行在tomcat中的web应用程序移植到使用嵌入式tomcat的spring boot应用程序 在应用程序运行几天后,内存和cpu使用率达到100%。 在堆转储分析中,有一堆http会话对象没有被销毁 我可以在调试中看到使用配置的超时值创建的会话,比如说,5分钟。但在此之后,不会触发失效。只有在超时后我再次请求时,才会调用它 我将此行为与tomcat中运行的应用程序进行了比较,我可以看到ContainerBackgroundProcessor线程[StandardMana

最近,我们将应用程序从运行在tomcat中的web应用程序移植到使用嵌入式tomcat的spring boot应用程序

在应用程序运行几天后,内存和cpu使用率达到100%。 在堆转储分析中,有一堆http会话对象没有被销毁

我可以在调试中看到使用配置的超时值创建的会话,比如说,5分钟。但在此之后,不会触发失效。只有在超时后我再次请求时,才会调用它

我将此行为与tomcat中运行的应用程序进行了比较,我可以看到ContainerBackgroundProcessor线程[StandardManager(ManagerBase).processExpires()]触发了会话失效

我在spring boot应用程序中没有看到这个背景线程

根据一些建议,采取了哪些措施:

  • application.properties中设置的会话超时: server.session.timout=300 或者在EmbeddedServletContainerCustomizer@Bean中: 工厂设置会话超时(5,时间单位:分钟)

  • 添加了HttpSessionEventPublisher和SessionRegistry bean

  • 没有任何帮助,会话在到期时不会失效


    有什么线索吗

    经过更多的调试和文档阅读,这就是原因和解决方案:

    在tomcat中,有一个代表根容器生成的线程,它定期扫描容器及其子容器会话池并使它们无效。每个容器/子容器可以配置为具有自己的后台处理器来执行该任务,或者依赖于其主机的后台处理器。 这由context.backgroundProcessorDelay控制

    背景处理程序延迟-
    此值表示在此引擎上调用backgroundProcess方法与其子容器(包括所有主机和上下文)之间的延迟(秒)。如果子容器的延迟值不是负值(这意味着它们正在使用自己的处理线程),则不会调用子容器。将此设置为正值将导致生成线程。等待指定的时间后,线程将调用此引擎及其所有子容器上的backgroundProcess方法。如果未指定,此属性的默认值为10,表示10秒的延迟

    内置tomcat的spring引导应用程序 TomcatEmbeddedServletContainerFactory.configureEngine()为StandardEngine[Tomcat]设置此属性-1,据我所知,StandardEngine[Tomcat]是Tomcat层次结构中的根容器。 包括web app在内的所有子容器也将此参数设置为-1。 这意味着他们都依赖其他人来完成这项工作。 春天不做,没人做

    我的解决方案是为应用程序上下文设置此参数:

    @Bean
    public EmbeddedServletContainerCustomizer servletContainerCustomizer() {
        return new EmbeddedServletContainerCustomizer() {
    
            @Override
            public void customize(ConfigurableEmbeddedServletContainer container) {
                if (container instanceof TomcatEmbeddedServletContainerFactory) {
                    TomcatEmbeddedServletContainerFactory factory = (TomcatEmbeddedServletContainerFactory) container;
                    TomcatContextCustomizer contextCustomizer = new TomcatContextCustomizer() {
                        
                        @Override
                        public void customize(Context context) {
                            context.setBackgroundProcessorDelay(10);
                        }
                    };
                    List<TomcatContextCustomizer> contextCustomizers = new ArrayList<TomcatContextCustomizer>();
                    contextCustomizers.add(contextCustomizer);
                    factory.setTomcatContextCustomizers(contextCustomizers);
                    customizeTomcat(factory);
                }
            }
    
    @Bean
    公共嵌入式servletContainerCustomizer servletContainerCustomizer(){
    返回新的EmbeddedServletContainerCustomizer(){
    @凌驾
    public void自定义(ConfigurableMbeddedServletContainer){
    if(TomcatEmbeddedServletContainerFactory的容器实例){
    TomcatEmbeddedServletContainerFactory=(TomcatEmbeddedServletContainerFactory)容器;
    TomcatContextCustomizer contextCustomizer=新的TomcatContextCustomizer(){
    @凌驾
    公共void自定义(上下文){
    背景。挫折背景过程延迟(10);
    }
    };
    List contextCustomizers=new ArrayList();
    添加(contextCustomizer);
    setTomcatContextCustomizers(contextCustomizers);
    定制MCAT(工厂);
    }
    }
    
    在最新版本的SpringBoot(2.1)中,backgroundProcessorDelay的默认值似乎是10。