Heim  >  Artikel  >  Java  >  Detaillierte Erläuterung der Ursachen des Sitzungszeitüberschreitungsproblems in SpringBoot

Detaillierte Erläuterung der Ursachen des Sitzungszeitüberschreitungsproblems in SpringBoot

巴扎黑
巴扎黑Original
2018-05-10 13:49:595525Durchsuche

In diesem Artikel wird hauptsächlich die detaillierte Erklärung des Sitzungs-Timeout-Prinzips in SpringBoot vorgestellt. Der Herausgeber findet es recht gut, daher werde ich es jetzt mit Ihnen teilen und als Referenz verwenden. Folgen wir dem Editor, um einen Blick darauf zu werfen.

1: Vorwort:

Wenn nach der Anmeldung kein Vorgang erfolgt Zahlungshintergrund für einen bestimmten Zeitraum, Sie müssen sich immer erneut anmelden, bevor Sie auf die Seite zugreifen können. Der Grund für dieses Problem ist, dass die Sitzung abgelaufen ist. Nach dem Debuggen des Codes wurde festgestellt, dass die Sitzung abgelaufen ist ist 1800. Das heißt, wenn innerhalb von 1800 Sekunden keine Operation erfolgt, tritt eine Zeitüberschreitung der Sitzung auf. Wie wird dieses Timeout eingestellt? Wie kann man dann dieses Timeout zurücksetzen? Wie stellt das System fest, wann die Sitzung abgelaufen ist? Als nächstes werden wir sie einzeln beantworten.

2: Wie wird das Systemsitzungs-Timeout standardmäßig eingestellt?

Erklärung: Die Methode zum Abrufen des Sitzungszeitlimits ist „request.getSession().getMaxInactiveInterval()“, aber der Parameter zum Festlegen des Zeitlimits in Tomcat ist „sessionTimeout“ , dann Wie sind sie verbunden?

Schritt eins: Laden Sie den sessionTimeout-Parameter.

1. Die Initialisierung des Projektvorgangs lädt die Klasse „org.springframework.boot.autoconfigure.web.ServerProperties“ über die Annotation „@ConfigurationProperties“.

//springBoot中默认的配置文件为"application.yml"或者"application.perties"文件,也就是说server是其中的一个配置参数。
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties
  implements EmbeddedServletContainerCustomizer, EnvironmentAware, Ordered {
//代码
}

2. Die „ServerProperties“ in der obigen Klasse erben von der Schnittstelle „EmbeddedServletContainerCustomizer“. Schreiben Sie die Methode „Customize“ neu und drücken Sie sie dann nach oben, um die Klasse „AbstractConfigurableEmbeddedServletContainer“ zu finden.

@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
 //多个参数判断,如果在application中没配置的情况下都是null
 if (getPort() != null) {
  container.setPort(getPort());
 }
 ...//n多个参数判断,
 //以下的代码就是重点,因为是tomcat容器,所以以下条件为“真”,经过一系列的查找父类或者实现接口即可找到抽象类“AbstractConfigurableEmbeddedServletContainer”
 //public class TomcatEmbeddedServletContainerFactory extends AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware
 //public abstract class AbstractEmbeddedServletContainerFactory extends AbstractConfigurableEmbeddedServletContainer implements EmbeddedServletContainerFactory 
 if (container instanceof TomcatEmbeddedServletContainerFactory) {
  getTomcat().customizeTomcat(this,
   (TomcatEmbeddedServletContainerFactory) container);
 }
//以上代码执行完成之后,实际上已经有对应的session所有的默认参数,之后通过下面方法,将所有参数放入对应的容器中。第3、4步就是设置过程
 container.addInitializers(new SessionConfiguringInitializer(this.session));
}

3. Die relevanten Einstellungen von „timeout“ finden Sie endlich in der Klasse „AbstractConfigurableEmbeddedServletContainer“

//重要代码
//45行
private static final int DEFAULT_SESSION_TIMEOUT = (int) TimeUnit.MINUTES
  .toSeconds(30);
//66行
private int sessionTimeout = DEFAULT_SESSION_TIMEOUT;
 
@Override
public void setSessionTimeout(int sessionTimeout) {
 this.sessionTimeout = sessionTimeout;
}
//171-188行
@Override
public void setSessionTimeout(int sessionTimeout, TimeUnit timeUnit) {
 Assert.notNull(timeUnit, "TimeUnit must not be null");
 this.sessionTimeout = (int) timeUnit.toSeconds(sessionTimeout);
}

/**
 * Return the session timeout in seconds.
 * @return the timeout in seconds
 */
public int getSessionTimeout() {
 return this.sessionTimeout;
}

4. Führen Sie Schritt 2 von „Container.addInitializers(new SessionConfiguringInitializer) aus (this.session)) „Lädt alle Konfigurationsparameter.

public static class Session {

 /**
 * Session timeout in seconds.
 */
 private Integer timeout;

