管理器组件

目录

简介

Manager 元素表示将用于创建和维护 HTTP 会话(根据关联 Web 应用程序的请求)的会话管理器

Manager 元素可以嵌套在 Context 组件中。如果未包含,将自动创建默认的 Manager 配置,这足以满足大多数要求,——有关此配置的详细信息,请参阅下文的标准管理器实现

属性

通用属性

Manager 的所有实现都支持以下属性

属性 说明
className

要使用的实现的 Java 类名。此类必须实现 org.apache.catalina.Manager 接口。如果未指定,将使用标准值(定义如下)。

maxActiveSessions

此 Manager 将创建的最大活动会话数,或 -1(默认值)表示无限制。

达到限制时,任何创建新会话的尝试(例如使用 HttpServletRequest.getSession() 调用)都将失败,并出现 IllegalStateException

notifyAttributeListenerOnUnchangedValue

如果将属性添加到会话中,并且该属性已在会话中以相同名称存在,那么任何 HttpSessionAttributeListener 都将收到通知,告知该属性已被替换。如果未指定,将使用默认值 true

notifyBindingListenerOnUnchangedValue

如果将属性添加到会话中,该属性已在会话中以相同名称存在,并且该属性实现了 HttpSessionBindingListener,那么将通知侦听器该属性已解除绑定并重新绑定。如果未指定,将使用默认值 false

sessionActivityCheck

如果为 true,Tomcat 将跟踪每个会话的活动请求数。在确定会话是否有效时,任何至少有一个活动请求的会话都将始终被视为有效。

如果 org.apache.catalina.STRICT_SERVLET_COMPLIANCE 设置为 true,此设置的默认值为 true,否则默认值为 false

sessionLastAccessAtStart

如果为 true,会话的最后访问时间将从上一个请求开始计算。如果为 false,会话的最后访问时间将从上一个请求结束时计算。这还会影响空闲时间的计算方式。

如果 org.apache.catalina.STRICT_SERVLET_COMPLIANCE 设置为 true,此设置的默认值为 true,否则默认值为 false

标准实现

Tomcat 提供了两个标准的 Manager 实现供使用——默认实现存储活动会话,而可选实现存储已交换出的活动会话(除了在 Tomcat 重新启动时保存会话外),存储位置是通过使用适当的 Store 嵌套元素选择的。

标准管理器实现

Manager 的标准实现是 org.apache.catalina.session.StandardManager。它支持以下附加属性(除了上面列出的常见属性外)

属性 说明
pathname

如果可能,会话状态将在应用程序重新启动时保留在该文件中,该文件的绝对或相对(对于此上下文的 work 目录)路径名。默认值为 null。
有关更多信息,请参阅 跨重启持久性。可以通过将此属性设置为非空字符串来启用此持久性。

persistAuthentication

当会话状态在应用程序重新启动时保留时,是否应包括身份验证信息?如果为 true,则会话的身份验证将被保留,以便在应用程序重新启动后会话保持经过身份验证。如果未指定,将使用默认值 false
有关更多信息,请参阅 跨重启持久性

请注意,会话的 Principal 类及其后代类都受 sessionAttributeValueClassNameFilter 约束。如果指定了此类过滤器或启用了 SecurityManager,则 Principal 类和后代类的名称必须与该过滤器模式匹配才能还原。

processExpiresFrequency

会话过期频率和相关的管理器操作。对于指定的 backgroundProcess 调用次数,管理器操作将执行一次(即,次数越少,检查发生的频率越高)。最小值为 1,默认值为 6。

secureRandomClass

用于扩展 java.security.SecureRandom 以生成会话 ID 的 Java 类的名称。如果未指定,则默认值为 java.security.SecureRandom

secureRandomProvider

用于创建生成会话 ID 的 java.security.SecureRandom 实例的提供程序的名称。如果指定了无效的算法和/或提供程序,则管理器将使用平台默认提供程序和默认算法。如果未指定,将使用平台默认提供程序。

secureRandomAlgorithm

