【问题标题】:Timeouts are not correct for servlet in spring bootSpring Boot 中的 servlet 超时不正确
【发布时间】:2020-01-24 08:16:33
【问题描述】:

这是远程服务器属性:

server.servlet.session.timeout=3m

我的 local.properties

相同

我们也有这样的配置:

 http
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .invalidSessionUrl("/login?invalidSession")//dokunma
                .maximumSessions(1)//
                .maxSessionsPreventsLogin(true)//
                .expiredUrl("/login?expired")
                .sessionRegistry(sessionRegistry());

我们有一个这样的类:

@Bean // Http Listener
public HttpSessionListener httpSessionListener() {
    return new HttpSessionListener() {
        @Override
        public void sessionCreated(HttpSessionEvent se) {

            HttpSession session = se.getSession();

            if (session != null) {
              LoggerService.logger.info("sessionCreated sessionid: {}, setMaxInactiveInterval: {}, ipaddress: {}",
                        session.getId(), session.getMaxInactiveInterval(), SecurityUtil.getIpAddress());

我这样做是为了查看内部时间。

但是在服务器上,我看到了这个日志:

sessionCreated sessionid: 342E6139B2FE108D26537C9D684FBFF3, setMaxInactiveInterval: 1800, ipaddress: null

一定是180,而不是1800。为什么会倍增?

我们没有任何其他代码来设置它。例如:

request.getSession(false).setMaxInactiveInterval(11);

我们没有这个。但是如果我找不到任何解决方案,我会使用它。

例如,对于远程,我改为:

server.servlet.session.timeout=44s

但我看到的是:

sessionCreated sessionid: 7C3573FE7B5FB6C8939DF8BF60B1B550, setMaxInactiveInterval: 1800, ipaddress: null

Tomcat9 正在这样做吗?

在我的本地,我使用该属性进行测试。

所以

server.servlet.session.timeout=44s

用于我本地的本地和远程服务器数据库配置。

但这一次:

 sessionCreated sessionid: 747E6BF3DCD061DFF306325FE4FD76B6, getMaxInactiveInterval: 60, ipaddress: 0:0:0:0:0:0:0:1
747E6BF3DCD061DFF306325FE4FD76B6    0:0:0:0:0:0:0:1 Session Created

我做错了什么?

对于上次测试,我将此添加到本地成功处理程序中,但具有远程属性:

  LoggerService.logger.info("onAuthenticationSuccess sessionid: {}, getMaxInactiveInterval: {}, ipaddress: {}",
                    session.getId(), session.getMaxInactiveInterval(), SecurityUtil.getIpAddress());

            request.getSession(false).setMaxInactiveInterval(55);

            LoggerService.logger.info("onAuthenticationSuccess sessionid: {}, getMaxInactiveInterval: {}, ipaddress: {}",
                    session.getId(), session.getMaxInactiveInterval(), SecurityUtil.getIpAddress());

如果我输入我的用户名密码,我可以看到:

   : onAuthenticationSuccess sessionid: F796EA6C54D8BCA239A36E02C4A7A030, getMaxInactiveInterval: 60, ipaddress: 0:0:0:0:0:0:0:1

  : onAuthenticationSuccess sessionid: F796EA6C54D8BCA239A36E02C4A7A030, getMaxInactiveInterval: 55, ipaddress: 0:0:0:0:0:0:0:1

我也这样做了:

@Bean // Http Listener
public HttpSessionListener httpSessionListener() {
    return new HttpSessionListener() {
        @Override
        public void sessionCreated(HttpSessionEvent se) {

            HttpSession session = se.getSession();

            if (session != null) {
              LoggerService.logger.info("sessionCreated sessionid: {}, setMaxInactiveInterval: {}, ipaddress: {}",
                        session.getId(), session.getMaxInactiveInterval(), SecurityUtil.getIpAddress());

                session.setMaxInactiveInterval(55);

              LoggerService.logger.info("sessionCreated sessionid: {}, setMaxInactiveInterval: {}, ipaddress: {}",
                        session.getId(), session.getMaxInactiveInterval(), SecurityUtil.getIpAddress());

还是一样:

sessionCreated sessionid: FFA7DC9A6558951F1CB790AD9D804F88, getMaxInactiveInterval: 60, ipaddress: null
sessionCreated sessionid: FFA7DC9A6558951F1CB790AD9D804F88, getMaxInactiveInterval: 55, ipaddress: null
FFA7DC9A6558951F1CB790AD9D804F88    0:0:0:0:0:0:0:1 Session Created

对于远程,我用相同的代码进行了测试,它也可以工作,但我不想以编程方式设置

sessionCreated before sessionid: 38EC29F7C9C45B34D1FDF05B1F90DC3A, getMaxInactiveInterval: 1800, ipaddress: 192.ss

sessionCreated after sessionid: 38EC29F7C9C45B34D1FDF05B1F90DC3A, getMaxInactiveInterval: 180, ipaddress: 192.ss

所以,有两个问题:

  1. 为什么 application-remote-properties 超时值不适用于本地?
  2. 为什么远程超时乘以10(属性有3m但日志显示1800s)

【问题讨论】:

  • 您无法更改远程服务器的会话超时,server.* 属性仅适用于本地嵌入式服务器。此外,tomcat 上的间隔不能少于一分钟,因为 Tomcat 每分钟运行一次会话失效线程,因此将会话超时设置为少于一分钟是没有意义的。此外,您的安全配置不会影响会话超时,因此将其添加到问题中不会添加任何其他信息。
  • @M.Deinum 但在远程,它正在与安全配置中的编程一起工作?
  • 是的,这将起作用,因为您随后为每个单独的会话设置它,而不是为服务器全局设置。这不是配置,它只是在会话创建时执行的代码的一部分,这与全局配置服务器不同!。
  • on tomcat as the session invalidation thread that Tomcat has runs once every minute 在tomcat上,它不会每隔一分钟就失效。我必须等待“1800”秒。 '这与全局配置服务器不同!'那我该怎么办?为什么弹簧不能做到这一点?也许 docker 而不是 tomcat 可以更好地工作?
  • 因为Spring无法控制外部配置的服务器!会很安静,一个惊喜,你的运营团队设置了一个服务器,你部署了你的应用程序,突然那里精确配置的服务器突然将所有会话超时切换到 3 分钟。仅仅因为您决定这样做(这会影响部署在该服务器上的所有应用程序)。是的,您必须等待 1800 秒,但是检查会话是否超时的线程每分钟运行一次!。因此,将其设置为更少(就像您对 44s 样本所做的那样)几乎没有用,这就是为什么 spring boot 会在几分钟内切换的原因。

标签: spring-boot timeout embedded-tomcat


【解决方案1】:

server.* 属性用于控制 Spring Boot 使用的嵌入式容器。 Spring Boot 将使用 ServletWebServerFactory 实例之一创建 servlet 容器的实例。这些类使用server.* 属性来配置受控的servlet 容器(tomcat、jetty 等)。

但是,当您将应用程序作为 war 文件部署到 Tomcat 实例时,server.* 属性不适用。它们不适用,因为预配置的 servlet 容器可用(因为它是远程运行的服务)。因此,部署到远程 Tomcat 将使server.* 属性无用。

关于会话超时以分钟为单位。 Spring Boot 会convert the session.servlet.session.timeout property to minutes,所以44s55s 会自动转换为1 分钟。将其设置为不到一分钟也没有多大意义,因为 Tomcat 每分钟运行一个线程会使会话无效。

【讨论】:

  • 但是,服务器可以从application-server.properties读取数据库url、密码等?
  • 这与配置嵌入式服务器有什么关系?您可以为您的应用程序配置数据源,这与使用嵌入式或远程服务器无关。
  • 因为你说the server.* properties don't apply.。所以它适用吗?
  • 不,它没有。 server. 命名空间中的属性仅适用于嵌入式容器。这些将不会配置远程服务器。配置数据源与配置嵌入式 servlet 容器无关。您甚至可以在独立的 Spring 应用程序中执行此操作。因此,所有其他属性都适用于配置您的 spring 应用程序,但 不是 server.* 属性,因为 Spring 不控制远程服务器。
  • 我从一开始就是这么说的。
猜你喜欢
  • 2016-09-13
  • 2021-02-21
  • 2018-02-23
  • 1970-01-01
  • 1970-01-01
  • 2019-09-04
  • 1970-01-01
  • 2020-11-14
  • 1970-01-01
相关资源
最近更新 更多