 public Integer getTimeout() {
  return this.timeout;
 }
//将session超时时间设置进来
 public void setTimeout(Integer sessionTimeout) {
  this.timeout = sessionTimeout;
 }

Schritt 2: Weisen Sie dem Parameter „MaxInactiveInterval“ den oben genannten Timeout-Zeitraum zu.

Hinweis: Da die oben genannten von Tomcat benötigten Parameter geladen wurden, wird Tomcat als Nächstes ausgeführt. Ich werde hier nicht auf Details eingehen und direkt zur Beschreibung der Tomcat-Start- und Ladeparameter übergehen. Der Methodenaufrufprozess in der Klasse „TomcatEmbeddedServletContainerFactory“ ist wie folgt:

getEmbeddedServletContainer--》prepareContext--》configureContext--》configureSession--》getSessionTimeoutInMinutes.

1. Rufen Sie configureSession auf, um die Sitzungskonfigurationsparameter von Tomcat festzulegen

//以下代码
private void configureSession(Context context) {
 long sessionTimeout = getSessionTimeoutInMinutes();
 context.setSessionTimeout((int) sessionTimeout);
 Manager manager = context.getManager();
 if (manager == null) {
  manager = new StandardManager();
  //此处即为设置相应的参数的位置。之后会调用StandardContext类的setManger(Manager)方法,在setManger中会调用"manager.setContext(this)"
  context.setManager(manager);
 }
}
//计算超时时间为分钟(注意:此处会将之前的1800秒,转换为30分钟)。可以看出最终的时间结果是个整数的分钟类型,也就是说如果设置的超时时间(单位为秒)不是60的倍数,也会最终转换为60的倍数,并且最小超时时间设置的是60秒。
private long getSessionTimeoutInMinutes() {
 long sessionTimeout = getSessionTimeout();
 if (sessionTimeout > 0) {
  sessionTimeout = Math.max(TimeUnit.SECONDS.toMinutes(sessionTimeout), 1L);
 }
 return sessionTimeout;
}

2. Weisen Sie schließlich SessionTimeout zu MaxInactiveInterval zu. Endlich ist die Einstellung des Sitzungszeitlimits abgeschlossen.

//以下代码
@Override
public void setContext(Context context) {
 //省略其余设置代码,直接重新设置Session超时时间,此时又将上面的分钟单位转为秒。此时终于给Sesseion设置了默认超时时间。
 if (this.context != null) {
  setMaxInactiveInterval(this.context.getSessionTimeout() * 60);
  this.context.addPropertyChangeListener(this);
 }
}

3: Was passiert, wenn das Timeout angepasst wird?

Tatsächlich ist aus dem obigen Prozess nicht schwer zu erkennen, dass Sie nur die entsprechenden Sitzungsparameter in „org.springframework.boot.autoconfigure“ finden müssen. web.ServerProperties“-Klasse. Initialisieren Sie sie und lassen Sie sie laden, um die Einstellung abzuschließen.

/**
 * Get the session timeout.
 * @return the session timeout
 * @deprecated since 1.3.0 in favor of {@code session.timeout}.
 */
@Deprecated
@DeprecatedConfigurationProperty(replacement = "server.session.timeout")
public Integer getSessionTimeout() {
 return this.session.getTimeout();
}

Konfigurieren Sie also einfach „server.session.timeout“ in der Anwendung. Der Parametertyp ist ein langer Typ und die Einheit ist „Sekunden“.

4: Wie bestimmt das laufende Programm das Sitzungs-Timeout?

Es ist eigentlich ganz einfach: Sie müssen nur die Zeit derselben Sessionequest-Anfrage mit der vorherigen Anfragezeit vergleichen und feststellen, dass der Unterschied zwischen den beiden Werten beträgt größer als MaxInactiveInterval Der Wert ist ausreichend.

//判断是否超时
@Override
public boolean isValid() {
 //省略多个条件判断
 if (maxInactiveInterval > 0) {
  //判断此session空闲时间是否比maxInactiveInterval大,如果大的情况下,session就超时
  int timeIdle = (int) (getIdleTimeInternal() / 1000L);
  if (timeIdle >= maxInactiveInterval) {
   expire(true);
  }
 }
 return this.isValid;
}
//将上次访问时间和当前时间比较,拿到空闲时间值
@Override
public long getIdleTimeInternal() {
 long timeNow = System.currentTimeMillis();
 long timeIdle;
 if (LAST_ACCESS_AT_START) {
  timeIdle = timeNow - lastAccessedTime;
 } else {
  timeIdle = timeNow - thisAccessedTime;
 }
 return timeIdle;
}

Erklärung:

Um eine längere Sitzungszeitüberschreitung sicherzustellen, können Sie den Parameter „server.session.timeout“ in der Anwendungskonfigurationsdatei konfigurieren Die Einheit ist „Sekunden“. Wenn der Parameter kein ganzzahliges Vielfaches von 60 ist, wird er in ein ganzzahliges Vielfaches von 60 konvertiert (siehe 2: So stellen Sie das System-Timeout und den Algorithmus in Schritt 2 auf „1“ ein). Wenn sie weniger als eine Minute beträgt, wird sie in 60 Sekunden umgerechnet.

Erweiterung:

Tatsächlich können Sie die Anpassungsmethode von EmbeddedServletContainerCustomizer für die Zuweisung auch direkt überschreiben.

 @Bean
 public EmbeddedServletContainerCustomizer containerCustomizer(){
  return new EmbeddedServletContainerCustomizer() {
   @Override
   public void customize(ConfigurableEmbeddedServletContainer container) {
     container.setSessionTimeout(600);//单位为S
   }
  };
 }

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Ursachen des Sitzungszeitüberschreitungsproblems in SpringBoot. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn