3. HttpSession 集成
Spring Session 提供了与javax.servlet.http.HttpSession
.这意味着开发人员
可以将HttpSession
implementation 替换为 Spring Session 支持的 implementation。
Spring Session 支持插入多个不同的数据存储提供程序(例如,如 Apache Geode)
为了管理HttpSession
州。
3.1. 为什么选择Spring Session和HttpSession?
我们已经提到 Spring Session 提供了与HttpSession
但是有什么好处
我们能摆脱这一切吗?
-
HttpSession - 启用
HttpSession
要进行集群化(即复制 以实现高可用性),而无需绑定到特定于应用程序容器的解决方案。 -
REST API - 允许在协议标头中提供会话 ID,以便与 RESTful API 一起使用。
-
WebSocket - 提供将
HttpSession
alive 时。 -
WebSession - 允许替换 Spring WebFlux 的
WebSession
以应用程序容器中立的方式。
3.2. 使用 Apache Geode 进行 HttpSession 管理
当 Apache Geode 与 Spring Session 一起使用时,Web 应用程序的javax.servlet.http.HttpSession
可以替换为由 Apache Geode 管理的群集实现
并使用 Spring Session 的 API 方便地访问。
使用 Apache Geode 管理会话状态的两种最常见拓扑包括:
此外,Apache Geode 还支持使用 WAN 拓扑进行站点到站点复制。 配置和使用 Apache Geode 的 WAN 功能的能力独立于 Spring Session、 并且超出了本文档的范围。
有关使用 Spring Data for Apache Geode 配置 Apache Geode WAN 功能的更多详细信息 可以在这里找到。
3.2.1. Apache Geode 客户端-服务器
客户端-服务器拓扑可能是 在 Spring Session 中使用 Apache Geode 作为提供程序时,用户最常见的配置选择,因为 与应用程序相比,Apache Geode 服务器具有明显不同且独特的 JVM 堆要求。 使用 Client-Server 拓扑使应用程序能够独立管理(例如复制)应用程序状态 从其他应用程序进程。
在 Client-Server 拓扑中,使用 Spring Session 的应用程序将打开与远程集群的 1 个或多个连接
的 Apache Geode 服务器,这些服务器将管理对所有HttpSession
州。
您可以使用以下任一方式配置客户端-服务器拓扑:
Apache Geode Client-Server 基于 Java 的配置
本节介绍如何配置 Apache Geode 的客户端-服务器拓扑以管理HttpSession
州
使用基于 Java 的配置。
带有 Apache Geode(客户端-服务器)的 HttpSession 提供了一个工作示例,演示如何
将 Spring Session 与 Apache Geode 集成以管理HttpSession state 使用 Java 配置。您可以阅读
通过下面的基本集成步骤,但我们鼓励您按照详细的 'HttpSession' 进行作
与 Apache Geode (客户端-服务器) 指南集成时。 |
Spring Java 配置
添加所需的依赖项和存储库声明后,我们可以创建 Spring 配置。
Spring 配置负责创建一个 ServletFilter
,它取代了HttpSession
以及由 Spring Session 和 Apache Geode 支持的实现。
客户端配置
添加以下 Spring 配置:
@ClientCacheApplication(name = "SpringSessionDataGeodeJavaConfigSampleClient", logLevel = "error",
readTimeout = 15000, retryAttempts = 1, subscriptionEnabled = true) (1)
@EnableGemFireHttpSession(poolName = "DEFAULT") (2)
public class ClientConfig extends ClientServerIntegrationTestsSupport {
@Bean
ClientCacheConfigurer gemfireServerReadyConfigurer( (3)
@Value("${spring.data.gemfire.cache.server.port:40404}") int cacheServerPort) {
return (beanName, clientCacheFactoryBean) -> waitForServerToStart("localhost", cacheServerPort);
}
}
1 | 首先,我们通过注释ClientConfig 类
跟@ClientCacheApplication .此外,我们还调整了一些基本的 “DEFAULT”Pool 设置(例如readTimeout ). |
2 | @EnableGemFireHttpSession 创建一个名为springSessionRepositoryFilter 实现javax.servlet.Filter .过滤器将替换HttpSession 使用 Spring Session 提供的实现
并由 Apache Geode 提供支持。此外,该配置还将创建必要的客户端Region (默认情况下,“ClusteredSpringSessions”,它是一个PROXY Region ) 对应于同一服务器端Region 按名称。所有会话状态都通过Region 数据访问作。
客户端Region 使用 “DEFAULT”Pool . |
3 | 然后,我们等待确保 Apache Geode Server 已启动并运行,然后再继续。这才真正有用 用于自动化 (集成) 测试目的。 |
在典型的 Apache Geode 生产部署中,集群可能包括数百或数千个 的服务器(也称为数据节点)中,客户端更常见的是连接到 1 个或多个正在运行的 Apache Geode 定位器 在同一个集群中。Locator 将有关集群中可用服务器的元数据传递给客户端,单个 server load 以及哪些服务器具有感兴趣的客户端数据,这对于 Direct 尤为重要。 单跳数据访问和延迟敏感型应用程序。有关客户端/服务器部署的更多详细信息,请参阅 Apache Geode 用户指南。 |
有关配置 Spring Data Geode 的更多信息,请参阅参考指南。 |
这@EnableGemFireHttpSession
注解使开发人员能够配置 Spring Session 的某些方面
和 Apache Geode 开箱即用,使用以下属性:
-
clientRegionShortcut
- 使用 ClientRegionShortcut 在客户端上指定 Apache Geode 数据管理策略(默认值为PROXY
).此属性仅在配置客户端时使用Region
. -
indexableSessionAttributes
- 按名称标识 Session 应为查询目的编制索引的属性。 只有 name 显式标识的 Session 属性才会被索引。 -
maxInactiveIntervalInSeconds
- 控制 HttpSession 空闲超时过期时间(默认为 30 分钟)。 -
poolName
- 专用 Apache Geode 的名称Pool
用于将客户端连接到服务器集群。 仅当应用程序是高速缓存客户端时,才使用此属性。默认为gemfirePool
. -
regionName
- 指定 Apache Geode 的名称Region
用于存储和管理HttpSession
州 (默认为 “ClusteredSpringSessions”)。 -
serverRegionShortcut
- 使用 RegionShortcut 在服务器上指定 Apache Geode 数据管理策略(默认值为PARTITION
).此属性仅在配置 server 时使用Regions
, 或者当采用 P2P 拓扑时。
请务必记住,Apache Geode 客户端Region name 必须与 server 匹配Region 如果客户端Region 是一个PROXY 或CACHING_PROXY .客户端和服务器Region 名字
如果客户端Region 用于存储会话状态的是LOCAL .但是,请记住
该会话状态不会传播到服务器,并且您将失去使用 Apache Geode 的所有好处
要在分布式
复制方式。 |
服务器配置
到目前为止,我们只介绍了等式的一面。我们还需要一个 Apache Geode 服务器,以便我们的缓存客户端与之通信 并将会话状态发送到服务器进行管理。
在此示例中,我们将使用以下 Java 配置来配置和运行 Apache Geode 服务器:
@CacheServerApplication(name = "SpringSessionDataGeodeJavaConfigSampleServer", logLevel = "error") (1)
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 30) (2)
public class GemFireServer {
@SuppressWarnings("resource")
public static void main(String[] args) {
new AnnotationConfigApplicationContext(GemFireServer.class).registerShutdownHook();
}
}
1 | 首先,我们使用@CacheServerApplication 注解来简化对等缓存实例的创建
包含CacheServer 供缓存客户端连接。 |
2 | (可选)然后,GemFireServer class 的@EnableGemFireHttpSession 创建必要的
服务器端Region (默认情况下为 “ClusteredSpringSessions”)用于存储HttpSession 州。此步骤为
可选,因为会话Region 可以手动创建,也许使用外部方法。
用@EnableGemFireHttpSession 方便快捷。 |
Apache Geode 客户端-服务器基于 XML 的配置
本节介绍如何配置 Apache Geode 的客户端-服务器拓扑以管理HttpSession
州
使用基于 XML 的配置。
使用 XML 的 HttpSession 与 Apache Geode(客户端-服务器)提供了一个工作示例
演示如何将 Spring Session 与 Apache Geode 集成以管理HttpSession 使用 XML 的状态
配置。您可以阅读下面的集成基本步骤,但我们鼓励您按照
在详细的 'HttpSession' with Apache Geode (Client-Server) using XML Guide 中集成时
您自己的应用程序。 |
Spring XML 配置
添加所需的依赖项和存储库声明后,我们可以创建 Spring 配置。
Spring 配置负责创建一个Servlet
Filter
,它取代了javax.servlet.http.HttpSession
以及由 Spring Session 和 Apache Geode 支持的实现。
客户端配置
添加以下 Spring 配置:
<context:annotation-config/>
<context:property-placeholder/>
<bean class="sample.client.ClientServerReadyBeanPostProcessor"/>
(1)
<util:properties id="gemfireProperties">
<prop key="log-level">${spring.data.gemfire.cache.log-level:error}</prop>
</util:properties>
(2)
<gfe:client-cache properties-ref="gemfireProperties" pool-name="gemfirePool"/>
(3)
<gfe:pool read-timeout="15000" retry-attempts="1" subscription-enabled="true">
<gfe:server host="localhost" port="${spring.data.gemfire.cache.server.port:40404}"/>
</gfe:pool>
(4)
<bean class="org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration"
p:poolName="DEFAULT"/>
1 | (可选)首先,我们可以包含一个Properties bean 配置 Apache Geode 的某些方面ClientCache 使用 Pivotal GemFire 属性。在这种情况下,我们只是
使用特定于应用程序的 System 属性设置 Apache Geode 的 “log-level”,默认为 “warning”
如果未指定。 |
2 | 我们必须创建一个 Apache Geode 的实例ClientCache .我们使用gemfireProperties . |
3 | 然后我们配置一个Pool 与客户端/服务器拓扑中的 Apache Geode 服务器通信的连接数。
在我们的配置中,我们对超时、连接数等使用合理的设置。此外,我们的Pool 已配置为直接连接到服务器(使用嵌套的gfe:server 元素)。 |
4 | 最后,一个GemFireHttpSessionConfiguration bean 以启用 Spring Session 功能。 |
在典型的 Apache Geode 生产部署中,集群可能包括数百或数千个 的服务器(也称为数据节点)中,客户端更常见的是连接到 1 个或多个正在运行的 Apache Geode 定位器 在同一个集群中。Locator 将有关集群中可用服务器的元数据传递给客户端,单个 server load 以及哪些服务器具有感兴趣的客户端数据,这对于 Direct 尤为重要。 单跳数据访问和延迟敏感型应用程序。有关客户端/服务器部署的更多详细信息,请参阅 Apache Geode 用户指南。 |
有关为 Apache Geode 配置 Spring Data 的更多信息,请参阅参考指南。 |
服务器配置
到目前为止,我们只介绍了等式的一面。我们还需要一个 Apache Geode 服务器,以便我们的缓存客户端与之通信 并将会话状态发送到服务器进行管理。
在此示例中,我们将使用以下 XML 配置来启动 Apache Geode 服务器:
<context:annotation-config/>
<context:property-placeholder/>
(1)
<util:properties id="gemfireProperties">
<prop key="name">SpringSessionDataGeodeSampleXmlServer</prop>
<prop key="log-level">${spring.data.gemfire.cache.log-level:error}</prop>
</util:properties>
(2)
<gfe:cache properties-ref="gemfireProperties"/>
(3)
<gfe:cache-server port="${spring.data.gemfire.cache.server.port:40404}"/>
(4)
<bean class="org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration"
p:maxInactiveIntervalInSeconds="30"/>
1 | (可选)首先,我们可以包含一个Properties bean 配置 Apache Geode 对等节点的某些方面Cache 使用 Pivotal GemFire 属性。在这种情况下,我们只是
使用特定于应用程序的 System 属性设置 Apache Geode 的 “log-level”,默认为 “warning”
如果未指定。 |
2 | 我们必须配置 Apache Geode 对等体Cache 实例。我们使用 Apache Geode 属性对其进行初始化。 |
3 | 接下来,我们定义一个CacheServer 具有合理的配置bind-address 和port 由我们的缓存客户端使用
应用程序连接到服务器并发送会话状态。 |
4 | 最后,我们启用我们在客户端 XML 配置中声明的相同 Spring Session 功能
通过注册GemFireHttpSessionConfiguration ,但我们设置了会话过期超时
设置为 30 秒。我们稍后会解释这意味着什么。 |
Apache Geode Server 使用以下方法进行引导:
@Configuration (1)
@ImportResource("META-INF/spring/session-server.xml") (2)
public class GemFireServer {
public static void main(String[] args) {
new AnnotationConfigApplicationContext(GemFireServer.class).registerShutdownHook();
}
}
而不是使用main 方法,您可以考虑改用 Spring Boot。 |
1 | 这@Configuration 注解将此 Java 类指定为 Spring 配置元数据的源,使用
7.9. 基于注解的容器配置[Spring 的注解配置支持]。 |
2 | 首先,配置来自META-INF/spring/session-server.xml 文件。 |
XML Servlet 容器初始化
我们的 Spring XML 配置创建了一个名为springSessionRepositoryFilter
实现javax.servlet.Filter
接口。这springSessionRepositoryFilter
bean 负责替换
这javax.servlet.http.HttpSession
使用由 Spring Session 和 Apache Geode 提供的自定义实现。
为了我们的Filter
为了发挥它的魔力,我们需要指示 Spring 加载
我们session-client.xml
配置文件。
我们使用以下配置执行此作:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/session-client.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
ContextLoaderListener 读取contextConfigLocation
context 参数值,并选取我们的 session-client.xml 配置文件。
最后,我们需要确保我们的 Servlet 容器(即 Tomcat)使用我们的springSessionRepositoryFilter
对于每个请求。
以下代码片段为我们执行了最后一步:
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
DelegatingFilterProxy 将查找名称为springSessionRepositoryFilter
并将其转换为Filter
.对于每个 HTTP 请求,
这DelegatingFilterProxy
调用,该 API 将委托给springSessionRepositoryFilter
.
3.2.2. Apache Geode 点对点 (P2P)
一种不太常见的方法是将 Spring Session 应用程序配置为 Apache Geode 集群中的对等成员 使用点对点 (P2P) 拓扑。 在此配置中,Spring Session 应用程序将是 Apache Geode 中的实际服务器(或数据节点) cluster 的 CLUSTER,而不仅仅是像以前那样只是一个缓存客户端。
这种方法的一个优点是应用程序接近应用程序的状态(即它的数据),
特别是HttpSession
州。但是,还有其他有效的方法可以实现类似的
依赖于数据的计算,例如使用 Apache Geode 的 Function Execution。
在以下情况下可以使用 Apache Geode 的任何其他功能
Apache Geode 在 Spring Session 中充当提供程序。
P2P 拓扑结构对于测试目的以及更小、更专注和独立的应用程序非常有用。 例如微服务架构中的那些,并且肯定会改善您的应用程序的感知 延迟和吞吐量需求。
您可以使用以下任一方式配置点对点 (P2P) 拓扑:
Apache Geode 点对点 (P2P) 基于 Java 的配置
本节介绍如何配置 Apache Geode 的点对点 (P2P) 拓扑以管理HttpSession
州
使用基于 Java 的配置。
HttpSession 与 Apache Geode (P2P) 提供了一个工作示例,演示如何
将 Spring Session 与 Apache Geode 集成以管理HttpSession state 使用 Java 配置。您可以阅读
通过下面的基本集成步骤,但我们鼓励您按照详细的 'HttpSession' 进行作
与 Apache Geode (P2P) 指南集成时。 |
Spring Java 配置
添加所需的依赖项和存储库声明后,我们可以创建 Spring 配置。
Spring 配置负责创建一个Servlet
Filter
,它取代了javax.servlet.http.HttpSession
以及由 Spring Session 和 Apache Geode 支持的实现。
添加以下 Spring 配置:
@PeerCacheApplication(name = "SpringSessionDataGeodeJavaConfigP2pSample", logLevel = "error") (1)
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 30) (2)
public class Config {
}
1 | 首先,我们使用@PeerCacheApplication 注解来简化对等缓存实例的创建。 |
2 | 然后,Config class 的@EnableGemFireHttpSession 创建必要的服务器端Region (默认情况下为 “ClusteredSpringSessions”)用于存储HttpSession 州。 |
有关为 Apache Geode 配置 Spring Data 的更多信息,请参阅参考指南。 |
这@EnableGemFireHttpSession
注解使开发人员能够配置 Spring Session 的某些方面
和 Apache Geode 开箱即用,使用以下属性:
-
clientRegionShortcut
- 使用 ClientRegionShortcut 在客户端上指定 Apache Geode 数据管理策略(默认值为PROXY
).此属性仅在配置客户端时使用Region
. -
indexableSessionAttributes
- 按名称标识 Session 应为查询目的编制索引的属性。 只有 name 显式标识的 Session 属性才会被索引。 -
maxInactiveIntervalInSeconds
- 控制 HttpSession 空闲超时过期时间(默认为 30 分钟)。 -
poolName
- 专用 Apache Geode 的名称Pool
用于将客户端连接到服务器集群。 仅当应用程序是高速缓存客户端时,才使用此属性。默认为gemfirePool
. -
regionName
- 指定 Apache Geode 的名称Region
用于存储和管理HttpSession
州 (默认为 “ClusteredSpringSessions”)。 -
serverRegionShortcut
- 使用 RegionShortcut 在服务器上指定 Apache Geode 数据管理策略(默认值为PARTITION
).此属性仅在配置 server 时使用Regions
, 或者当采用 P2P 拓扑时。
Java Servlet 容器初始化
我们的<<[httpsession-spring-java-configuration-p2p,Spring Java Configuration>>创建了一个名为springSessionRepositoryFilter
实现javax.servlet.Filter
.这springSessionRepositoryFilter
豆
负责替换javax.servlet.http.HttpSession
使用由
Spring Session 和 Apache Geode。
为了我们的Filter
为了发挥它的魔力,Spring 需要加载我们的Config
类。我们还需要确保我们的
Servlet 容器(即 Tomcat)使用我们的springSessionRepositoryFilter
在每个 HTTP 请求上。
幸运的是,Spring Session 提供了一个名为AbstractHttpSessionApplicationInitializer
使两者
步骤非常简单。
您可以在下面找到一个示例:
public class Initializer extends AbstractHttpSessionApplicationInitializer { (1)
public Initializer() {
super(Config.class); (2)
}
}
我们类的名称 (Initializer ) 无关紧要。重要的是,我们扩展AbstractHttpSessionApplicationInitializer . |
1 | 第一步是扩展AbstractHttpSessionApplicationInitializer .这可确保名为springSessionRepositoryFilter 在我们的 Servlet 容器中注册,并用于每个 HTTP 请求。 |
2 | AbstractHttpSessionApplicationInitializer 还提供了一种机制,可轻松允许 Spring 加载
我们Config 类。 |
基于 Apache Geode 对等 (P2P) XML 的配置
本节介绍如何配置 Apache Geode 的点对点 (P2P) 拓扑以管理HttpSession
州
使用基于 XML 的配置。
使用 XML 的 HttpSession with Apache Geode (P2P) 提供了一个工作示例,演示如何
将 Spring Session 与 Apache Geode 集成以管理HttpSession state 使用 XML 配置。您可以阅读
通过下面的基本集成步骤,但我们鼓励您按照详细的 'HttpSession' 进行作
与 Apache Geode (P2P) 集成时,使用 XML 指南。 |
Spring XML 配置
添加所需的依赖项和存储库声明后,我们可以创建 Spring 配置。
Spring 配置负责创建一个Servlet
Filter
,它取代了javax.servlet.http.HttpSession
以及由 Spring Session 和 Apache Geode 支持的实现。
添加以下 Spring 配置:
<context:annotation-config/>
<context:property-placeholder/>
(1)
<util:properties id="gemfireProperties">
<prop key="name">SpringSessionDataGeodeXmlP2pSample</prop>
<prop key="log-level">${spring.data.gemfire.cache.log-level:error}</prop>
</util:properties>
(2)
<gfe:cache properties-ref="gemfireProperties"/>
(3)
<bean class="org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration"
p:maxInactiveIntervalInSeconds="30"/>
1 | (可选)首先,我们可以包含一个Properties bean 配置 Apache Geode 对等节点的某些方面Cache 使用 VMware Tanzu GemFire 属性。在这种情况下,我们只是
使用特定于应用程序的 System 属性设置 Apache Geode 的 “log-level”,默认为 “warning”
如果未指定。 |
2 | 我们必须配置 Apache Geode 对等体Cache 实例。我们使用 Apache Geode 属性对其进行初始化。 |
3 | 最后,我们通过注册GemFireHttpSessionConfiguration . |
有关为 Apache Geode 配置 Spring Data 的更多信息,请参阅参考指南。 |
XML Servlet 容器初始化
Spring XML 配置创建了一个名为springSessionRepositoryFilter
实现javax.servlet.Filter
.这springSessionRepositoryFilter
bean 负责替换javax.servlet.http.HttpSession
使用由 Spring Session 和 Apache Geode 支持的自定义实现。
为了我们的Filter
为了发挥它的魔力,我们需要指示 Spring 加载我们的session.xml
配置文件。
我们使用以下配置执行此作:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/*.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
ContextLoaderListener 读取contextConfigLocation
context 参数值,并选取我们的 session.xml 配置文件。
最后,我们需要确保我们的 Servlet 容器(即 Tomcat)使用我们的springSessionRepositoryFilter
对于每个 HTTP 请求。
以下代码片段为我们执行了最后一步:
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
DelegatingFilterProxy 将查找名称为springSessionRepositoryFilter
并将其转换为Filter
.对于每个 HTTP 请求
这DelegatingFilterProxy
调用,委托给springSessionRepositoryFilter
.
3.3. 配置HttpSession
使用具有属性的 Apache Geode 进行管理
虽然@EnableGemFireHttpSession
注解在开始使用 Spring Session 时易于使用和方便
和 Apache Geode 在 Spring Boot 应用程序中迁移时,您很快就会遇到限制
环境转换为另一个环境,例如,从 DEV 迁移到 QA 再到 PROD 时。
使用@EnableGemFireHttpSession
annotation 属性,则无法更改
环境到另一个。因此,Spring Session for Apache Geode 引入了众所周知的、记录在案的属性
对于所有的@EnableGemFireHttpSession
annotation 属性。
财产 | Annotation 属性 | 描述 | 违约 |
---|---|---|---|
spring.session.data.gemfire.cache.client.pool.name |
|
客户端区域存储/访问 Session 状态使用的专用池的名称。 |
gemfirePool |
spring.session.data.gemfire.cache.client.region.shortcut |
|
在客户端-服务器拓扑中设置客户端区域数据管理策略。 |
ClientRegionShortcut.代理 |
spring.session.data.gemfire.cache.server.region.shortcut |
|
在对等 (P2P) 拓扑中设置对等区域数据管理策略。 |
RegionShortcut.PARTITION 分区 |
spring.session.data.gemfire.session.attributes.indexable |
|
要在 Session 区域中编制索引的 Session 属性的逗号分隔列表。 |
|
spring.session.data.gemfire.session.expiration.bean-name |
|
实现过期策略的 Spring 容器中的 Bean 的名称 |
|
spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds |
|
会话过期超时(秒) |
1800 |
spring.session.data.gemfire.session.region.name |
|
用于存储和访问 Session 状态的客户端或对等区域的名称。 |
ClusteredSpringSessions 集群 |
spring.session.data.gemfire.session.serializer.bean-name |
|
实现序列化策略的 Spring 容器中的 Bean 的名称 |
SessionPdxSerializer |
所有属性都记录在@EnableGemFireHttpSession annotation 属性 Javadoc 中。 |
因此,在使用 Apache Geode 时,调整 Spring Session 的配置非常简单 作为您的提供商,如下所示:
@SpringBootApplication
@ClientCacheApplication
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 900)
class MySpringSessionApplication {
// ...
}
然后,在application.properties
:
#application.properties
spring.session.data.gemfire.cache.client.region.shortcut=CACHING_PROXY
spring.session.data.gemfire.session.expiration.max-inactive-internval-seconds=3600
显式定义的任何属性都会覆盖相应的@EnableGemFireHttpSession
annotation 属性。
在上面的示例中,即使EnableGemFireHttpSession
注解maxInactiveIntervalInSeconds
属性
设置为900
秒或 15 分钟,则相应的属性属性
(即spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds
)
覆盖该值并将 Expiration 设置为3600
秒,即 60 分钟。
请记住,属性会在运行时覆盖 annotation 属性值。 |
3.3.1. 属性的属性
您甚至可以变得更复杂,并使用其他属性配置您的属性,如下所示:
#application.properties
spring.session.data.gemfire.session.expiration.max-inactive-internval-seconds=${app.geode.region.expiration.timeout:3600}
此外,您可以使用 Spring 配置文件根据环境改变过期超时(或其他属性) 或您的应用程序,或者您的应用程序要求的任何标准。
属性占位符和嵌套是核心 Spring Framework 的一个功能,并不特定于 Spring Session 或 Spring Session for Apache Geode。 |
3.4. 配置HttpSession
使用 Apache Geode 和 Configurer 进行管理
除了属性之外,Spring Session for Apache Geode 还允许您调整
使用 Apache Geode 的 Spring SessionSpringSessionGemFireConfigurer
接口。该接口定义了一个
Contract 包含每个@EnableGemFireHttpSession
annotation 属性
调整配置。
这SpringSessionGemFireConfigurer
在概念上类似于 Spring Web MVC 的 Configurer 接口
(例如o.s.web.servlet.config.annotation.WebMvcConfigurer
),它调整 Web 应用程序的
配置,例如配置异步支持。声明和实现Configurer
是它允许您对配置进行编程控制。这在您需要的情况下非常有用
轻松表达确定是否应应用配置的复杂条件逻辑。
例如,要像以前一样调整 client Region data management policy (客户端区域数据管理策略) 和 Session expiration timeout (会话过期超时),请执行以下作: 使用以下内容:
@Configuration
class MySpringSessionConfiguration {
@Bean
SpringSessionGemFireConfigurer exampleSpringSessionGemFireConfigurer() {
return new SpringSessionGemFireConfigurer() {
@Override
public ClientRegionShortcut getClientRegionShortcut() {
return ClientRegionShortcut.CACHING_PROXY;
}
@Override
public int getMaxInactiveIntervalInSeconds() {
return 3600;
}
};
}
}
当然,这个例子不是很有创意。您肯定可以使用更复杂的逻辑来确定 每个 configuration 属性的 configuration。
您可以根据需要进行调试,例如通过实施Configurer
在其他属性方面
使用 Spring 的@Value
注解,如下所示:
@Configuration
class MySpringSessionConfiguration {
@Bean
@Primary
@Profile("production")
SpringSessionGemFireConfigurer exampleSpringSessionGemFireConfigurer(
@Value("${app.geode.region.data-management-policy:CACHING_PROXY}") ClientRegionShortcut shortcut,
@Value("${app.geode.region.expiration.timeout:3600}") int timeout) {
return new SpringSessionGemFireConfigurer() {
@Override
public ClientRegionShortcut getClientRegionShortcut() {
return shortcut;
}
@Override
public int getMaxInactiveIntervalInSeconds() {
return timeout;
}
};
}
}
Spring Boot 将解析@Value annotation 属性占位符值或 SpEL 表达式。
但是,如果您不使用 Spring Boot,则必须显式注册一个静态PropertySourcesPlaceholderConfigurer bean 定义。 |
但是,您只能声明 1SpringSessionGemFireConfigurer
bean 中,除非
您还在使用 Spring 配置文件或标记了多个SpringSessionGemFireConfigurer
以 bean 为主要
通过使用 Spring 的@Primary
context 注释。
3.4.1. 配置优先级
一个SpringSessionGemFireConfigurer
优先于@EnableGemFireHttpSession
注释属性
或任何已知且记录在 案的 Spring Session for Apache Geode 属性
(例如spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds
)
在 Spring Boot 中定义application.properties.
如果您的 Web 应用程序使用了 1 种以上的配置方法,则以下优先级将适用:
-
SpringSessionGemFireConfigurer
“已实现” 回调方法 -
记录的 Spring Session for Apache Geode 属性(请参阅相应的
@EnableGemFireHttpSession
注解 属性 Javadoc;例如spring.session.data.gemfire.session.region.name
) -
@EnableGemFireHttpSession
注释属性
Spring Session for Apache Geode 会小心翼翼地仅应用来自SpringSessionGemFireConfigurer
豆
在 Spring 容器中声明。
在上面的示例中,由于您没有实现getRegionName()
method,即 Apache Geode 区域的名称
管理HttpSession
state 不会由 Configurer 决定。
例
例如,请考虑以下配置:
@ClientCacheApplication
@EnableGemFireHttpSession(
maxInactiveIntervalInSeconds = 3600,
poolName = "DEFAULT"
)
class MySpringSessionConfiguration {
@Bean
SpringSessionGemFireConfigurer sessionExpirationTimeoutConfigurer() {
return new SpringSessionGemFireConfigurer() {
@Override
public int getMaxInactiveIntervalInSeconds() {
return 300;
}
};
}
}
此外,请考虑以下 Spring Bootapplication.properties
文件:
-
Spring Boot
application.properties
spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds = 900 spring.session.data.gemfire.session.region.name = Sessions
Session expiration timeout (会话过期超时) 将为 300 秒或 5 分钟,覆盖
(即spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds
) 为 900 秒或 15 分钟,
以及显式的@EnableGemFireHttpSession.maxInactiveIntervalInSeconds
annotation 属性值为
3600 秒,即 1 小时。
由于 “sessionExpirationTimeoutConfigurer” bean 不会覆盖getRegionName()
方法中,Session Region
name 将由属性(即spring.session.data.gemfire.session.region.name
)、设置为 “会话”、
这会覆盖隐式的@EnableGemFireHttpSession.regionName
annotation 属性的默认值
“ClusteredSpringSessions” 的 ClusteredSpringSessions 中。
这@EnableGemFireHttpSession.poolName
annotation 属性的值 “DEFAULT” 将决定存储池的名称
在客户端和服务器之间发送 Region作以管理服务器上的 Session 状态时使用,因为
设置了相应的属性(即 spring.session.data.gemfire.cache.client.pool.name'),也未设置
这SpringSessionGemFireConfigurer.getPoolName()
方法被 “sessionExpirationTimeoutConfigurer” Bean 覆盖。
最后,用于管理 Session 状态的 Client Region 将具有PROXY
,则默认的
值@EnableGemFireHttpSession.clientRegionShortcut
annotation 属性,该属性未显式设置,也
是相应的属性(即spring.session.data.gemfire.cache.client.region.shortcut
) 的 S 属性。
而且,由于SpringSessionConfigurer.getClientRegionShortcut()
method 未被覆盖,则使用默认值。
3.5. Apache Geode 过期
默认情况下,Apache Geode 使用 过期超时为 30 分钟,并将 INVALIDATE 条目作为作。这意味着当用户的 Session 保持非活动状态时 (即空闲)超过 30 分钟,Session 将过期并失效,用户必须开始新的 Session 以便继续使用该应用程序。
但是,如果您对会话状态管理和过期以及使用 默认的空闲超时 (TTI) 过期策略不足以满足您的用例 (UC) 需求?
现在,Spring Session for Apache Geode 支持特定于应用程序的自定义过期策略。作为应用程序 开发者,你可以指定自定义规则来管理由 Spring Session 管理的 Session 的过期,由 Apache Geode 的 Apache。
Spring Session for Apache Geode 提供了新的SessionExpirationPolicy
策略界面。
@FunctionalInterface
interface SessionExpirationPolicy {
// determine timeout for expiration of individual Session
Optional<Duration> determineExpirationTimeout(Session session);
// define the action taken on expiration
default ExpirationAction getExpirationAction() {
return ExpirationAction.INVALIDATE;
}
enum ExpirationAction {
DESTROY,
INVALIDATE
}
}
您实施此接口以指定应用程序所需的 Session 过期策略,然后注册 实例作为 Spring 应用程序上下文中的 Bean。
使用@EnableGemFireHttpSession
注解sessionExpirationPolicyBeanName
属性来配置
这SessionExpirationPolicy
实现 Session 过期的自定义应用程序策略和规则的 bean。
例如:
SessionExpirationPolicy
class MySessionExpirationPolicy implements SessionExpirationPolicy {
public Duration determineExpirationTimeout(Session session) {
// return a java.time.Duration specifying the length of time until the Session should expire
}
}
然后,在您的 application 类中,简单地声明以下内容:
SessionExpirationPolicy
配置@SpringBootApplication
@EnableGemFireHttpSession(
maxInactiveIntervalInSeconds = 600,
sessionExpirationPolicyBeanName = "expirationPolicy"
)
class MySpringSessionApplication {
@Bean
SessionExpirationPolicy expirationPolicy() {
return new MySessionExpirationPolicy();
}
}
或者,该SessionExpirationPolicy bean 可以使用spring.session.data.gemfire.session.expiration.bean-name 属性,或者通过声明SpringSessionGemFireConfigurer bean 并覆盖 Spring 容器中的getSessionExpirationPolicyBeanName() 方法。 |
您只需实现determineExpirationTimeout(:Session):Optional<Duration>
方法
它封装了规则以确定 Session 何时到期。Session 的过期超时
表示为Optional
之java.time.Duration
,它指定会话过期之前的时间长度。
这determineExpirationTimeout
method 可以是特定于 Session 的,并且可能会随着每次调用而更改。
或者,您可以实现getAction
方法指定 Session 过期时执行的作。默认情况下,
区域条目(即 Session)无效。另一种选择是在过期时销毁 Region Entry,
这将删除键 (Session ID) 和值 (Session)。Invalidate 仅删除该值。
在后台,SessionExpirationPolicy 改编为 Apache Geode 的实例CustomExpiry 接口。
本届Spring SessionCustomExpiry 对象设置为会话区域的自定义条目空闲超时过期策略。 |
在确定到期时间期间,CustomExpiry.getExpiry(:Region.Entry<String, Session>):ExpirationAttributes 每次运行过期线程时,都会为区域中的每个条目(即 Session)调用 method,这反过来又会调用
调用我们的SessionExpirationPolicy.determineExpirationTimout(:Session):Optional<Duration> 方法。
返回的java.time.Duration 转换为秒,并用作ExpirationAttributes 从CustomExpiry.getExpiry(..) 方法调用。 |
Apache Geode 的过期线程每秒运行一次,评估区域中的每个条目(即会话)
以确定条目是否已过期。您可以使用gemfire.EXPIRY_THREADS 财产。有关更多详细信息,请参阅 Apache Geode 文档。 |
3.5.1. Expiration Timeout 配置
如果要将过期超时作为自定义SessionExpirationPolicy
上
这@EnableGemFireHttpSession
注解maxInactiveIntervalInSeconds
属性,或者
相应的spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds
财产
然后是您的自定义SessionExpirationPolicy
implementation 还可以实现SessionExpirationTimeoutAware
接口。
这SessionExpirationTimeoutAware
interface 定义为:
interface SessionExpirationTimeoutAware {
void setExpirationTimeout(Duration expirationTimeout);
}
当您的自定义SessionExpirationPolicy
implementation 还会实现SessionExpirationTimeoutAware
接口
则 Spring Session for Apache Geode 将为您的实现提供@EnableGemFireHttpSession
注解maxInactiveIntervalInSeconds
属性,或者从spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds
属性(如果已设置)或从任何SpringSessionGemFireConfigurer
bean 作为java.time.Duration
.
如果使用了 1 个以上的配置选项,则以下顺序优先:
-
SpringSessionGemFireConfigurer.getMaxInactiveIntervalInSeconds()
-
spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds
财产 -
@EnableGemFireHttpSession
注解maxInactiveIntervalInSeconds
属性
3.5.2. 固定超时过期
为了更加方便,Spring Session for Apache Geode 提供了SessionExpirationPolicy
固定持续时间过期的接口(或核心 Spring Session Issue #922 中描述的“绝对会话超时”)。
在某些情况下,例如出于安全原因,可能需要在固定 时间长度 (例如每小时),无论用户的 Session 是否仍处于活动状态。
Spring Session for Apache Geode 提供了FixedTimeoutSessionExpirationPolicy
开箱即用的实施
对于此确切的用例 (UC)。除了处理固定期限到期外,还要小心地仍然考虑
并应用默认的 Idle Expiration 超时。
例如,考虑这样一个场景:用户登录,开始一个会话,处于活动状态 10 分钟,然后离开 让 Session 处于空闲状态。如果固定持续时间过期超时设置为 60 分钟,但空闲过期 超时仅设置为 30 分钟,并且用户未返回,则 Session 应在 40 分钟后过期 而不是 60 分钟,此时将发生固定持续时间过期。
相反,如果用户忙碌了整整 40 分钟,从而使 Session 保持活动状态,从而避免了 30 分钟 idle expiration timeout,然后离开,那么我们的固定持续时间过期超时应该开始并过期 用户的 Session 时间,即使用户的空闲过期超时要到 70 分钟才会发生 in(40 分钟 (活动) + 30 分钟 (空闲) = 70 分钟)。
嗯,这正是FixedTimeoutSessionExpirationPolicy
确实。
要配置FixedTimeoutSessionExpirationPolicy
,执行以下作:
@SpringBootApplication
@EnableGemFireHttpSession(sessionExpirationPolicyBeanName = "fixedTimeoutExpirationPolicy")
class MySpringSessionApplication {
@Bean
SessionExpirationPolicy fixedTimeoutExpirationPolicy() {
return new FixedTimeoutSessionExpirationPolicy(Duration.ofMinutes(60L));
}
}
在上面的示例中,FixedTimeoutSessionExpirationPolicy
在 Spring 应用程序上下文中声明为 Bean
并使用 60 分钟的固定持续时间过期超时进行初始化。因此,用户的 Session 将
在空闲超时(默认为 30 分钟)或固定超时(配置为 60 分钟)后过期,
哪个先发生。
还可以使用
Apache Geode 的 Spring SessionFixedDurationExpirationSessionRepositoryBeanPostProcessor .此 BPP 包装
任何特定于 Data Store 的SessionRepository 在FixedDurationExpirationSessionRepository 实现
,仅评估 Sessions 在访问时过期。此方法与基础数据存储无关
因此可以与任何 Spring Session 提供程序一起使用。到期确定完全基于
会话creationTime 属性和所需的java.time.Duration 指定固定持续时间
过期超时。 |
这FixedDurationExpirationSessionRepository 不应在严格的过期超时情况下使用,例如
当 Session 必须在固定持续时间过期超时后立即过期时。此外,与
这FixedTimeoutSessionExpirationPolicy 这FixedDurationExpirationSessionRepository 不采用空闲过期
timeout 的考虑。也就是说,在确定过期超时时,它只使用固定持续时间
对于给定的 Session。 |
3.5.3.SessionExpirationPolicy
链接
使用 Composite 软件设计模式,您可以将一组SessionExpirationPolicy
实例作为单个实例,就像在一个链中一样工作,就像
Servlet 过滤器本身。
复合软件设计模式是一种功能强大的模式,由SessionExpirationPolicy
,@FunctionalInterface
,只需返回Optional
之java.time.Duration
从
这determineExpirationTimeout
方法。
这允许每个组合SessionExpirationPolicy
以 “optionally” 返回一个Duration
仅当
可以由此实例确定。或者,此实例可能会传送到下一个SessionExpirationPolicy
在组合中,或链,直到返回非空过期超时,或者最终返回
不返回过期超时。
事实上,这个策略正是由FixedTimeoutSessionExpirationPolicy
,它将返回Optional.empty()
在固定超时之前发生空闲超时的情况下。通过返回
无过期超时,Apache Geode 将遵循默认的、配置的条目空闲超时过期策略
在管理 Session 状态的区域上。
3.6. Apache Geode 序列化
为了在客户端和服务器之间传输数据,或者在对等节点之间分发和复制数据 在集群中,数据必须序列化。在这种情况下,有问题的数据是 Session 的状态。
每当 Session 在 client/server 拓扑中被持久化或访问时,Session 的状态都会通过网络发送。 通常,启用了 Spring Session 的 Spring Boot 应用程序将是集群中服务器的客户端 Apache Geode 节点。
在服务器端,Session 状态可能分布在集群中的多个服务器(数据节点)之间进行复制 数据,并保证 Session 状态的高可用性。使用 Apache Geode 时,可以对数据进行分区, 或 sharded,并且可以指定 redundancy-level 。当分发数据以进行复制时,它还必须 serialized 在集群中的 Peer 节点之间传输 Session 状态。
开箱即用的 Apache Geode 支持 Java 序列化。Java 序列化有很多优点, 例如处理对象图中的循环,或者被任何用 Java 编写的应用程序普遍支持。 但是,Java 序列化非常冗长,并不是最有效的在线格式。
因此,Apache Geode 提供了自己的序列化框架来序列化 Java 类型:
3.6.1. Apache Geode 序列化背景
如上所述,Apache Geode 提供了 2 个额外的序列化框架:数据序列化和 PDX 序列化。
数据序列化
数据序列化是一种非常有效的格式(即快速和紧凑),与 Java 序列化相比开销很小。
它通过发送 只发送实际更改的数据位,而不是发送整个对象,这肯定会减少 除了在持久保存数据时减少 IO 量外,还关注通过网络发送的数据量 或溢出到磁盘。
但是,每当数据通过网络传输或持久化/溢出到
并从磁盘访问,因为接收端执行反序列化。事实上,无论何时使用 Delta Propagation,都必须在接收端对对象进行反序列化,以便应用 “delta”。Apache Geode 适用
deltas 的org.apache.geode.Delta
接口。显然,你不能
在序列化对象上调用方法。
PDX
另一方面,PDX 代表便携式数据交换,它保留了发送数据的形式。
例如,如果客户端以 PDX 格式将数据发送到服务器,则服务器会将数据保留为 PDX 序列化字节
并将它们存储在缓存中Region
数据访问作是其目标。
此外,PDX,顾名思义,是“可移植的”,这意味着它支持 Java 和本地语言客户端。 例如 C、C++ 和 C# 客户端,以对同一数据集进行互作。
PDX 甚至允许对序列化的字节执行 OQL 查询,而不会导致对象被反序列化 首先,以便评估查询谓词并执行查询。这可以从 Apache Geode 开始实现 维护一个 “Type Registry”,其中包含被序列化和存储的对象的类型元数据 使用 PDX 的 Apache Geode。
但是,可移植性确实有成本,其开销略高于数据序列化。尽管如此,PDX 还很遥远 比 Java 序列化更高效、更灵活,Java 序列化将类型元数据存储在对象的序列化字节中 而不是像 Apache Geode 在使用 PDX 时那样在单独的类型注册表中。
PDX 不支持 Delta。从技术上讲,PDX 可序列化对象可以通过实现
这org.apache.geode.Delta
接口,并且只有 “delta” 会是
发送的,即使在 PDX 的上下文中也是如此。但是,必须反序列化 PDX 序列化对象才能应用增量。
请记住,调用一个方法来应用 delta,这首先违背了使用 PDX 的目的。
在开发管理 {data-store-name} 集群中数据的 Native Client(例如 C)时,甚至在混合 具有 Java 客户端的 Native Client,通常不会在 Classpath 上提供任何关联的 Java 类型 集群中 的服务器。使用 PDX,无需在 Classpath 上提供 Java 类型,并且许多 仅开发和使用 Native Client 来访问存储在 {data-store-name} 中的数据的用户将不会提供任何 Java 类型。
Apache Geode 还支持序列化为 PDX 或从 PDX 序列化的 JSON。在这种情况下,Java 类型很可能不会 在服务器 Classpath 上提供,因为支持 JSON 的许多不同语言(例如 JavaScript、Python、Ruby)可以是 与 Apache Geode 一起使用。
尽管如此,即使 PDX 正在运行,用户也必须注意不要在集群中的服务器上导致 PDX 序列化对象 进行反序列化。
例如,考虑对序列化为 PDX...
@Region("People")
class Person {
private LocalDate birthDate;
private String name;
public int getAge() {
// no explicit 'age' field/property in Person
// age is just implemented in terms of the 'birthDate' field
}
}
随后,如果 OQL 查询调用Person
对象,例如:
SELECT * FROM /People p WHERE p.age >= 21
然后,这将导致 PDX 序列化Person
对象进行反序列化,因为age
不是Person
,
而是一个包含基于另一个字段Person
(即birthDate
).同样,调用
任何java.lang.Object
方法,例如Object.toString()
将导致反序列化发生
也。
Apache Geode 确实提供了read-serialized
配置设置,以便任何缓存Region.get(key)
可能在Function
不会导致 PDX 序列化对象被反序列化。但是,没有什么能阻止构思不周的 OQL 查询
导致反序列化,所以要小心。
数据序列化 + PDX + Java 序列化
Apache Geode 可以同时支持所有 3 种序列化格式。
例如,您的应用程序域模型可能包含实现java.io.Serialiable
接口
并且您可能正在使用 Data Serialization 框架和 PDX 的组合。
虽然可以将 Java 序列化与 Data Serialization 和 PDX 一起使用,但通常更可取 ,建议使用 1 个序列化策略。 |
与 Java 序列化不同,数据序列化和 PDX 序列化不处理对象图周期。 |
有关 Apache Geode 序列化机制的更多背景信息,请参阅此处。
3.6.2. 使用 Spring Session 进行序列化
以前,Spring Session for Apache Geode 仅支持 Apache Geode 数据序列化格式。主要的 这背后的动机是利用 Apache Geode 的 Delta Propagation 功能,因为 Session 的 state 可以是任意大的。
但是,从 Spring Session for Apache Geode 2.0 开始,PDX 也受支持,现在是新的默认序列化 选择。在 Spring Session for Apache Geode 2.0 中,默认值更改为 PDX,主要是因为 PDX 是最 用户广泛使用和请求的格式。
PDX 无疑是最灵活的格式,以至于您甚至不需要 Spring Session for Apache Geode 或其对集群中服务器的 Classpath 的任何传递依赖项,以使用 Spring Session Apache Geode 的 Apache。事实上,使用 PDX,您甚至不需要将应用程序域对象类型存储在 服务器的 Classpath 上的 (HTTP) Session。
实质上,在使用 PDX 序列化时,Apache Geode 不需要存在关联的 Java 类型 在服务器的 Classpath 上。只要集群中的服务器上没有发生反序列化,您就是安全的。
这@EnableGemFireHttpSession
annotation 引入了新的 sessionSerializerBeanName
属性,该属性将用户
可用于配置在 Spring 容器中声明和注册的 bean 的名称,该 bean 实现了所需的
序列化策略。Spring Session for Apache Geode 使用序列化策略进行序列化
Session 状态。
Spring Session for Apache Geode 提供 2 种开箱即用的序列化策略:1 种用于 PDX,1 种用于数据序列化。它会自动在 Spring 容器中注册两个序列化策略 bean。 但是,这些策略中只有 1 种在运行时实际使用,即 PDX!
在实现数据序列化和 PDX 的 Spring 容器中注册的 2 个 bean 被命名为SessionDataSerializer
和SessionPdxSerializer
分别。默认情况下,sessionSerializerBeanName
属性
设置为SessionPdxSerializer
,就好像用户注释了他/她的 Spring Boot、启用了 Spring Session 的应用程序一样
configuration 类替换为:
@SpringBootApplication
@EnableGemFireHttpSession(sessionSerializerBeanName = "SessionPdxSerializer")
class MySpringSessionApplication { }
将序列化策略更改为 Data Serialization 是一件简单的事情,只需将sessionSerializerBeanName
属性设置为SessionDataSerializer
如下:
@SpringBootApplication
@EnableGemFireHttpSession(sessionSerializerBeanName = "SessionDataSerializer")
class MySpringSessionApplication { }
由于这两个值非常常见,因此 Spring Session for Apache Geode 为GemFireHttpSessionConfiguration
类:GemFireHttpSessionConfiguration.SESSION_PDX_SERIALIZER_BEAN_NAME
和GemFireHttpSessionConfiguration.SESSION_DATA_SERIALIZER_BEAN_NAME
.因此,您可以显式配置 PDX,
如下:
import org.springframework.session.data.geode.config.annotation.web.http.GemFireHttpSessionConfiguration;
@SpringBootApplication
@EnableGemFireHttpSession(sessionSerializerBeanName = GemFireHttpSessionConfiguration.SESSION_PDX_SERIALIZER_BEAN_NAME)
class MySpringSessionApplication { }
使用 1 个属性和 2 个开箱即用的 bean 定义,您可以指定所需的序列化框架 与由 Apache Geode 支持的支持 Spring Session 的 Spring Boot 应用程序一起使用。
3.6.3. Spring Session for Apache Geode 序列化框架
为了抽象出 Apache Geode 的数据序列化和 PDX 序列化框架的细节, Spring Session for Apache Geode 提供了自己的序列化框架(门面),将 Apache Geode 的 序列化框架。
序列化 API 位于org.springframework.session.data.gemfire.serialization
包。主要
接口是org.springframework.session.data.gemfire.serialization.SessionSerializer
.
接口定义为:
SessionSerializer
接口interface SessionSerializer<T, IN, OUT> {
void serialize(T session, OUT out);
T deserialize(IN in);
boolean canSerialize(Class<?> type);
boolean canSerialize(Object obj) {
// calls Object.getClass() in a null-safe way and then calls and returns canSerialize(:Class)
}
}
基本上,该接口允许你序列化和反序列化 SpringSession
对象。
这IN
和OUT
类型参数和这些类型的相应方法参数提供对对象的引用
负责编写Session
转换为字节流或读取Session
从字节流中。实际的
参数将特定于类型,具体取决于配置的基础 Apache Geode 序列化策略。
例如,当使用 Apache Geode 的 PDX 序列化框架时,IN
和OUT
将是org.apache.geode.pdx.PdxReader
和org.apache.geode.pdx.PdxWriter
分别。配置 Apache Geode 的数据序列化框架后,则IN
和OUT
将是java.io.DataInput
和java.io.DataOutput
分别。
这些参数提供给SessionSerializer
implementation 和
前面提到的是基于配置的底层 Apache Geode 序列化策略。
从本质上讲,尽管 Spring Session for Apache Geode 为 Apache Geode 的 序列化框架,在后台 Apache Geode 仍然需要这些序列化框架之一 用于将数据序列化到 Apache Geode 或从 Apache Geode 序列化数据。
那么SessionSerializer
接口真的有用吗?
实际上,它允许用户自定义 Session 状态的哪些方面实际被序列化和存储
在 Apache Geode 中。应用程序开发人员可以提供自己的自定义、特定于应用程序的SessionSerializer
实现,在 Spring 容器中将其注册为 Bean,然后将其配置为由 Spring Session 使用
用于序列化 Session 状态,如下所示:
@EnableGemFireHttpSession(sessionSerializerBeanName = "MyCustomSessionSerializer")
class MySpringSessionDataGemFireApplication {
@Bean("MyCustomSessionSerializer")
SessionSerializer<Session, ?, ?> myCustomSessionSerializer() {
// ...
}
}
实现 SessionSerializer
Spring Session for Apache Geode 在用户想要实现自定义SessionSerializer
它适合 Apache Geode 的序列化框架之一。
如果用户只是实现org.springframework.session.data.gemfire.serialization.SessionSerializer
接口
直接扩展,而无需从 Spring Session for Apache Geode 提供的抽象基类之一扩展,相关的
添加到 Apache Geode 的 Serialization 框架之一,则 Spring Session for Apache Geode 会将用户的
习惯SessionSerializer
在org.springframework.session.data.gemfire.serialization.pdx.support.PdxSerializerSessionSerializerAdapter
并将其注册为 Apache Geode 的org.apache.geode.pdx.PdxSerializer
.
Spring Session for Apache Geode 小心翼翼地避免STOMP踏任何现有的PdxSerializer
实现,即用户
可能已经通过其他方式向 Apache Geode 注册。事实上,有几种不同的,只要
Apache Geode 的org.apache.geode.pdx.PdxSerializer
interface 存在:
-
Apache Geode 本身提供了
org.apache.geode.pdx.ReflectionBasedAutoSerializer
. -
Spring Data for Apache Geode (SDG) 提供了
org.springframework.data.gemfire.mapping.MappingPdxSerializer
, 它用于 SD 存储库抽象和 SDG 的扩展,以处理将 PDX 序列化类型映射到 在应用程序存储库界面中定义的应用程序域对象类型。
这是通过获取任何当前注册的PdxSerializer
实例并组合它
使用PdxSerializerSessionSerializerAdapter
包装用户的自定义应用程序SessionSerializer
实现并重新注册此 “复合" PdxSerializer
在 Apache Geode 缓存上。“复合"
PdxSerializer
实现由 Spring Session for Apache Geode 的org.springframework.session.data.gemfire.pdx.support.ComposablePdxSerializer
类
当实体作为 PDX 存储在 Apache Geode 中时。
如果没有其他PdxSerializer
当前已注册到 Apache Geode 缓存,则适配器
只是注册了。
当然,您可以强制使用与自定义SessionSerializer
通过执行以下 1 项作来实现:
-
自定义
SessionSerializer
实现可以实现 Apache Geode 的org.apache.geode.pdx.PdxSerializer
接口,或者为方便起见,扩展 Spring Session for Apache Geode 的org.springframework.session.data.gemfire.serialization.pdx.AbstractPdxSerializableSessionSerializer
类 Spring Session for Apache Geode 将注册自定义SessionSerializer
作为PdxSerializer
与 Apache Geode 一起使用。 -
自定义
SessionSerializer
implementation 可以扩展 Apache Geode 的org.apache.geode.DataSerializer
类,或者为了方便起见,扩展 Spring Session for Apache Geode 的org.springframework.session.data.gemfire.serialization.data.AbstractDataSerializableSessionSerializer
类 Spring Session for Apache Geode 将注册自定义SessionSerializer
作为DataSerializer
与 Apache Geode 一起使用。 -
最后,用户可以创建自定义
SessionSerializer
implementation 一样,不指定哪个 Apache Geode 序列化框架,因为自定义SessionSeriaizer
implementation 未实现 任何 Apache Geode 序列化接口或从 Spring Session for Apache Geode 提供的任何 抽象基类,并且仍将其在 Apache Geode 中注册为DataSerializer
通过声明 其他 Spring Session for Apache Geode bean 在 Spring 容器中的类型为org.springframework.session.data.gemfire.serialization.data.support.DataSerializerSessionSerializerAdapter
这样。。。
@EnableGemFireHttpSession(sessionSerializerBeanName = "customSessionSerializer")
class Application {
@Bean
DataSerializerSessionSerializerAdapter dataSerializerSessionSerializer() {
return new DataSerializerSessionSerializerAdapter();
}
@Bean
SessionSerializer<Session, ?, ?> customSessionSerializer() {
// ...
}
}
仅凭DataSerializerSessionSerializerAdapter
在 Spring 容器中注册为 Bean,
任何中立自定义SessionSerializer
implementation 将被处理并注册为DataSerializer
在 Apache Geode 中。
对数据序列化的额外支持
如果您正在配置和引导 Apache Geode 服务器,请随时跳过本节 在您的集群中使用 Spring (Boot),因为通常以下信息将不适用。答案是肯定的 这完全取决于你声明的依赖项和 Spring 配置。但是,如果您使用 Gfsh 启动集群中的服务器,那么请务必继续阅读。 |
背景
使用 Apache Geode 的 DataSerialization 框架时,尤其是在序列化 (HTTP) 会话时从客户端 状态添加到集群中的服务器,则必须注意在集群中配置 Apache Geode 服务器 替换为适当的依赖项。如前一节所述,在利用增量时尤其如此 在 Data Serialization 上。
当使用 DataSerialization 框架作为序列化策略来序列化 (HTTP) 会话状态时 你的 Web 应用程序客户端连接到服务器,那么服务器必须正确地配置 Spring Session ,用于表示 (HTTP) 会话及其内容的 Apache Geode 类类型。这意味着包括 服务器 Classpath 上的 Spring JAR。
此外,使用 DataSerialization 可能还需要包含包含应用程序域的 JAR 类,这些类由 Web 应用程序使用,并作为 Session Attribute 值放入 (HTTP) Session 中, 特别是在以下情况下:
-
您的类型实现
org.apache.geode.DataSerializable
接口。 -
您的类型实现
org.apache.geode.Delta
接口。 -
您已注册了
org.apache.geode.DataSerializer
,用于标识和序列化类型。 -
您的类型实现
java.io.Serializable
接口。
当然,您必须确保放置在 (HTTP) Session 中的应用程序域对象类型在某些 形式或其他形式。但是,并非严格要求您使用 DataSerialization,也不必如此 在以下情况下,需要将应用程序域对象类型放在 servers 类路径上:
-
您的类型实现
org.apache.geode.pdx.PdxSerializable
接口。 -
或者,您已经注册了
org.apache.geode.pdx.PdxSerializer
正确识别和序列化 您的应用程序域对象类型。
Apache Geode 在确定要使用的序列化策略时,将应用以下优先顺序 要序列化对象图:
-
第一
DataSerializable
对象和/或任何已注册的DataSerializers
标识要序列化的对象。 -
然后
PdxSerializable
对象和/或任何已注册的PdxSerializer
标识要序列化的对象。 -
最后,所有
java.io.Serializable
类型。
这也意味着,如果特定的应用程序域对象类型(例如A
) 实现java.io.Serializable
,
但是,A (自定义)PdxSerializer
已在 Apache Geode 中注册,以标识相同的应用程序
domain 对象类型(即A
),则 Apache Geode 将使用 PDX 来序列化 “A” 而不是 Java 序列化,
在这种情况下。
这特别有用,因为您可以使用 DataSerialization 来序列化 (HTTP) Session 对象,利用 增量和 DataSerialization 的所有强大功能,但随后使用 PDX 序列化应用程序域对象 类型,这大大简化了所涉及的配置和/或工作。
现在我们已经大致了解了为什么存在这种支持,您如何启用它?
配置
首先,创建 Apache Geodecache.xml
如下:
cache.xml
配置<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="http://geode.apache.org/schema/cache"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://geode.apache.org/schema/cache https://geode.apache.org/schema/cache/cache-1.0.xsd"
version="1.0">
<initializer>
<class-name>
org.springframework.session.data.gemfire.serialization.data.support.DataSerializableSessionSerializerInitializer
</class-name>
</initializer>
</cache>
然后,在 *Gfsh* 中使用以下命令启动您的服务器:
gfsh> start server --name=InitializedServer --cache-xml-file=/path/to/cache.xml --classpath=...
配置 Apache Geode 服务器classpath
使用适当的依赖项是棘手的部分,
但一般来说,以下内容应该有效:
gfsh> set variable --name=REPO_HOME --value=${USER_HOME}/.m2/repository
gfsh> start server ... --classpath=\
${REPO_HOME}/org/springframework/spring-core/{spring-version}/spring-core-{spring-version}.jar\
:${REPO_HOME}/org/springframework/spring-aop/{spring-version}/spring-aop-{spring-version}.jar\
:${REPO_HOME}/org/springframework/spring-beans/{spring-version}/spring-beans-{spring-version}.jar\
:${REPO_HOME}/org/springframework/spring-context/{spring-version}/spring-context-{spring-version}.jar\
:${REPO_HOME}/org/springframework/spring-context-support/{spring-version}/spring-context-support-{spring-version}.jar\
:${REPO_HOME}/org/springframework/spring-expression/{spring-version}/spring-expression-{spring-version}.jar\
:${REPO_HOME}/org/springframework/spring-jcl/{spring-version}/spring-jcl-{spring-version}.jar\
:${REPO_HOME}/org/springframework/spring-tx/{spring-version}/spring-tx-{spring-version}.jar\
:${REPO_HOME}/org/springframework/data/spring-data-commons/{spring-data-commons-version}/spring-data-commons-{spring-data-commons-version}.jar\
:${REPO_HOME}/org/springframework/data/spring-data-geode/{spring-data-geode-version}/spring-data-geode-{spring-data-geode-version}.jar\
:${REPO_HOME}/org/springframework/session/spring-session-core/{spring-session-core-version}/spring-session-core-{spring-session-core-version}.jar\
:${REPO_HOME}/org/springframework/session/spring-session-data-geode/{spring-session-data-geode-version}/spring-session-data-geode-{spring-session-data-geode-version}.jar\
:${REPO_HOME}/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar
请记住,您可能还需要将应用程序域对象 JAR 文件添加到服务器 Classpath 中。
要全面了解其工作原理,请参阅示例。
自定义变化检测
默认情况下,每当 Session 被修改时(例如lastAccessedTime
更新为当前时间),则 Session
被 Spring Session for Apache Geode (SSDG) 视为脏的。在使用 Apache Geode 数据序列化框架时,利用 Apache Geode 的增量传播功能也非常有用和有价值。
使用数据序列化时,SSDG 还使用增量传播仅发送对 Session 状态的更改 客户端和服务器。这包括可能已添加、删除或更新的任何 Session 属性。
默认情况下,随时Session.setAttribute(name, value)
时,Session 属性被视为 “dirty”
,并将在 Client 端和 Server 之间的 delta 中发送。即使您的应用程序域对象
未更改。
通常,从来没有理由调用Session.setAttribute(..)
除非您的对象已更改。然而
如果发生这种情况,并且您的对象相对较大(具有复杂的对象层次结构),则可能需要
请考虑以下任一内容:
-
在应用程序域对象中实现 Delta 接口 模型虽然有用,但侵入性很强,或者......
-
提供 SSDG 的自定义实现
org.springframework.session.data.gemfire.support.IsDirtyPredicate
strategy 界面。
SSDG 提供了 5 种开箱即用的IsDirtyPredicate
策略界面:
类 | 描述 | 违约 |
---|---|---|
|
新的 Session 属性值始终被视为脏。 |
|
|
新的 Session 属性值永远不会被视为脏。 |
|
|
当旧值和新值
不同,如果新值的 type 没有实现 |
是的 |
|
如果旧值不等于
新值由 |
|
|
如果旧值与
使用标识等于运算符的新值(即 |
如上表所示,DeltaAwareDirtyPredicate
是 SSDG 使用的默认实现。
这DeltaAwareDirtyPredicate
自动考虑实现
Apache GeodeDelta
接口。然而DeltaAwareDirtyPredicate
即使您的应用程序
domain 对象不实现Delta
接口。SSDG 会将您的应用程序域对象视为脏
任何时候Session.setAttribute(name, newValue)
如果新值与旧值不同,则调用
或新值未实现Delta
接口。
您只需在 Spring 容器中声明一个 bean 即可更改 SSDG 的脏实现、确定策略
的IsDirtyPredicate
接口类型:
IsDirtyPredicate
策略@EnableGemFireHttpSession
class ApplicationConfiguration {
@Bean
IsDirtyPredicate equalsDirtyPredicate() {
return EqualsDirtyPredicate.INSTANCE;
}
}
组成
这IsDirtyPredicate
interface 还提供了andThen(:IsDirtyPredicate)
和orThen(:IsDirtyPredicate)
方法
编写 2 个或更多IsDirtyPredicate
实现,以便组织复杂的逻辑和规则
用于确定应用程序域对象是否脏。
例如,您可以将EqualsDirtyPredicate
和DeltaAwareDirtyPredicate
使用 OR 运算符:
EqualsDirtyPredicate
跟DeltaAwareDirtyPredicate
使用逻辑 OR 运算符@EnableGemFireHttpSession
class ApplicationConfiguration {
@Bean
IsDirtyPredicate equalsOrThenDeltaDirtyPredicate() {
return EqualsDirtyPredicate.INSTANCE
.orThen(DeltaAwareDirtyPredicate.INSTANCE);
}
}
您甚至可以实现自己的自定义IsDirtyPredicates
基于特定的应用程序域对象类型:
IsDirtyPredicate
实现class CustomerDirtyPredicate implements IsDirtyPredicate {
public boolean isDirty(Object oldCustomer, Object newCustomer) {
if (newCustomer instanceof Customer) {
// custom logic to determine if a new Customer is dirty
}
return true;
}
}
class AccountDirtyPredicate implements IsDirtyPredicate {
public boolean isDirty(Object oldAccount, Object newAccount) {
if (newAccount instanceof Account) {
// custom logic to determine if a new Account is dirty
}
return true;
}
}
然后结合CustomerDirtyPredicate
使用AccountDirtyPredicate
以及 fallback 的默认谓词,如下所示:
IsDirtyPredicates
@EnableGemFireHttpSession
class ApplicationConfiguration {
@Bean
IsDirtyPredicate typeSpecificDirtyPredicate() {
return new CustomerDirtyPredicate()
.andThen(new AccountDirtyPredicate())
.andThen(IsDirtyPredicate.ALWAYS_DIRTY);
}
}
组合和可能性是无穷无尽的。
实施自定义时要小心IsDirtyPredicate 策略。如果您错误地确定
application domain 对象在实际脏时不是脏的,则不会在 Session delta 中发送
从客户端到服务器。 |
更改 Session 表示
在内部,Spring Session for Apache Geode 维护 (HTTP) Session 和 Session 的 属性。每种表示形式都基于是否支持 Apache Geode“增量”。
由于前面讨论的原因,在使用数据序列化时,只有 Spring Session for Apache Geode 才会启用 Apache Geode 增量传播。
实际上,该策略是:
-
如果配置了 Apache Geode 数据序列化,则支持增量,并且
DeltaCapableGemFireSession
和DeltaCapableGemFireSessionAttributes
使用表示。 -
如果配置了 Apache Geode PDX 序列化,则将禁用增量传播 和
GemFireSession
和GemFireSessionAttributes
使用表示。
可以覆盖 Spring Session for Apache Geode 和用户使用的这些内部表示
来提供自己的 Session 相关类型。唯一严格的要求是 Session 实现
必须实现核心 Spring Sessionorg.springframework.session.Session
接口。
举个例子,假设你想定义自己的 Session 实现。
首先,定义Session
类型。也许您的自定义Session
type 甚至封装并处理 Session
属性,而不必定义单独的类型。
class MySession implements org.springframework.session.Session {
// ...
}
然后,您需要扩展org.springframework.session.data.gemfire.GemFireOperationsSessionRepository
类
并覆盖createSession()
创建自定义实例的方法Session
implementation 类。
class MySessionRepository extends GemFireOperationsSessionRepository {
@Override
public Session createSession() {
return new MySession();
}
}
如果您提供自己的自定义SessionSerializer
implementation 和 Apache Geode PDX 序列化是
configured,然后您完成了。
但是,如果您配置了 Apache Geode 数据序列化,则必须另外提供自定义
实现SessionSerializer
接口,并让它直接扩展 Apache Geode 的org.apache.geode.DataSerializer
类,或扩展 Spring Session for Apache Geode 的org.springframework.session.data.gemfire.serialization.data.AbstractDataSerializableSessionSerializer
类
并覆盖getSupportedClasses():Class<?>[]
方法。
例如:
class MySessionSerializer extends AbstractDataSerializableSessionSerializer {
@Override
public Class<?>[] getSupportedClasses() {
return new Class[] { MySession.class };
}
}
不幸getSupportedClasses()
无法返回通用的 Spring Sessionorg.springframework.session.Session
interface 类型。如果可以,那么我们可以避免显式地覆盖getSupportedClasses()
method 开启
定制DataSerializer
实现。但是,Apache Geode 的数据序列化框架只能匹配
在确切的类类型上,因为它错误地在内部存储并按名称引用类类型,然后
要求用户覆盖并实现getSupportedClasses()
方法。
3.7. HttpSession 集成的工作原理
幸运的是,两者都javax.servlet.http.HttpSession
和javax.servlet.http.HttpServletRequest
(用于
获取HttpSession
) 是接口。这意味着我们可以为每个 API 提供自己的实现。
本节描述了 Spring Session 如何提供与javax.servlet.http.HttpSession .
其目的是让用户了解后台发生的事情。此功能已实现
和 integrated 的,因此您无需自己实现此 logic。 |
首先,我们创建一个自定义javax.servlet.http.HttpServletRequest
,它返回javax.servlet.http.HttpSession
.它看起来像下面这样:
public class SessionRepositoryRequestWrapper extends HttpServletRequestWrapper {
public SessionRepositoryRequestWrapper(HttpServletRequest original) {
super(original);
}
public HttpSession getSession() {
return getSession(true);
}
public HttpSession getSession(boolean createNew) {
// create an HttpSession implementation from Spring Session
}
// ... other methods delegate to the original HttpServletRequest ...
}
任何返回javax.servlet.http.HttpSession
被覆盖。所有其他方法都是由javax.servlet.http.HttpServletRequestWrapper
并简单地委托给原始javax.servlet.http.HttpServletRequest
实现。
我们将javax.servlet.http.HttpServletRequest
使用 Servlet 的实现Filter
叫SessionRepositoryFilter
.伪代码可以在下面找到:
public class SessionRepositoryFilter implements Filter {
public doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
HttpServletRequest httpRequest = (HttpServletRequest) request;
SessionRepositoryRequestWrapper customRequest = new SessionRepositoryRequestWrapper(httpRequest);
chain.doFilter(customRequest, response, chain);
}
// ...
}
通过传入自定义javax.servlet.http.HttpServletRequest
implementation 导入到FilterChain
我们确保
在我们的Filter
使用自定义的javax.servlet.http.HttpSession
实现。
这凸显了为什么 Spring Session 的SessionRepositoryFilter
必须放在任何内容之前
它与javax.servlet.http.HttpSession
.
3.8. HttpSession监听器
Spring Session 支持HttpSessionListener
通过翻译SessionCreatedEvent
和SessionDestroyedEvent
到HttpSessionEvent
通过声明SessionEventHttpSessionListenerAdapter
.
要使用此支持,您需要:
-
确保您的
SessionRepository
implementation 支持并配置为触发SessionCreatedEvent
和 'SessionDestroyedEvent' 的 Package。 -
配置
SessionEventHttpSessionListenerAdapter
作为 Spring bean 进行。 -
注入每个
HttpSessionListener
到SessionEventHttpSessionListenerAdapter
如果您将 HttpSession 中记录的配置支持与 Apache Geode 结合使用,
然后您需要做的就是注册每个HttpSessionListener
作为 Bean 进行。
例如,假设您希望支持 Spring Security 的并发控制,并且需要使用HttpSessionEventPublisher
,
然后您只需添加HttpSessionEventPublisher
作为 Bean 进行。
3.10. SessionRepository
一个SessionRepository
负责创建、持久化和访问Session
instances 和 state 的
如果可能,开发人员不应直接与SessionRepository
或Session
.相反,开发人员
应该更愿意与SessionRepository
和Session
间接通过javax.servlet.http.HttpSession
,WebSocket
和WebSession
集成。
3.11. FindByIndexNameSessionRepository
Spring Session 最基本的 API 用于使用Session
是SessionRepository
.API 故意非常简单
这样就很容易提供具有基本功能的其他 implementations。
一些SessionRepository
实现可以选择实现FindByIndexNameSessionRepository
也。
例如,Spring Session 的 Apache Geode 支持实现了FindByIndexNameSessionRepository
.
这FindByIndexNameSessionRepository
添加单个方法以查找特定用户的所有会话。
这是通过确保名称为FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME
中填充了用户名。开发人员有责任确保填充该属性,因为
Spring Session 不知道正在使用的身份验证机制。
的一些 implementation |
3.12. 启用 SpringHttpSession
这@EnableSpringHttpSession
注释可以添加到任何@Configuration
类来公开SessionRepositoryFilter
作为 Spring 容器中名为“springSessionRepositoryFilter”的 Bean。
为了利用注释,单个SessionRepository
bean 的 bean 中。
3.13. 启用 GemFireHttpSession
这@EnableGemFireHttpSession
注释可以添加到任何@Configuration
类代替@EnableSpringHttpSession
注解来公开SessionRepositoryFilter
作为 Spring 容器中名为
“springSessionRepositoryFilter”,并将 Apache Geode 定位为管理javax.servlet.http.HttpSession
州。
使用@EnableGemFireHttpSession
注解中,额外的配置是开箱即用的,并且
提供了SessionRepository
interface 名称为GemFireOperationsSessionRepository
.
3.14. GemFireOperationsSessionRepository
GemFireOperationsSessionRepository
是一个SessionRepository
使用 Spring Session 实现的实现
适用于 Apache Geode's_GemFireOperationsSessionRepository
.
在 Web 环境中,此存储库与SessionRepositoryFilter
.
此实现支持SessionCreatedEvents
,SessionDeletedEvents
和SessionDestroyedEvents
通过SessionEventHttpSessionListenerAdapter
.
3.14.1. 在 Apache Geode 中使用索引
虽然有关正确定义对 Apache Geode 性能有积极影响的索引的最佳实践 超出了本文档的范围,重要的是要认识到 Spring Session for Apache Geode 会创建 并使用 Indexes 高效地查询和查找 Sessions。
Spring Session for Apache Geode 在主体名称上创建 1 个哈希类型的索引。有两个
用于查找 Principal Name 的不同内置策略。第一个策略是 Session 的值
属性,名称为FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME
将被索引为相同的
索引名称。
例如:
String indexName = FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME;
session.setAttribute(indexName, username);
Map<String, Session> idToSessions =
this.sessionRepository.findByIndexNameAndIndexValue(indexName, username);
3.14.2. 在 Apache Geode 和 Spring Security 中使用索引
或者,Spring Session for Apache Geode 将映射 Spring Security 的当前Authentication#getName()
自
索引FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME
.
例如,如果您使用的是 Spring Security,则可以使用以下方法查找当前用户的会话:
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
String indexName = FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME;
Map<String, Session> idToSessions =
this.sessionRepository.findByIndexNameAndIndexValue(indexName, authentication.getName());
3.14.3. 在 Apache Geode 中使用自定义索引
这使开发人员能够使用GemFireOperationsSessionRepository
以编程方式查询并查找所有会话
有效地使用给定的主体名称。
此外,Spring Session for Apache Geode 将在实现 Session 的
地图类型attributes
属性(即在任何任意 Session 属性上),当开发人员标识 1 个或多个
命名的 Session 属性,这些属性应由 Apache Geode 编制索引。
要索引的 Sessions 属性可以使用indexableSessionAttributes
属性@EnableGemFireHttpSession
注解。开发人员将此注释添加到他们的 Spring 应用程序中@Configuration
类,当他/她希望启用 Spring Session 对HttpSession
支持
Apache Geode 的 Apache。
String indexName = "name1";
session.setAttribute(indexName, indexValue);
Map<String, Session> idToSessions =
this.sessionRepository.findByIndexNameAndIndexValue(indexName, indexValue);
仅在@EnableGemFireHttpSession 注解的indexableSessionAttributes 属性将定义一个 Index。不会为所有其他 Session 属性编制索引。 |
但是,有一个问题。存储在可索引 Session 属性中的任何值都必须实现java.lang.Comparable<T>
接口。如果这些对象值未实现Comparable
,然后是 Apache Geode
将在启动时引发错误,当为具有持久 Session 数据的区域定义 Index 时,或者尝试
在运行时为可索引的 Session 属性分配一个不是Comparable
,并且 Session 已保存
到 Apache Geode。
任何未编入索引的 Session 属性都可以存储非Comparable 值。 |
要了解有关 Apache Geode 基于范围的索引的更多信息,请参阅在映射字段上创建索引。
要了解有关 Apache Geode 索引的一般信息,请参阅使用索引。