用于创建生成会话 ID 的 java.security.SecureRandom 实例的算法名称。如果指定了无效的算法和/或提供程序,则管理器将使用平台默认提供程序和默认算法。如果未指定,则将使用 SHA1PRNG 的默认算法。如果默认算法不受支持,则将使用平台默认算法。要指定应使用平台默认算法,请不要设置 secureRandomProvider 属性,并将此属性设置为一个空字符串。

sessionAttributeNameFilter

用于过滤哪些会话属性将序列化以进行群集/复制或存储到任何持久存储的正则表达式。仅当属性名称与此模式匹配时,该属性才会被序列化。如果模式长度为零或为 null,则所有属性都符合分发条件。该模式已固定,因此会话属性名称必须与该模式完全匹配。例如,值 (userName|sessionHistory) 将仅分发名为 userNamesessionHistory 的两个会话属性。如果未指定,将使用 null 的默认值。

sessionAttributeValueClassNameFilter

用于过滤哪些会话属性将序列化以进行群集/复制或存储到任何持久存储的正则表达式。仅当值的实现类名称与此模式匹配时,该属性才会被序列化。如果模式长度为零或为 null,则所有属性都符合分发条件。该模式已固定,因此完全限定的类名称必须与该模式完全匹配。如果未指定,将使用 null 的默认值,除非启用了 SecurityManager,在这种情况下,默认值为 java\\.lang\\.(?:Boolean|Integer|Long|Number|String)|org\\.apache\\.catalina\\.realm\\.GenericPrincipal\\$SerializablePrincipal|\\[Ljava.lang.String;

warnOnSessionAttributeFilterFailure

如果 sessionAttributeNameFiltersessionAttributeValueClassNameFilter 阻止了某个属性,是否应在 WARN 级别记录此属性?如果禁用了 WARN 级别记录,则将在 DEBUG 级别记录。此属性的默认值为 false,除非启用了 SecurityManager,在这种情况下,默认值为 true

持久管理器实现

注意:您必须将 org.apache.catalina.session.StandardSession.ACTIVITY_CHECKorg.apache.catalina.STRICT_SERVLET_COMPLIANCE 系统属性 设置为 true,才能让持久管理器正常工作。

Manager 的持久实现是 org.apache.catalina.session.PersistentManager。除了创建和删除会话的常规操作外,PersistentManager 还具有将活动(但空闲)会话交换到持久存储机制以及在 Tomcat 正常重新启动时保存所有会话的功能。实际使用的持久存储机制是通过在 Manager 元素内嵌套的 Store 元素选择的 - 这是使用 PersistentManager 所必需的。

除了前面描述的 通用属性 之外,Manager 的此实现还支持以下属性。

属性 说明
className

它具有与上面 通用属性 中描述的相同含义。必须指定 org.apache.catalina.session.PersistentManager 才能使用此管理器实现。

maxIdleBackup

会话自上次访问以来经过的时间间隔(以秒为单位),在此时间间隔内会话才有资格持久存储到会话存储,或 -1 表示禁用此功能。默认情况下,此功能处于禁用状态。

maxIdleSwap

会话由于不活动而有资格交换到磁盘之前可以处于空闲状态的最长时间。将其设置为 -1 表示会话不应仅因不活动而被交换出去。如果启用此功能,此处指定的时间间隔应等于或长于为 maxIdleBackup 指定的值。默认情况下,此功能处于禁用状态。

minIdleSwap

会话必须处于空闲状态的最小时间(以秒为单位),然后才有资格交换到磁盘以将活动会话计数保持在 maxActiveSessions 以下。设置为 -1 表示不会交换会话以降低活动会话计数。如果指定,此值应小于 maxIdleSwap 指定的值。默认情况下,此值设置为 -1

persistAuthentication

当会话交换到持久存储时,是否应包含身份验证信息?如果为 true,则会话的身份验证将被保留,以便在从持久存储中重新加载(交换)后会话保持经过身份验证的状态。如果未指定,将使用默认值 false

请注意,会话的 Principal 类及其后代类都受 sessionAttributeValueClassNameFilter 约束。如果指定了此类过滤器或启用了 SecurityManager,则 Principal 类和后代类的名称必须与该过滤器模式匹配才能还原。

processExpiresFrequency

与上面为 org.apache.catalina.session.StandardManager 类描述的相同。

saveOnRestart

当 Tomcat 关闭并重新启动(或当此应用程序重新加载)时,是否应持久化并重新加载所有会话?默认情况下,此属性设置为 true

secureRandomClass

与上面为 org.apache.catalina.session.StandardManager 类描述的相同。

secureRandomProvider

与上面为 org.apache.catalina.session.StandardManager 类描述的相同。

secureRandomAlgorithm

与上面为 org.apache.catalina.session.StandardManager 类描述的相同。

sessionAttributeNameFilter

用于过滤哪些会话属性将序列化以进行群集/复制或存储到任何持久存储的正则表达式。仅当属性名称与此模式匹配时,该属性才会被序列化。如果模式长度为零或为 null,则所有属性都符合分发条件。该模式已固定,因此会话属性名称必须与该模式完全匹配。例如,值 (userName|sessionHistory) 将仅分发名为 userNamesessionHistory 的两个会话属性。如果未指定,将使用 null 的默认值。

sessionAttributeValueClassNameFilter

用于过滤哪些会话属性将序列化以进行群集/复制或存储到任何持久存储的正则表达式。仅当值的实现类名称与此模式匹配时,该属性才会被序列化。如果模式长度为零或为 null,则所有属性都符合分发条件。该模式已固定,因此完全限定的类名称必须与该模式完全匹配。如果未指定,将使用 null 的默认值,除非启用了 SecurityManager,在这种情况下,默认值为 java\\.lang\\.(?:Boolean|Integer|Long|Number|String)|org\\.apache\\.catalina\\.realm\\.GenericPrincipal\\$SerializablePrincipal|\\[Ljava.lang.String;

warnOnSessionAttributeFilterFailure

如果 sessionAttributeNameFiltersessionAttributeValueClassNameFilter 阻止了某个属性,是否应在 WARN 级别记录此属性?如果禁用了 WARN 级别记录,则将在 DEBUG 级别记录。此属性的默认值为 false,除非启用了 SecurityManager,在这种情况下,默认值为 true

为了成功使用 PersistentManager,您必须在其内部嵌套一个 <Store> 元素,如下所述。

嵌套组件

所有 Manager 实现

所有 Manager 实现都允许嵌套 <SessionIdGenerator> 元素。它定义会话 ID 生成的行为。所有 SessionIdGenerator 实现都允许以下属性

属性 说明
sessionIdLength

可以使用 sessionIdLength 属性更改会话 ID 的长度。

持久管理器实现

如果您使用上面描述的持久化 Manager 实现,则必须在内部嵌套一个 <Store> 元素,该元素定义持久性数据存储的特征。目前有两种 <Store> 元素实现,具有不同的特征,如下所述。

基于文件的存储

基于文件的存储实现将交换出的会话保存在可配置目录中各个文件中(名称基于会话标识符)。因此,随着活动会话数量的增加,您可能会遇到可扩展性问题,这主要应被视为一种轻松进行实验的方法。

要配置此项,请在 <Manager> 元素中添加一个嵌套的 <Store>,并具有以下属性

属性 说明
className

要使用的实现的 Java 类名。此类必须实现 org.apache.catalina.Store 接口。您必须指定 org.apache.catalina.session.FileStore 才能使用此实现。

directory

写入各个会话文件的目录的绝对或相对(对于此 Web 应用程序的临时工作目录)路径名。如果未指定,则利用容器分配的临时工作目录。

基于数据源的存储

基于数据源的存储实现将交换出的会话保存在通过数据源访问的数据库中预配置表的各个行中。对于大量交换出的会话,此实现将比上面描述的基于文件的存储表现出更好的性能。

要配置此项,请在 <Manager> 元素中添加一个嵌套的 <Store>,并具有以下属性

属性 说明
className

要使用的实现的 Java 类名。此类必须实现 org.apache.catalina.Store 接口。您必须指定 org.apache.catalina.session.DataSourceStore 才能使用此实现。

dataSourceName

JDBC DataSource-factory 的 JNDI 资源的名称。由于此代码使用预编译语句,因此您可能希望配置池化预编译语句,如 JNDI 资源操作指南 中所示。

localDataSource

这允许存储使用为上下文而不是全局数据源定义的数据源。如果未指定,则默认值为 false:使用全局数据源。

sessionAppCol

包含在指定会话表中的数据库列的名称,该列包含引擎、主机和 Web 应用程序上下文名称,格式为 /Engine/Host/Context。如果未指定,将使用默认值 app

sessionDataCol

包含在指定会话表中的数据库列的名称,该列包含已交换会话的所有会话属性的序列化形式。该列类型必须接受二进制对象(通常称为 BLOB)。如果未指定,将使用默认值 data

sessionIdCol

包含在指定会话表中的数据库列的名称,该列包含已交换会话的会话标识符。该列类型必须接受字符字符串数据,其长度至少与 Tomcat 创建的会话标识符中包含的字符数相同(通常为 32)。如果未指定,将使用默认值 id

sessionLastAccessedCol

包含在指定会话表中的数据库列的名称,该列包含此会话的 lastAccessedTime 属性。该列类型必须接受 Java long(64 位)。如果未指定,将使用默认值 maxinactive

sessionMaxInactiveCol

包含在指定会话表中的数据库列的名称,该列包含此会话的 maxInactiveInterval 属性。该列类型必须接受 Java integer(32 位)。如果未指定,将使用默认值 maxinactive

sessionTable

用于存储已交换会话的数据库表的名称。此表必须包含(至少)此元素的其他属性配置的数据库列。如果未指定,将使用默认值 tomcat$sessions

sessionValidCol

包含在指定会话表中的数据库列的名称,该列包含一个标志,指示此已交换会话是否仍然有效。该列类型必须接受单个字符。如果未指定,将使用默认值 valid

在首次尝试使用数据源存储之前,您必须创建将用于存储已交换会话的表。详细的 SQL 命令因您使用的数据库而异,但通常需要类似以下内容的脚本

create table tomcat_sessions (
  session_id     varchar(100) not null primary key,
  valid_session  char(1) not null,
  max_inactive   int not null,
  last_access    bigint not null,
  app_name       varchar(255),
  session_data   mediumblob,
  KEY kapp_name(app_name)
);

注意:上面的 SQL 命令没有使用表或列的默认名称,因此需要配置数据源 Store 来反映这一点。

特殊功能

跨重启持久性

每当 Apache Tomcat 正常关闭并重新启动,或触发应用程序重新加载时,标准 Manager 实现都会尝试将所有当前活动会话序列化到通过 pathname 属性找到的磁盘文件中。然后,在应用程序重新加载完成后,所有这些已保存的会话都将被反序列化并激活(假设它们在此期间没有过期)。

为了成功恢复会话属性的状态,所有此类属性都必须实现 java.io.Serializable 接口。您可以通过在 Web 应用程序部署描述符 (/WEB-INF/web.xml) 中包含 <distributable> 元素来让 Manager 强制执行此限制。

请注意,如果 persistAuthentication 也设置为 true,则会话中存在的 Principal 类也必须实现 java.io.Serializable 接口才能让身份验证持久性正常工作。该 Principal 类的实际类型由应用程序使用的 Realm 实现来确定。由大多数 Realm(JAASRealm 除外)实例化的 Tomcat 标准 Principal 类实现了 java.io.Serializable

StandardManager 提供的跨重启持久性比 PersistentManager 提供的持久性更简单。如果需要跨重启的稳定、生产质量的持久性,则应将 PersistentManager 与适当的配置一起使用。

启用会话持久性

如上所述,默认情况下每个 Web 应用程序都配置了标准管理器实现,它可以在重启时执行会话持久性。要启用此持久性功能,请为 Web 应用程序创建一个 Context 配置文件,并在其中添加以下元素(在此示例中,它会将会话保存到名为 SESSIONS.ser 的文件中)

<Manager pathname="SESSIONS.ser" />