Spring Session for Apache Geode 教程

时间:2022-12-06 19:04:42

Spring Session for Apache Geode 教程

1. 简介

Spring 会话提供了用于管理用户会话信息的 API 和实现。 它还提供与以下各项的透明集成:

  • HttpSession- 使它能够被集群化(即复制) 实现高可用性),而无需绑定到特定于应用程序容器的解决方案。HttpSession
  • REST API - 允许在协议标头中提供会话 ID 以使用 RESTful API。
  • WebSocket - 提供在接收 WebSocket 消息时保持活动状态的能力。HttpSession
  • WebSession- 允许以应用程序容器中立的方式替换Spring WebFlux。WebSession

简而言之,Spring Session以应用程序容器中立的方式取代了应用程序容器 通过提供更常见和更健壮的会话实现支持。​​javax.servlet.http.HttpSession​​​​HttpSession​

2. 示例和指南(从这里开始)

如果您想从春季课程开始,最好的起点 与我们的示例应用程序一起使用。

Table 1. Sample Application using Spring Boot

描述

指导

带有Spring Boot和Apache Geode的HttpSession

演示如何使用 Spring 会话在 Spring Boot 应用程序中使用 Apache Geode 进行管理 使用客户端/服务器拓扑。​​HttpSession​

带有 Spring Boot 和 Apache Geode Guide 的 HttpSession

HttpSession with Spring Boot 和 Apache Geode using Gfsh

演示如何使用 Spring 会话在 Spring Boot 应用程序中使用 Apache Geode 进行管理 使用客户端/服务器拓扑。此外,还配置和使用Apache Geode的DataSerialization框架。​​HttpSession​

HttpSession with Spring Boot and Apache Geode using Gfsh Guide

HttpSession with Spring Boot 和 Apache Geode using Scoped Proxies

演示如何使用 Spring 会话在 Spring Boot 应用程序中使用 Apache Geode 进行管理 使用客户端/服务器拓扑。该应用程序还使用 Spring 请求和会话范围的代理 bean。​​HttpSession​

HttpSession with Spring Boot and Apache Geode using Scoped Proxies Guide

Table 2. Sample Applications using Spring’s Java-based configuration

描述

指导

HttpSession with Apache Geode (Client/Server)

演示如何使用 Spring 会话通过客户端/服务器拓扑来管理 Apache Geode。​​HttpSession​

HttpSession with Apache Geode (Client/Server) Guide

HttpSession with Apache Geode (P2P)

演示如何使用春季会话通过 P2P 拓扑与 Apache Geode 进行管理。​​HttpSession​

HttpSession with Apache Geode (P2P) Guide

Table 3. Sample Applications using Spring’s XML-based configuration

描述

指导

HttpSession with Apache Geode (Client/Server)

演示如何使用 Spring 会话通过客户端/服务器拓扑来管理 Apache Geode。​​HttpSession​

HttpSession with Apache Geode (Client/Server) Guide

HttpSession with Apache Geode (P2P)

演示如何使用春季会话通过 P2P 拓扑与 Apache Geode 进行管理。​​HttpSession​

HttpSession with Apache Geode (P2P) Guide

3. 会话集成

春季会议提供透明的集成。这意味着开发人员 可以将实现替换为由 Spring 会话支持的实现。​​javax.servlet.http.HttpSession​​​​HttpSession​

Spring Session允许插入多个不同的数据存储提供程序(例如Apache Geode)。 为了管理状态。​​HttpSession​

3.1. 为什么是Spring Session和HttpSession?

我们已经提到春季会议提供了透明的集成,但是有什么好处 我们能摆脱困境吗?​​HttpSession​

  • HttpSession- 使它能够被集群化(即复制) 实现高可用性),而无需绑定到特定于应用程序容器的解决方案。HttpSession
  • REST API - 允许在协议标头中提供会话 ID 以使用 RESTful API。
  • WebSocket - 提供在接收 WebSocket 消息时保持活动状态的能力。HttpSession
  • WebSession- 允许以应用程序容器中立的方式替换Spring WebFlux。WebSession

3.2. 使用 Apache Geode 进行 HttpSession Management

当Apache​Geode 与 Spring Session 一起使用时,Web 应用程序的扫描将替换为由 Apache Geode 管理的集群实现 并使用春季会话的 API 方便地访问。javax.servlet.http.HttpSession

使用 Apache Geode 管理会话状态的两种最常见的拓扑包括:

  • 客户端-服务器
  • 点对点 (P2P)

此外,Apache Geode 支持使用WAN 拓扑进行站点到站点复制。 配置和使用Apache Geode的WAN功能的能力独立于Spring Session, 并且超出了本文档的范围。

有关使用 Spring Data for Apache Geode 配置 Apache Geode WAN 功能的更多详细信息 可以在这里找到。

3.2.1. Apache Geode 客户端-服务器

客户端-服务器拓扑可能是 在春季会话中使用Apache Geode作为提供程序时,用户中最常见的配置选择,因为 与应用程序相比,Apache Geode 服务器具有明显不同且独特的 JVM 堆要求。 使用客户端-服务器拓扑使应用程序能够独立管理(例如复制)应用程序状态 从其他应用程序进程。

在客户端-服务器拓扑中,使用 Spring 会话的应用程序将打开 1 个或多个到远程群集的连接 的 Apache Geode 服务器,这些服务器将管理对 allstate 的访问。HttpSession

您可以使用以下任一方式配置客户端-服务器拓扑:

  • 基于 Java 的配置
  • 基于 XML 的配置
Apache Geode Client-Server based Configuration

本节介绍如何将 Apache Geode 的客户端-服务器拓扑配置为管理状态 使用基于 Java 的配置。​​HttpSession​

HttpSession with Apache Geode(客户端-服务器)提供了一个工作示例,演示了如何 将Spring Session与Apache Geode集成,以使用Java配置进行管理状态。您可以阅读 通过下面的基本集成步骤,但建议您按照详细的“HttpSession”进行操作 与您自己的应用程序集成时使用 Apache Geode(客户端-服务器)指南。​​HttpSession​

Spring Java 配置

添加所需的依赖项和存储库声明后,我们可以创建 Spring 配置。 Spring 配置负责创建一个 Servlet,用 Spring Session 和 Apache Geode 支持的实现替换它。​​Filter​​​​HttpSession​

客户端配置

添加以下 Spring 配置:

@ClientCacheApplication(name = "SpringSessionDataGeodeJavaConfigSampleClient", logLevel = "error",
readTimeout = 15000, retryAttempts = 1, subscriptionEnabled = true)
@EnableGemFireHttpSession(poolName = "DEFAULT")
public class ClientConfig extends ClientServerIntegrationTestsSupport {

@Bean
ClientCacheConfigurer gemfireServerReadyConfigurer(
@Value("${spring.data.gemfire.cache.server.port:40404}") int cacheServerPort) {

return (beanName, clientCacheFactoryBean) -> waitForServerToStart("localhost", cacheServerPort);
}
}

首先,我们通过注释我们的类来声明我们的 Web 应用程序是 Apache Geode 缓存客户端。

跟。此外,我们调整了一些基本的“默认”设置(例如)。​​ClientConfig​​​​@ClientCacheApplication​​​​Pool​​​​readTimeout​

​@EnableGemFireHttpSession​​创建一个名为“实现”的春豆。过滤器替换为Spring Session提供的实现

并得到Apache Geode的支持。此外,该配置还将创建必要的客户端(默认情况下,“ClusteredSpringSessions”,即 a)对应于相同的服务器端名称。所有会话状态都通过数据访问操作从客户端发送到服务器。客户端使用“默认”。​​springSessionRepositoryFilter​​​​javax.servlet.Filter​​​​HttpSession​​​​Region​​​​PROXY​​​​Region​​​​Region​​​​Region​​​​Region​​​​Pool​

然后,我们等待确保Apache Geode服务器已启动并运行,然后再继续。这才真正有用

用于自动化(集成)测试目的。

在典型的 Apache Geode 生产部署中,集群可能包含数百或数千个 服务器(又称数据节点),客户端连接到 1 个或多个正在运行的 Apache Geode 定位器更为常见 在同一集群中。定位器将有关集群中可用服务器的元数据传递给客户端,单个 服务器负载以及哪些服务器具有感兴趣的客户端数据,这对于直接, 单跳数据访问和延迟敏感型应用程序。有关客户端/服务器部署的更多详细信息,请参阅 Apache Geode 用户指南。

有关配置 Spring 数据 Geode 的更多信息,请参阅参考指南。

注释使开发人员能够配置两个春季会话的某些方面 和使用以下属性的开箱即用的 Apache Geode:​​@EnableGemFireHttpSession​

  • ​clientRegionShortcut​​- 使用ClientRegionShortcut(默认为 )在客户端上指定 Apache Geode数据管理策略。此属性仅在配置客户端时使用。PROXYRegion
  • ​indexableSessionAttributes​​- 按名称标识应为查询目的编制索引的会话属性。 只有按名称显式标识的会话属性才会被编入索引。
  • ​maxInactiveIntervalInSeconds​​- 控制HttpSession空闲超时过期时间(默认为30 分钟)。
  • ​poolName​​- 用于将客户端连接到服务器群集的专用 Apache GeoDeused 的名称。 仅当应用程序是缓存客户端时才使用此属性。默认为。PoolgemfirePool
  • ​regionName​​- 指定用于存储和管理状态的 Apache GeoDeused 的名称 (默认为“集群春季会话”)。RegionHttpSession
  • ​serverRegionShortcut​​- 使用RegionShortcut(默认为 )在服务器上指定 Apache Geode数据管理策略。此属性仅在配置服务器时使用, 或者当采用 P2P 拓扑时。PARTITIONRegions

重要的是要记住,如果客户端是 aor,则 Apache Geode 客户端名称必须与同名的服务器匹配。客户端和服务器名称 如果用于存储会话状态的客户端是,则不需要匹配。但是,请记住 该会话状态将不会传播到服务器,您将失去使用Apache Geode的所有好处 在分布式服务器上存储和管理分布式复制的会话状态信息, 复制方式。​​Region​​​​Region​​​​Region​​​​PROXY​​​​CACHING_PROXY​​​​Region​​​​Region​​​​LOCAL​

服务器配置

到目前为止,我们只涵盖了等式的一面。我们还需要一个Apache Geode服务器供我们的缓存客户端通信 并将会话状态发送到服务器进行管理。

在此示例中,我们将使用以下 Java 配置来配置和运行 Apache Geode 服务器:

@CacheServerApplication(name = "SpringSessionDataGeodeJavaConfigSampleServer", logLevel = "error") 
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 30)
public class GemFireServer {

@SuppressWarnings("resource")
public static void main(String[] args) {
new AnnotationConfigApplicationContext(GemFireServer.class).registerShutdownHook();
}
}

首先,我们使用注释来简化对等缓存实例的创建

包含与 afor 缓存客户端连接。​​@CacheServerApplication​​​​CacheServer​

(可选)然后,对类进行注释以创建必要的

服务器端(默认情况下,“ClusteredSpringSessions”)用于存储状态。此步骤是

可选,因为会话可以手动创建,也许使用外部方式。使用方便快捷。​​GemFireServer​​​​@EnableGemFireHttpSession​​​​Region​​​​HttpSession​​​​Region​​​​@EnableGemFireHttpSession​

Apache Geode 客户端-服务器基于 XML 的配置

本节介绍如何将 Apache Geode 的客户端-服务器拓扑配置为管理状态 使用基于 XML 的配置。​​HttpSession​


​使用 XML 的 HttpSession with Apache Geode (Client-Server)​​提供了一个工作示例 演示如何使用XML将Spring Session与Apache Geode集成以管理状态 配置。您可以通读下面的集成基本步骤,但建议您遵循 在详细的“HttpSession”中使用 Apache Geode(客户端-服务器)使用 XML 指南与 您自己的应用程序。​​HttpSession​

弹簧 XML 配置

添加所需的依赖项和存储库声明后,我们可以创建 Spring 配置。 Spring 配置负责创建一个替换由 Spring Session 和 Apache Geode 支持的实现。​​Servlet​​​​Filter​​​​javax.servlet.http.HttpSession​

客户端配置

添加以下 Spring 配置:

<context:annotation-config/>

<context:property-placeholder/>

<bean class="sample.client.ClientServerReadyBeanPostProcessor"/>


<util:properties >
<prop key="log-level">${spring.data.gemfire.cache.log-level:error}</prop>
</util:properties>


<gfe:client-cache properties-ref="gemfireProperties" pool-name="gemfirePool"/>


<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>


<bean class="org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration"
p:poolName="DEFAULT"/>

(可选)首先,我们可以包含 abean 来配置 Apache GeodeusingPivotal GemFire 属性的某些方面。在这种情况下,我们只是

使用特定于应用程序的系统属性设置 Apache Geode 的“日志级别”,默认为“警告”如果未指定。​​Properties​​​​ClientCache​

我们必须创建一个 Apache Geode 的实例。我们用我们的初始化它。​​ClientCache​​​​gemfireProperties​

然后,我们配置 aof 连接以与客户端/服务器拓扑中的 Apache Geode 服务器通信。

在我们的配置中,我们对超时、连接数等使用合理的设置。此外,我们已经配置为直接连接到服务器(使用嵌套元素)。​​Pool​​​​Pool​​​​gfe:server​

最后,注册 abean 以启用春季会话功能。​​GemFireHttpSessionConfiguration​

在典型的 Apache Geode 生产部署中,集群可能包含数百或数千个 服务器(又称数据节点),客户端连接到 1 个或多个正在运行的 Apache Geode 定位器更为常见 在同一集群中。定位器将有关集群中可用服务器的元数据传递给客户端,单个 服务器负载以及哪些服务器具有感兴趣的客户端数据,这对于直接, 单跳数据访问和延迟敏感型应用程序。有关客户端/服务器部署的更多详细信息,请参阅 Apache Geode 用户指南。

有关为 Apache Geode 配置 Spring 数据的更多信息,请参阅参考指南。

服务器配置

到目前为止,我们只涵盖了等式的一面。我们还需要一个Apache Geode服务器供我们的缓存客户端通信 并将会话状态发送到服务器进行管理。

在此示例中,我们将使用以下 XML 配置来启动 Apache Geode 服务器:

<context:annotation-config/>

<context:property-placeholder/>


<util:properties >
<prop key="name">SpringSessionDataGeodeSampleXmlServer</prop>
<prop key="log-level">${spring.data.gemfire.cache.log-level:error}</prop>
</util:properties>


<gfe:cache properties-ref="gemfireProperties"/>


<gfe:cache-server port="${spring.data.gemfire.cache.server.port:40404}"/>


<bean class="org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration"
p:maxInactiveIntervalInSeconds="30"/>

(可选)首先,我们可以使用Pivotal GemFire 属性包含 abean 来配置 Apache Geode 对等的某些方面。在这种情况下,我们只是

使用特定于应用程序的系统属性设置 Apache Geode 的“日志级别”,默认为“警告”如果未指定。​​Properties​​​​Cache​

我们必须配置一个Apache Geode对等实例。我们使用 Apache Geode 属性初始化它。​​Cache​

接下来,我们定义一个由缓存客户端使用的合理配置

用于连接到服务器并发送会话状态的应用程序。​​CacheServer​​​​bind-address​​​​port​

最后,我们启用我们在客户端 XML 配置中声明的相同 Spring 会话功能

通过注册一个实例,除了我们设置的会话过期超时到30 秒。稍后我们将解释这意味着什么。​​GemFireHttpSessionConfiguration​

Apache Geode 服务器通过以下方式引导:

@Configuration 
@ImportResource("META-INF/spring/session-server.xml")
public class GemFireServer {

public static void main(String[] args) {
new AnnotationConfigApplicationContext(GemFireServer.class).registerShutdownHook();
}
}

与其使用 amethod定义一个简单的 Java 类,不如考虑使用 Spring Boot 来代替。​​main​

Theannotation 将此 Java 类指定为 Spring 配置元数据的来源,使用

7.9. 基于注释的容器配置[Spring 的注释配置支持]。​​@Configuration​

主要,配置来自文件。​​META-INF/spring/session-server.xml​

XML Servlet 容器初始化

我们的Spring XML 配置创建了一个名为 Spring bean 的实现接口。底豆负责更换 使用Spring Session和Apache Geode提供的自定义实现。​​springSessionRepositoryFilter​​​​javax.servlet.Filter​​​​springSessionRepositoryFilter​​​​javax.servlet.http.HttpSession​

为了让我们的魔力发挥,我们需要指示 Spring 加载 我们的配置文件。​​Filter​​​​session-client.xml​

我们使用以下配置执行此操作:

src/main/webapp/WEB-INF/web.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读取上下文参数值并获取我们的会话客户端.xml配置文件。​​contextConfigLocation​

最后,我们需要确保我们的 Servlet 容器(即 Tomcat)在每个请求中使用 ourfor。​​springSessionRepositoryFilter​

以下代码片段为我们执行了最后一步:

src/main/webapp/WEB-INF/web.xml

<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>

DemissionatingFilterProxy将按 的名称查找 bean 并将其转换为 a。对于每个 HTTP 请求, Theis 调用,它委托给。​​springSessionRepositoryFilter​​​​Filter​​​​DelegatingFilterProxy​​​​springSessionRepositoryFilter​

3.2.2. Apache Geode 点对点 (P2P)

一种不太常见的方法是将 Spring 会话应用程序配置为 Apache Geode 集群中的对等成员 使用对等 (P2P) 拓扑。 在此配置中,Spring 会话应用程序将是 Apache Geode 中的实际服务器(或数据节点) 群集,而不仅仅是以前的缓存客户端。

这种方法的一个优点是应用程序接近应用程序的状态(即其数据), 特别是国家。但是,还有其他有效的方法可以实现类似的目标 依赖于数据的计算,例如使用 Apache Geode 的函数执行​。 Apache Geode的任何其他功能都可以在以下情况下使用。 Apache Geode在Spring Session中担任提供者。​​HttpSession​

P2P 拓扑对于测试目的以及更小、更集中和独立的应用程序非常有用, 例如在微服务架构中找到的那些,并且肯定会改善应用程序的感知 延迟和吞吐量需求。

您可以使用以下任一方式配置对等 (P2P) 拓扑:

  • 基于 Java 的配置
  • 基于 XML 的配置
Apache Geode Peer-to-Peer (P2P) 基于 Java 的配置

本节介绍如何将 Apache Geode 的对等 (P2P) 拓扑配置为管理状态 使用基于 Java 的配置。​​HttpSession​

HttpSession with Apache Geode (P2P)提供了一个工作示例,演示了如何 将Spring Session与Apache Geode集成,以使用Java配置进行管理状态。您可以阅读 通过下面的基本集成步骤,但建议您按照详细的“HttpSession”进行操作 与您自己的应用程序集成时使用 Apache Geode (P2P) 指南。​​HttpSession​

Spring Java 配置

添加所需的依赖项和存储库声明后,我们可以创建 Spring 配置。

Spring 配置负责创建一个替换由 Spring Session 和 Apache Geode 支持的实现。​​Servlet​​​​Filter​​​​javax.servlet.http.HttpSession​

添加以下 Spring 配置:

@PeerCacheApplication(name = "SpringSessionDataGeodeJavaConfigP2pSample", logLevel = "error") 
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 30)
public class Config {

}

首先,我们使用注释来简化对等缓存实例的创建。​​@PeerCacheApplication​

然后,对类进行注释以创建用于存储状态的必要服务器端(默认情况下为“ClusteredSpringSessions”)。​​Config​​​​@EnableGemFireHttpSession​​​​Region​​​​HttpSession​

有关为 Apache Geode 配置 Spring 数据的更多信息,请参阅参考指南。

注释使开发人员能够配置两个春季会话的某些方面 和使用以下属性的开箱即用的 Apache Geode:​​@EnableGemFireHttpSession​

  • ​clientRegionShortcut​​- 使用ClientRegionShortcut(默认为 )在客户端上指定 Apache Geode数据管理策略。此属性仅在配置客户端时使用。PROXYRegion
  • ​indexableSessionAttributes​​- 按名称标识应为查询目的编制索引的会话属性。 只有按名称显式标识的会话属性才会被编入索引。
  • ​maxInactiveIntervalInSeconds​​- 控制HttpSession空闲超时过期时间(默认为30 分钟)。
  • ​poolName​​- 用于将客户端连接到服务器群集的专用 Apache GeoDeused 的名称。 仅当应用程序是缓存客户端时才使用此属性。默认为。PoolgemfirePool
  • ​regionName​​- 指定用于存储和管理状态的 Apache GeoDeused 的名称 (默认为“集群春季会话”)。RegionHttpSession
  • ​serverRegionShortcut​​- 使用RegionShortcut(默认为 )在服务器上指定 Apache Geode数据管理策略。此属性仅在配置服务器时使用, 或者当采用 P2P 拓扑时。PARTITIONRegions
Java Servlet 容器初始化

我们的<<[httpsession-spring-java-configuration-p2p,Spring Java Configuration>>创建了一个名为Spring bean的实现。底比亚 负责替换为由 春季会议和阿帕奇巨地。​​springSessionRepositoryFilter​​​​javax.servlet.Filter​​​​springSessionRepositoryFilter​​​​javax.servlet.http.HttpSession​

为了让我们的魔法发挥,春天需要加载我们的班级。我们还需要确保我们的 Servlet 容器(即 Tomcat)在每个 HTTP 请求中使用 ouron。​​Filter​​​​Config​​​​springSessionRepositoryFilter​

幸运的是,Spring Session提供了一个实用程序类,名为使两者兼而有之。 步骤非常简单。​​AbstractHttpSessionApplicationInitializer​

您可以在下面找到一个示例:

src/main/java/sample/Initializer.java

public class Initializer extends AbstractHttpSessionApplicationInitializer { 

public Initializer() {
super(Config.class);
}
}

我们类 () 的名称无关紧要。重要的是我们扩大。​​Initializer​​​​AbstractHttpSessionApplicationInitializer​

第一步是扩展。这确保了Spring bean namedis注册到我们的Servlet容器中,并在每个HTTP请求中使用。​​AbstractHttpSessionApplicationInitializer​​​​springSessionRepositoryFilter​

​AbstractHttpSessionApplicationInitializer​​还提供了一种机制,可轻松让弹簧加载

我们的班级。​​Config​

Apache Geode Peer-to-Peer (P2P) 基于 XML 的配置

本节介绍如何将 Apache Geode 的对等 (P2P) 拓扑配置为管理状态 使用基于 XML 的配置。​​HttpSession​

使用 XML 的 HttpSession with Apache Geode (P2P)提供了一个工作示例,演示了如何 将Spring Session与Apache Geode集成,以使用XML配置来管理状态。您可以阅读 通过下面的基本集成步骤,但建议您按照详细的“HttpSession”进行操作 与您自己的应用程序集成时使用 XML 指南的 Apache Geode (P2P)。​HttpSession​

弹簧 XML 配置

添加所需的依赖项和存储库声明后,我们可以创建 Spring 配置。

Spring 配置负责创建一个替换由 Spring Session 和 Apache Geode 支持的实现。​​Servlet​​​​Filter​​​​javax.servlet.http.HttpSession​

添加以下 Spring 配置:

src/main/webapp/WEB-INF/spring/session.xml

<context:annotation-config/>

<context:property-placeholder/>


<util:properties >
<prop key="name">SpringSessionDataGeodeXmlP2pSample</prop>
<prop key="log-level">${spring.data.gemfire.cache.log-level:error}</prop>
</util:properties>


<gfe:cache properties-ref="gemfireProperties"/>


<bean class="org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration"
p:maxInactiveIntervalInSeconds="30"/>


(可选)首先,我们可以包含 abean 来配置 Apache Geode 对等的某些方面,使用VMware Tanzu GemFire 属性。在这种情况下,我们只是

使用特定于应用程序的系统属性设置 Apache Geode 的“日志级别”,默认为“警告”如果未指定。​​Properties​​​​Cache​

我们必须配置一个Apache Geode对等实例。我们使用 Apache Geode 属性初始化它。​​Cache​

最后,我们通过注册一个实例来启用 Spring 会话功能。​​GemFireHttpSessionConfiguration​

有关为 Apache Geode 配置 Spring 数据的更多信息,请参阅参考指南。

XML Servlet 容器初始化

SpringXML 配置创建了一个名为 Spring bean 的实现。Thebean负责用Spring Session和Apache Geode支持的自定义实现替换the。​​springSessionRepositoryFilter​​​​javax.servlet.Filter​​​​springSessionRepositoryFilter​​​​javax.servlet.http.HttpSession​

为了让我们的魔力发挥,我们需要指示 Spring 加载我们的配置文件。​​Filter​​​​session.xml​

我们使用以下配置执行此操作:

src/main/webapp/WEB-INF/web.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读取上下文参数值并获取我们的会话.xml配置文件。​​contextConfigLocation​

最后,我们需要确保我们的 Servlet 容器(即 Tomcat)使用 our for 每个 HTTP 请求。​​springSessionRepositoryFilter​

以下代码片段为我们执行了最后一步:

src/main/webapp/WEB-INF/web.xml

<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>

DemissionatingFilterProxy将按 的名称查找 bean 并将其转换为 a。对于每个 HTTP 请求 Theis 调用,委托给 the。​​springSessionRepositoryFilter​​​​Filter​​​​DelegatingFilterProxy​​​​springSessionRepositoryFilter​

3.3. 使用带有属性的 Apache Geode 进行配置管理​​HttpSession​

虽然注释在开始使用春季会话时易于使用且方便 和 Apache Geode 在您的 Spring 启动应用程序中,当您从一个应用程序迁移时,您很快就会遇到限制 环境到另一个环境,例如,从 DEV 迁移到 QA 再到 PROD 时。​​@EnableGemFireHttpSession​

使用注释属性,无法从一个更改配置 环境到另一个。因此,Apache Geode 的春季课程介绍了众所周知的、记录在案的属性 对于所有注释属性。​​@EnableGemFireHttpSession​​​​@EnableGemFireHttpSession​

表 4.注释属性的已知、记录的属性。​​@EnableGemFireHttpSession​

财产

批注属性

描述

违约

spring.session.data.gemfire.cache.client.pool.name

​EnableGemFireHttpSession.poolName​

客户端区域存储/访问会话状态使用的专用池的名称。

宝石火池

spring.session.data.gemfire.cache.client.region.shortcut

​EnableGemFireHttpSession.clientRegionShortcut​

在客户端-服务器拓扑中设置客户端区域数据管理策略。

ClientRegionShortcut.PROXY

spring.session.data.gemfire.cache.server.region.shortcut

​EnableGemFireHttpSession.serverRegionShortcut​

在对等 (P2P) 拓扑中设置对等区域数据管理策略。

区域快捷方式.分区

spring.session.data.gemfire.session.attributes.indexable

​EnableGemFireHttpSession.indexableSessionAttributes​

要在会话区域中编制索引的会话属性的逗号分隔列表。

spring.session.data.gemfire.session.expiration.bean-name

​EnableGemFireHttpSession.sessionExpirationPolicyBeanName​

实现过期策略的 Spring 容器中 Bean 的名称

spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds

​EnableGemFireHttpSession.maxInactiveIntervalInSeconds​

会话过期超时(以秒为单位)

1800

spring.session.data.gemfire.session.region.name

​EnableGemFireHttpSession.regionName​

用于存储和访问会话状态的客户端或对等区域的名称。

集群春季会话

spring.session.data.gemfire.session.serializer.bean-name

​EnableGemFireHttpSession.sessionSerializerBeanName​

实现序列化策略的 Spring 容器中 Bean 的名称

会话Pdx序列化程序

所有属性也都记录在注释属性Javadoc中。​​@EnableGemFireHttpSession​

因此,在使用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​

在上面的例子中,即使注释属性 设置为秒或 15 分钟,相应的属性属性 (即) 重写该值并将过期时间设置为秒或 60 分钟。​​EnableGemFireHttpSession​​​​maxInactiveIntervalInSeconds​​​​900​​​​spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds​​​​3600​

请记住,属性在运行时会覆盖批注属性值。

3.3.1. 属性的属性

您甚至可以变得更复杂,并使用其他属性配置您的属性,如下所示:

#application.properties
spring.session.data.gemfire.session.expiration.max-inactive-internval-seconds=${app.geode.region.expiration.timeout:3600}

此外,您可以使用 Spring 配置文件根据环境改变过期超时(或其他属性)。 或您的应用程序,或您的应用程序要求规定的任何标准。

属性占位符和嵌套是核心 Spring 框架的一个功能,而不是特定于 Spring 会话 或 Apache Geode 的春季会议。

3.4. 使用带有配置器的 Apache Geode 进行配置管理​​HttpSession​

除了属性之外,Spring Session for Apache Geode 还允许您调整 春季会议与Apache Geode使用界面。该接口定义了一个 协定包含可重写的 Eachannotation 属性的默认方法 以调整配置。​​SpringSessionGemFireConfigurer​​​​@EnableGemFireHttpSession​

这在概念上类似于Spring Web MVC的配置器接口 (例如),它调整 Web 应用程序的各个方面 启动时配置,例如配置异步支持。声明和实现 ais 的优点是,它使您能够以编程方式控制配置。这在您需要的情况下很有用 轻松表达确定是否应应用配置的复杂条件逻辑。​​SpringSessionGemFireConfigurer​​​​o.s.web.servlet.config.annotation.WebMvcConfigurer​​​​Configurer​

例如,要像之前一样调整客户端区域数据管理策略和会话过期超时, 使用以下内容:

@Configuration
class MySpringSessionConfiguration {

@Bean
SpringSessionGemFireConfigurer exampleSpringSessionGemFireConfigurer() {

return new SpringSessionGemFireConfigurer() {

@Override
public ClientRegionShortcut getClientRegionShortcut() {
return ClientRegionShortcut.CACHING_PROXY;
}

@Override
public int getMaxInactiveIntervalInSeconds() {
return 3600;
}
};
}
}

当然,这个例子不是很有创意。您肯定可以使用更复杂的逻辑来确定 每个配置属性的配置。

您可以随心所欲地复杂,例如通过实现其他属性的 yourin 使用泉三注解,如下:​​Configurer​​​​@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 引导将自动解析注释属性占位符值或 SpEL 表达式。 但是,如果您不使用 Spring Boot,则必须显式注册静态 bean 定义。​​@Value​​​​PropertySourcesPlaceholderConfigurer​

但是,您一次只能在 Spring 容器中声明 1bean,除非 您还在使用 Spring 配置文件或已将 1 个多豆标记为主 通过使用 Spring 的上下文注释。​​SpringSessionGemFireConfigurer​​​​SpringSessionGemFireConfigurer​​​​@Primary​

3.4.1. 配置优先级

优先于任一注释属性 或任何知名且有记录的 Apache Geode 属性春季会议 (例如) 在 Spring Boot 中定义​​SpringSessionGemFireConfigurer​​​​@EnableGemFireHttpSession​​​​spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds​​​​application.properties.​

如果 Web 应用程序采用 1 种以上的配置方法,则将应用以下优先级:

  1. ​SpringSessionGemFireConfigurer​​“实现的”回调方法
  2. 记录的 Apache Geode 属性的春季会话(请参阅相应的注释 属性Javadoc;例如@EnableGemFireHttpSessionspring.session.data.gemfire.session.region.name)
  3. ​@EnableGemFireHttpSession​​批注属性

Apache Geode 的春季会话小心翼翼地只应用来自 abean 的配置 在 Spring 容器中声明了您实际实现的方法。​​SpringSessionGemFireConfigurer​

在上面的示例中,由于您没有实现该方法,因此 Apache Geode 区域的名称 管理状态不会由配置程序决定。​​getRegionName()​​​​HttpSession​

例如,请考虑以下配置:

Apache Geode 配置的春季会话示例

@ClientCacheApplication
@EnableGemFireHttpSession(
maxInactiveIntervalInSeconds = 3600,
poolName = "DEFAULT"
)
class MySpringSessionConfiguration {

@Bean
SpringSessionGemFireConfigurer sessionExpirationTimeoutConfigurer() {

return new SpringSessionGemFireConfigurer() {

@Override
public int getMaxInactiveIntervalInSeconds() {
return 300;
}
};
}
}

此外,请考虑以下 Spring 引导文件:​​application.properties​

  1. 弹簧启动application.properties
spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds = 900
spring.session.data.gemfire.session.region.name = Sessions

会话过期超时将为 300 秒或 5 分钟,覆盖这两个属性 (即)900秒或15分钟, 以及显式注释属性值 3600 秒或 1 小时。​​spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds​​​​@EnableGemFireHttpSession.maxInactiveIntervalInSeconds​

由于“sessionExexpationTimeoutConfigurer”bean不会覆盖该方法,因此会话区域 名称将由属性确定(即),设置为“会话”, 它覆盖隐式批注属性的默认值 “集群春季会议”。​​getRegionName()​​​​spring.session.data.gemfire.session.region.name​​​​@EnableGemFireHttpSession.regionName​

注释属性的值“DEFAULT”将决定池的名称 在客户端和服务器之间发送区域操作以管理服务器上的会话状态时使用,因为两者都不是 设置了相应的属性(即 spring.session.data.gemfire.cache.client.pool.name'),也没有 该方法被“sessionExexpationTimeoutConfigurer”bean覆盖。​​@EnableGemFireHttpSession.poolName​​​​SpringSessionGemFireConfigurer.getPoolName()​

最后,用于管理会话状态的客户端区域将具有默认的数据管理策略 注释属性的值,该属性未显式设置,也没有显式设置 是此属性的相应属性(即)。 并且,由于该方法未被重写,因此使用默认值。​​PROXY​​​​@EnableGemFireHttpSession.clientRegionShortcut​​​​spring.session.data.gemfire.cache.client.region.shortcut​​​​SpringSessionConfigurer.getClientRegionShortcut()​

3.5. Apache Geode 过期

默认情况下,Apache Geode 配置了区域条目、空闲超时 (TTI) 过期策略,使用 过期超时为 30 分钟,并使条目无效作为操作。这意味着当用户的会话保持非活动状态时 (即空闲)超过 30 分钟,会话将过期并失效,用户必须开始新的会话 为了继续使用该应用程序。

但是,如果您对会话状态管理和过期以及使用 默认情况下,空闲超时 (TTI) 过期策略不足以满足您的使用案例 (UC)?

现在,Apache Geode 的春季会话支持特定于应用程序的自定义过期策略。作为应用程序 开发人员,您可以指定自定义规则来管理由 Spring 会话管理的会话的到期时间,该规则由 Apache Geode。

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

}
}

实现此接口以指定应用程序所需的会话过期策略,然后注册 作为 Spring 应用程序上下文中的 Bean 的实例。

使用注释,属性来配置名称 Bean 实现自定义应用程序策略和会话过期规则。​​@EnableGemFireHttpSession​​​​sessionExpirationPolicyBeanName​​​​SessionExpirationPolicy​

例如:

习惯​​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
}
}

然后,在应用程序类中,简单声明以下内容:

自定义配置​​SessionExpirationPolicy​

@SpringBootApplication
@EnableGemFireHttpSession(
maxInactiveIntervalInSeconds = 600,
sessionExpirationPolicyBeanName = "expirationPolicy"
)
class MySpringSessionApplication {

@Bean
SessionExpirationPolicy expirationPolicy() {
return new MySessionExpirationPolicy();
}
}

或者,可以使用属性配置bean的名称,或者通过在Spring容器中声明abean并覆盖该方法来配置bean。​​SessionExpirationPolicy​​​​spring.session.data.gemfire.session.expiration.bean-name​​​​SpringSessionGemFireConfigurer​​​​getSessionExpirationPolicyBeanName()​

你只需要实现该方法, 它封装了规则以确定会话何时到期。会话的过期超时 表示为 anof,它指定会话到期前的时间长度。​​determineExpirationTimeout(:Session):Optional<Duration>​​​​Optional​​​​java.time.Duration​

该方法可以是特定于会话的,并且可能会随着每次调用而更改。​​determineExpirationTimeout​

(可选)您可以实现该方法以指定会话过期时执行的操作。默认情况下, 区域条目(即会话)无效。另一种选择是在到期时销毁区域条目, 这将删除键(会话 ID)和值(会话)。无效仅删除该值。​​getAction​

在引擎盖下,这些被改编成Apache GeodeCustomExpiry​接口的实例。 然后,此 Spring 会话对象将设置为会话区域的自定义条目空闲超时过期策略。​​SessionExpirationPolicy​​​​CustomExpiry​

在确定过期时间期间,每次运行过期线程时,都会为区域中的每个条目(即会话)调用该方法,进而运行过期线程 调用我们的方法。 返回的值转换为秒,并用作从CustomExpiry.getExpiry(..)​ 返回的过期属性中的过期​超时方法调用。​​CustomExpiry.getExpiry(:Region.Entry<String, Session>):ExpirationAttributes​​​​SessionExpirationPolicy.determineExpirationTimout(:Session):Optional<Duration>​​​​java.time.Duration​

Apache Geode 的过期线程每秒运行一次,评估区域中的每个条目(即会话) 以确定条目是否已过期。您可以使用属性控制过期线程数。有关更多详细信息,请参阅 Apache Geode文档​。​​gemfire.EXPIRY_THREADS​

3.5.1. 过期超时配置

如果您想为您的自定义设置过期超时 注释,属性,或者, 对应性质, 那么你的自定义实现也可以实现接口。​​SessionExpirationPolicy​​​​@EnableGemFireHttpSession​​​​maxInactiveIntervalInSeconds​​​​spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds​​​​SessionExpirationPolicy​​​​SessionExpirationTimeoutAware​

接口定义为:​​SessionExpirationTimeoutAware​

会话过期超时感知接口

interface SessionExpirationTimeoutAware {

void setExpirationTimeout(Duration expirationTimeout);

}

当您的自定义实现也实现接口时, 然后,Apache Geode 的 Spring 会话将为您的实现提供来自注释、属性或属性(如果已设置)的值,或者来自 Spring 应用程序上下文中声明的任何 bean 的值,作为实例。​​SessionExpirationPolicy​​​​SessionExpirationTimeoutAware​​​​@EnableGemFireHttpSession​​​​maxInactiveIntervalInSeconds​​​​spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds​​​​SpringSessionGemFireConfigurer​​​​java.time.Duration​

如果使用 1 个以上的配置选项,则按以下顺序优先:

  1. ​SpringSessionGemFireConfigurer.getMaxInactiveIntervalInSeconds()​
  2. ​spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds​​财产
  3. ​@EnableGemFireHttpSession​​注释,属性maxInactiveIntervalInSeconds

3.5.2. 修复超时过期问题

为了增加便利性,适用于Apache Geode的Spring Session提供了固定持续时间过期(或“绝对会话超时”,如核心春季会话问题#922中所述)的接口实现。​​SessionExpirationPolicy​

在某些情况下,例如出于安全原因,可能需要在修复后使用户的会话过期 时间长度(例如每小时),无论用户的会话是否仍处于活动状态。

Apache Geode 春季会议提供开箱即用的实现 对于这个确切的用例 (UC)。除了处理固定期限到期外,还要谨慎考虑 并应用默认的空闲过期超时。​​FixedTimeoutSessionExpirationPolicy​

例如,考虑这样一种情况:用户登录,开始会话,活动 10 分钟,然后离开 让会话闲置。如果固定持续时间过期超时设置为 60 分钟,但空闲过期 超时仅设置为 30 分钟,并且用户不返回,则会话应在 40 分钟后过期 而不是固定持续时间到期时的 60 分钟。

相反,如果用户忙了整整 40 分钟,则保持会话处于活动状态,从而避免了 30 分钟 空闲过期超时,然后离开,然后我们的固定持续时间过期超时应该启动并过期 用户的会话权限为 60 分钟,即使用户的空闲过期超时在 70 分钟之前不会发生 在(40 分钟(活动)+ 30 分钟(空闲)= 70 分钟)。

嗯,这正是你所做的。​​FixedTimeoutSessionExpirationPolicy​

要进行配置,请执行以下操作:​​FixedTimeoutSessionExpirationPolicy​

固定持续时间到期配置

@SpringBootApplication
@EnableGemFireHttpSession(sessionExpirationPolicyBeanName = "fixedTimeoutExpirationPolicy")
class MySpringSessionApplication {

@Bean
SessionExpirationPolicy fixedTimeoutExpirationPolicy() {
return new FixedTimeoutSessionExpirationPolicy(Duration.ofMinutes(60L));
}
}

在上面的例子中,thewas在Spring应用程序上下文中声明为bean。 并使用 60 分钟的固定持续时间过期超时进行初始化。因此,用户会话将 在空闲超时(默认为 30 分钟)或固定超时(配置为 60 分钟)之后过期, 哪个先发生。​​FixedTimeoutSessionExpirationPolicy​

还可以通过使用 Apache Geode的春季会议。这个 BPP 包装 任何特定于实现的数据存储 仅评估访问时的会话过期时间。此方法与基础数据存储无关 因此可以与任何春季会话提供程序一起使用。到期确定完全基于 会话属性和必需指定固定持续时间 过期超时。​​FixedDurationExpirationSessionRepositoryBeanPostProcessor​​​​SessionRepository​​​​FixedDurationExpirationSessionRepository​​​​creationTime​​​​java.time.Duration​

不应在严格的过期超时情况下使用,例如 当会话必须在固定持续时间过期超时过后立即过期时。此外,与 的,不采取空闲过期 考虑超时。也就是说,在确定过期超时时,它只使用固定持续时间 对于给定会话。​​FixedDurationExpirationSessionRepository​​​​FixedTimeoutSessionExpirationPolicy​​​​FixedDurationExpirationSessionRepository​

3.5.3.链接​​SessionExpirationPolicy​

使用Composite 软件设计模式,您可以将一组实例视为单个实例,就像在链中一样运行,就像在链中一样 Servlet 过滤器本身。​​SessionExpirationPolicy​

复合软件设计模式是一种功能强大的模式,只需返回 anoffrom 即可获得支持。 方法。​​SessionExpirationPolicy​​​​@FunctionalInterface​​​​Optional​​​​java.time.Duration​​​​determineExpirationTimeout​

这允许每个组合“可选”仅在过期时返回 可以通过此实例确定。或者,此实例可以下注到组合中的下一个实例,或者链直到返回非空过期超时,或者最终 不返回过期超时。​​SessionExpirationPolicy​​​​Duration​​​​SessionExpirationPolicy​

实际上,此策略在内部使用,在空闲超时将在固定超时之前发生的情况下返回。通过返回 没有过期超时,Apache Geode 将遵循默认的、配置的条目空闲超时过期策略 在区域管理会话状态上。​​FixedTimeoutSessionExpirationPolicy​​​​Optional.empty()​

这种确切的行为也记录在org.apache.geode.cache.CustomExpiry.getExpiry(:Region.Entry<String,Session>):ExplumationAttributes方法中。

3.6. Apache Geode 序列化

为了在客户端和服务器之间传输数据,或者在对等节点之间分发和复制数据时 在集群中,数据必须序列化。在这种情况下,有问题的数据是会话的状态。

每当在客户端/服务器拓扑中保留或访问会话时,会话的状态都会通过网络发送。 通常,启用了 Spring 会话的 Spring 引导应用程序将是集群中服务器的客户端 的 Apache Geode 节点。

在服务器端,会话状态可能分布在群集中的多个服务器(数据节点)上以进行复制 数据并保证会话状态的高可用性。使用Apache Geode时,可以对数据进行分区, 或分片,并且可以指定冗余级别。分发数据以进行复制时,还必须 序列化以在群集中的对等节点之间传输会话状态。

开箱即用的Apache Geode支持Java序列化Java 序列化有很多优点, 例如在对象图中处理循环,或者被任何用 Java 编写的应用程序普遍支持。 但是,Java 序列化非常冗长,不是最有效的在线格式。

因此,Apache Geode提供了自己的序列化框架来序列化Java类型:

  1. 数据序列化
  2. PDX 序列化

3.6.1. Apache Geode 序列化背景

如上所述,Apache Geode 提供了 2 个额外的序列化框架:数据序列化和 PDX序列化

数据序列化

数据序列化是一种非常有效的格式(即快速紧凑),与Java序列化相比,开销很小。

它通过发送支持增量传播 只有实际更改的数据位,而不是发送整个对象,这肯定会减少 除了在持久保存数据时减少 IO 量外,还通过网络发送的数据量 或溢出到磁盘。

但是,每当数据通过线传输或持久化/溢出到 并从磁盘访问,因为接收端执行反序列化。事实上,无论何时使用增量传播,都必须在接收端对对象进行反序列化,以便应用“增量”。Apache Geode 适用 通过在实现接口的对象上调用方法进行增量。显然,你不能 在序列化对象上调用方法。​​org.apache.geode.Delta​

PDX

另一方面,PDX代表便携式数据交换,保留发送数据的形式。 例如,如果客户端以 PDX 格式将数据发送到服务器,则服务器会将数据保留为 PDX 序列化字节 并将它们存储在数据访问操作所针对的缓存中。​​Region​

此外,顾名思义,PDX 是“可移植的”,这意味着它同时支持 Java 和本地语言客户端, 例如 C、C++ 和 C# 客户端,以便对同一数据集进行互操作。

PDX 甚至允许对序列化字节执行 OQL 查询,而不会导致对象反序列化 首先为了计算查询谓词并执行查询。这可以实现,因为Apache Geode 维护一个“类型注册表”,其中包含序列化和存储在 使用 PDX 的 Apache Geode。

但是,可移植性确实有成本,其开销略高于数据序列化。尽管如此,PDX还很远。 比 Java 序列化更高效、更灵活,Java 序列化将类型元数据存储在对象的序列化字节中 而不是像使用 PDX 时 Apache Geode 那样在单独的类型注册表中。

PDX 不支持增量。从技术上讲,PDX 可序列化对象可以通过实现 org.apache.geode.Delta接口,只有“delta”将是 发送,即使在 PDX 的上下文中也是如此。但是,必须反序列化 PDX 序列化对象才能应用增量。 请记住,调用一个方法来应用增量,这首先违背了使用 PDX 的目的。

在开发管理 {data-store-name} 集群中的数据的本机客户端(例如 C)时,甚至在混合时 具有 Java 客户机的本机客户机,通常不会在类路径上提供任何关联的 Java 类型 群集中的服务器。使用 PDX,没有必要在类路径上提供 Java 类型,并且许多 仅开发和使用本机客户端来访问存储在 {data-store-name} 中的数据的用户将不会提供任何 Java 类型对应的 C/C/C# 类型。

Apache Geode还支持序列化到PDX的JSON。在这种情况下,Java 类型很可能不会 在服务器类路径上提供,因为许多不同的语言(例如JavaScript,Python,Ruby)支持JSON可以 与Apache Geode一起使用。

尽管如此,即使使用 PDX,用户也必须注意不要在群集中的服务器上造成 PDX 序列化对象。 要反序列化。

例如,考虑对序列化为 PDX 的以下 Java 类型的对象的 OQL 查询...

@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 序列化对象被反序列化,因为不是字段, 而是一种包含基于另一个字段(即)的计算的方法。同样,调用 OQL 查询中的任何方法都会导致反序列化发生 也。​​Person​​​​age​​​​Person​​​​Person​​​​birthDate​​​​java.lang.Object​​​​Object.toString()​

Apache Geode 确实提供了读取序列化配置设置,以便可能在 a 内部调用的任何缓存操作不会导致 PDX 序列化对象被反​​序列化​​。但是,没有什么能阻止考虑不周的 OQL 查询 导致反序列化,因此要小心。​​Region.get(key)​​​​Function​

数据序列化 + PDX + Java 序列化

Apache Geode 可以同时支持所有 3 种序列化格式。

例如,应用程序域模型可能包含实现接口的对象, 并且您可能将数据序列化框架与 PDX 结合使用。​​java.io.Serialiable​

虽然可以将Java序列化与数据序列化和 PDX 一起使用,但通常更可取 并建议使用 1 个序列化策略。

Java 序列化不同,数据序列化和 PDX序列化不处理对象图周期。

有关Apache Geode序列化机制的更多背景可以在这里找到。

3.6.2. 春季会话的序列化

以前,Apache Geode 的 Spring Session 仅支持 Apache GeodeData Serialization格式。主要 这背后的动机是利用Apache Geode的增量传播功能,因为会话 状态可以是任意大的。

但是,从Apache Geode 2.0的春季会话开始,PDX也受支持,现在是新的默认序列化。 选择。在 Apache Geode 2.0 的春季会话中,默认值更改为 PDX,主要是因为 PDX 是最 用户广泛使用和要求的格式。

PDX 无疑是最灵活的格式,以至于您甚至不需要 Apache Geode 的 Spring 会话。 或其对集群中服务器的类路径的任何传递依赖关系,以便将 Spring 会话与 Apache Geode。事实上,使用 PDX,您甚至不需要将应用程序域对象类型存储在 服务器类路径上的 (HTTP) 会话。

本质上,当使用PDX序列化时,Apache Geode不需要存在关联的Java类型。 在服务器的类路径上。只要群集中的服务器上不发生反序列化,您就是安全的。

注释引入了用户的新属性 可用于配置在 Spring 容器中声明和注册的 bean 的名称,实现所需的 序列化策略。Spring会话使用序列化策略进行Apache Geode序列化 会话状态。​​@EnableGemFireHttpSession​​​​sessionSerializerBeanName​

开箱即用的 Apache Geode 春季会话提供了 2 种序列化策略:1 种用于 PDX,1 种用于数据序列化。它会自动在 Spring 容器中注册两个序列化策略 bean。 但是,这些策略中只有 1 种在运行时实际使用 PDX!

在实现数据序列化和 PDX 的 Spring 容器中注册的 2 个 bean 分别被命名为 and。默认情况下,属性 设置为,就像用户注释他/她的 Spring 启动一样,启用 Spring 会话的应用程序 配置类,具有:​​SessionDataSerializer​​​​SessionPdxSerializer​​​​sessionSerializerBeanName​​​​SessionPdxSerializer​

@SpringBootApplication
@EnableGemFireHttpSession(sessionSerializerBeanName = "SessionPdxSerializer")
class MySpringSessionApplication { }

通过将属性设置为将序列化策略更改为数据序列化是一件简单的事情,如下所示:​​sessionSerializerBeanName​​​​SessionDataSerializer​

@SpringBootApplication
@EnableGemFireHttpSession(sessionSerializerBeanName = "SessionDataSerializer")
class MySpringSessionApplication { }

由于这两个值非常常见,因此 Apache Geode 的 Spring Session 为 class:and 中的每个值提供了常量。因此,您可以显式配置 PDX, 如下:​​GemFireHttpSessionConfiguration​​​​GemFireHttpSessionConfiguration.SESSION_PDX_SERIALIZER_BEAN_NAME​​​​GemFireHttpSessionConfiguration.SESSION_DATA_SERIALIZER_BEAN_NAME​

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 定义,您可以指定所需的序列化框架 与您的 Spring Boot 一起使用,由 Apache Geode 支持的启用 Spring 会话的应用程序。

3.6.3. Apache Geode 序列化框架的春季会议

为了抽象出Apache Geode的数据序列化和PDX序列化框架的细节, Apache Geode的春季会议提供了自己的序列化框架(外观),包装了Apache Geode的 序列化框架。

序列化 API 存在于包下。主要 此 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)
}
}

基本上,该接口允许您序列化和反序列化 Springobject。​​Session​

这些类型的 theandtype 参数和相应的方法参数提供对对象的引用 负责写入字节流或从字节流中读取。实际的 参数将特定于类型,具体取决于配置的基础 Apache Geode 序列化策略。​​IN​​​​OUT​​​​Session​​​​Session​

例如,当使用Apache Geode的PDX序列化框架时,and将分别是and的实例。当Apache Geode的数据序列化框架被配置后,thenand将分别是and的实例。​​IN​​​​OUT​​​​org.apache.geode.pdx.PdxReader​​​​org.apache.geode.pdx.PdxWriter​​​​IN​​​​OUT​​​​java.io.DataInput​​​​java.io.DataOutput​

这些参数由框架自动提供给实现,并作为 前面提到的,是基于配置的基础 Apache Geode 序列化策略。​​SessionSerializer​

从本质上讲,即使Apache Geode的春季会议提供了一个围绕Apache Geode的门面。 序列化框架,底层的Apache Geode仍然期望这些序列化框架之一 用于将数据序列化到 Apache Geode 或从 Apache Geode 序列化。

那么​​,SessionSerializer​​接口到底有什么用呢?

实际上,它允许用户自定义会话状态的哪些方面实际被序列化和存储 在阿帕奇·乔德。应用程序开发人员可以提供自己的自定义、特定于应用程序的实现,在 Spring 容器中将其注册为 bean,然后将其配置为由 Spring 会话使用 让 Apache Geode 序列化会话状态,如下所示:​​SessionSerializer​

@EnableGemFireHttpSession(sessionSerializerBeanName = "MyCustomSessionSerializer")
class MySpringSessionDataGemFireApplication {

@Bean("MyCustomSessionSerializer")
SessionSerializer<Session, ?, ?> myCustomSessionSerializer() {
// ...
}
}
Implementing a SessionSerializer

Apache Geode 的春季会话在用户想要实现适合 Apache Geode 序列化框架之一的自定义时提供帮助。​​SessionSerializer​

如果用户只是实现接口 直接没有从 Apache Geode 提供的抽象基类的春季会话之一扩展,相关 到 Apache Geode 的序列化框架中的 1 个,然后 Apache Geode 的 Spring 会话将包装用户的 自定义实现 在实例中并将其注册到 Apache Geode 作为 a。​​org.springframework.session.data.gemfire.serialization.SessionSerializer​​​​SessionSerializer​​​​org.springframework.session.data.gemfire.serialization.pdx.support.PdxSerializerSessionSerializerAdapter​​​​org.apache.geode.pdx.PdxSerializer​

Apache Geode的春季会话小心翼翼地不要踩到用户的任何现有实现 可能已经通过其他方式在Apache Geode注册。事实上,有几个不同的,提供 Apache Geode接口的实现存在:​​PdxSerializer​​​​org.apache.geode.pdx.PdxSerializer​

  • Apache Geode 本身提供了org.apache.geode.pdx.ReflectionBasedAutoSerializer。
  • Spring Data for Apache Geode (SDG) 提供了org.springframework.data.gemfire.mapping.MappingPdxSerializer, 用于 SD存储库抽象和 SDG 的扩展,以处理将 PDX 序列化类型映射到 在应用程序存储库接口中定义的应用程序域对象类型。

这是通过获取缓存上当前注册的任何实例并对其进行组合来实现的 包装用户的自定义应用程序实现并在 Apache Geode 缓存上重新注册此“复合”。“复合”实现由Spring Session为Apache Geode的类提供 当实体作为 PDX 存储在 Apache Geode 中时。​​PdxSerializer​​​​PdxSerializerSessionSerializerAdapter​​​​SessionSerializer​​​​PdxSerializer​​​​PdxSerializer​​​​org.springframework.session.data.gemfire.pdx.support.ComposablePdxSerializer​

如果当前没有其他适配器在 Apache Geode 缓存中注册,则适配器 只是注册。​​PdxSerializer​

当然,您可以通过执行以下操作之一来强制使用与自定义实现一起使用的底层 Apache Geode 序列化策略:​​SessionSerializer​

  1. 自定义实现可以实现Apache Geode的接口,或者为了方便起见,为Apache Geode的类扩展Spring Session。 Apache Geode的春季会议将向Apache Geode注册customas a。SessionSerializerorg.apache.geode.pdx.PdxSerializerorg.springframework.session.data.gemfire.serialization.pdx.AbstractPdxSerializableSessionSerializerSessionSerializerPdxSerializer
  2. 自定义实现可以扩展 Apache Geode 的类,或者为了方便起见,扩展 Apache Geode 类的 Spring 会话 Apache Geode的春季会议将向Apache Geode注册customas a。SessionSerializerorg.apache.geode.DataSerializerorg.springframework.session.data.gemfire.serialization.data.AbstractDataSerializableSessionSerializerSessionSerializerDataSerializer
  3. 最后,用户可以像以前一样创建自定义实现,而无需指定哪个 要使用的 Apache Geode 序列化框架,因为自定义实现未实现 任何 Apache Geode 序列化接口或从任何 Spring Session 扩展 for Apache Geode 提供的 抽象基类,并且仍然在 Apache Geode 中将其注册为 a,方法是声明一个 在类型的 Spring 容器中为 Apache Geode bean 提供额外的春季会话,例如...SessionSerializerSessionSeriaizerDataSerializerorg.springframework.session.data.gemfire.serialization.data.support.DataSerializerSessionSerializerAdapter

强制将自定义 SessionSerializer 注册为 Apache Geode 中的数据序列化程序

@EnableGemFireHttpSession(sessionSerializerBeanName = "customSessionSerializer")
class Application {

@Bean
DataSerializerSessionSerializerAdapter dataSerializerSessionSerializer() {
return new DataSerializerSessionSerializerAdapter();
}

@Bean
SessionSerializer<Session, ?, ?> customSessionSerializer() {
// ...
}
}

仅仅通过春天容器中注册为豆子的存在, 任何中性自定义实现都将被视为 ain Apache Geode 并注册。​​DataSerializerSessionSerializerAdapter​​​​SessionSerializer​​​​DataSerializer​

对数据序列化的其他支持

如果您正在配置和引导Apache Geode服务器,请随时跳过本节 在集群中使用 Spring (引导),因为通常,以下信息将不适用。答案是肯定的 这完全取决于您声明的依赖项和 Spring 配置。但是,如果您使用Gfsh启动集群中的服务器,请务必继续阅读。

背景

使用 Apache Geode 的DataSerialization框架时,尤其是在序列化 (HTTP) 会话时从客户端 状态,您必须注意在集群中配置 Apache Geode 服务器 具有适当的依赖项。在利用增量时尤其如此,如前面部分所述 关于数据序列化

使用数据序列化框架作为序列化策略以序列化(HTTP) 会话状态时 您的 Web 应用程序客户端到服务器,则必须使用春季会话正确配置服务器 用于表示 (HTTP) 会话及其内容的 Apache Geode 类类型。这意味着包括 服务器类路径上的 Spring JAR。

此外,使用DataSerialization可能还需要包含包含应用程序域的 JAR。 Web 应用程序使用并作为会话属性值放入 (HTTP) 会话中的类, 特别是如果:

  1. 您的类型实现接口。org.apache.geode.DataSerializable
  2. 您的类型实现接口。org.apache.geode.Delta
  3. 您已注册标识和序列化类型的 a。org.apache.geode.DataSerializer
  4. 您的类型实现接口。java.io.Serializable

当然,必须确保放入 (HTTP) 会话中的应用程序域对象类型在某些会话中是可序列化的 形式或其他形式。但是,您并不严格要求使用数据序列化,也不一定 在以下情况下,需要在服务器类路径上具有应用程序域对象类型:

  1. 您的类型实现接口。org.apache.geode.pdx.PdxSerializable
  2. 或者,您已注册正确标识和序列化 您的应用程序域对象类型。org.apache.geode.pdx.PdxSerializer

Apache Geode 在确定要使用的序列化策略时将应用以下优先级顺序 序列化对象图:

  1. 首先,对象和/或任何已注册标识要序列化的对象。DataSerializableDataSerializers
  2. 然后对象和/或任何已注册标识要序列化的对象。PdxSerializablePdxSerializer
  3. 最后,所有类型。java.io.Serializable

这也意味着,如果特定的应用程序域对象类型(例如)实现, 但是,已向Apache Geode注册了(自定义)标识相同的应用程序 域对象类型(即),则 Apache Geode 将使用 PDX 来序列化“A”而不是 Java序列化, 在这种情况下。​​A​​​​java.io.Serializable​​​​PdxSerializer​​​​A​

这特别有用,因为您可以使用DataSerialization来序列化 (HTTP) 会话对象,利用 增量和数据序列化的所有强大功能,但随后使用 PDX 序列化应用程序域对象 类型,这大大简化了所涉及的配置和/或工作量。

现在我们已经大致了解了为什么存在这种支持,您如何启用它?

配置

首先,创建一个 Apache Geode,如下所示:​​cache.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 启动服务器

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 文件添加到服务器类路径中。

若要全面了解其工作原理,请参阅示例。

自定义更改检测

默认情况下,每当修改会话(例如更新到当前时间)时,会话 被 Apache Geode (SSDG) 的春季会议认为是肮脏的。在使用Apache Geode数据序列化框架时,利用Apache Geode的增量传播功能也非常有用和有价值。​​lastAccessedTime​

使用数据序列化时,SSDG 还使用增量传播仅发送对会话状态的更改 客户端和服务器。这包括可能已添加、删除或更新的任何会话属性。

默认情况下,每当调用时,会话属性都被视为“脏” 并将在客户端和服务器之间的增量中发送。即使应用程序域对象也是如此 尚未更改。​​Session.setAttribute(name, value)​

通常,除非对象已更改,否则永远没有理由调用。然而 如果发生这种情况,并且您的对象相对较大(具有复杂的对象层次结构),那么您可能需要 请考虑以下任一情况:​​Session.setAttribute(..)​

  1. 在应用程序域对象中实现增量接口 模型虽然有用,但非常具有侵入性,或者...
  2. 提供 SSDG 战略界面的自定义实现。org.springframework.session.data.gemfire.support.IsDirtyPredicate

开箱即用,SSDG 提供了 5 种策略接口实现:​​IsDirtyPredicate​

表 5.实现​​IsDirtyPredicate​

描述

违约

​IsDirtyPredicate.ALWAYS_DIRTY​

新会话属性值始终被视为脏。

​IsDirtyPredicate.NEVER_DIRTY​

新的会话属性值永远不会被视为脏。

​DeltaAwareDirtyPredicate​

当旧值和新值时,新会话属性值被视为脏 如果新值的类型未实现或新值的方法返回true,则不同。​​Delta​​​​Delta.hasDelta()​

是的

​EqualsDirtyPredicate​

如果旧值不等于,则新会话属性值被视为脏 确定方法的新值。​​Object.equals(:Object)​

​IdentityEqualsPredicate​

新会话属性值被视为脏值,如果旧值与 使用标识等于运算符的新值(即)。​​oldValue != newValue​

如上表所示,这是 SSDG 使用的默认实现。 自动考虑实现的应用程序域对象 Apache Geodeinterface。但是,即使您的应用程序也能正常工作 域对象不实现接口。SSDG 会将您的应用程序域对象视为脏对象 任何时候,只要提供新值与旧值不同, 或者新值没有实现接口。​​DeltaAwareDirtyPredicate​​​​DeltaAwareDirtyPredicate​​​​Delta​​​​DeltaAwareDirtyPredicate​​​​Delta​​​​Session.setAttribute(name, newValue)​​​​Delta​

您可以更改 SSDG 的脏实现、确定策略,只需在 Spring 容器中声明一个 bean 即可 接口类型:​​IsDirtyPredicate​

覆盖 SSDG 的默认策略​​IsDirtyPredicate​

@EnableGemFireHttpSession
class ApplicationConfiguration {

@Bean
IsDirtyPredicate equalsDirtyPredicate() {
return EqualsDirtyPredicate.INSTANCE;
}
}
组成

该接口还提供和方法 在组合中组合 2 个或多个实现,以便组织复杂的逻辑和规则 用于确定应用程序域对象是否脏。​​IsDirtyPredicate​​​​andThen(:IsDirtyPredicate)​​​​orThen(:IsDirtyPredicate)​​​​IsDirtyPredicate​

例如,您可以使用 OR 运算符组合两者:​​EqualsDirtyPredicate​​​​DeltaAwareDirtyPredicate​

组合使用逻辑 OR 运算符​​EqualsDirtyPredicate​​​​DeltaAwareDirtyPredicate​

@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;
}
}

然后与 and 组合回退的默认谓词,如下所示:​​CustomerDirtyPredicate​​​​AccountDirtyPredicate​

组合和配置特定于类型​​IsDirtyPredicates​

@EnableGemFireHttpSession
class ApplicationConfiguration {

@Bean
IsDirtyPredicate typeSpecificDirtyPredicate() {

return new CustomerDirtyPredicate()
.andThen(new AccountDirtyPredicate())
.andThen(IsDirtyPredicate.ALWAYS_DIRTY);
}
}

组合和可能性是无穷无尽的。

实施自定义策略时要小心。如果您错误地确定 应用程序域对象在实际脏时并不脏,那么它将不会在会话增量中发送 从客户端到服务器。​​IsDirtyPredicate​

更改会话表示形式

在内部,Apache Geode 的 Spring Session 维护 (HTTP) 会话和会话的 2 种表示形式 属性。每个表示形式都基于是否支持Apache Geode“增量”。

由于前面讨论过的原因,Apache Geode增量传播仅在使用数据序列化时由 Apache Geode 的春季会话启用。

实际上,该策略是:

  1. 如果配置了 Apache Geode数据序列化,则支持增量并使用 theand表示。DeltaCapableGemFireSessionDeltaCapableGemFireSessionAttributes
  2. 如果配置了 Apache Geode PDX序列化,则将禁用增量传播 并使用与表示。GemFireSessionGemFireSessionAttributes

可以覆盖Spring Session为Apache Geode和用户使用的这些内部表示。 以提供自己的会话相关类型。唯一严格的要求是会话实现 必须实现核心 Spring 会话接口。​​org.springframework.session.Session​

例如,假设您要定义自己的会话实现。

首先,定义类型。也许您的自定义类型甚至封装和处理会话 属性,而无需定义单独的类型。​​Session​​​​Session​

用户定义的会话接口实现

class MySession implements org.springframework.session.Session {
// ...
}

然后,您需要扩展类 并重写该方法以创建自定义实现类的实例。​​org.springframework.session.data.gemfire.GemFireOperationsSessionRepository​​​​createSession()​​​​Session​

自定义会话存储库实现创建和返回自定义会话类型的实例

class MySessionRepository extends GemFireOperationsSessionRepository {

@Override
public Session createSession() {
return new MySession();
}
}

如果您提供自己的自定义实现,并且 Apache Geode PDX序列化是 配置,然后你完成了。​​SessionSerializer​

但是,如果您配置了 Apache Geode数据序列化,则必须另外提供自定义 接口的实现,要么让它直接扩展Apache Geode的类,要么扩展Apache Geode的类的Spring Session。 并覆盖该方法。​​SessionSerializer​​​​org.apache.geode.DataSerializer​​​​org.springframework.session.data.gemfire.serialization.data.AbstractDataSerializableSessionSerializer​​​​getSupportedClasses():Class<?>[]​

例如:

自定义会话序列化程序用于自定义会话类型

class MySessionSerializer extends AbstractDataSerializableSessionSerializer {

@Override
public Class<?>[] getSupportedClasses() {
return new Class[] { MySession.class };
}
}

不幸的是,无法返回通用的 Spring 会话接口类型。如果可以,那么我们可以避免显式需要覆盖方法 自定义实现。但是,Apache Geode的数据序列化框架只能匹配 在确切的类类型上,因为它错误地在内部存储并按名称引用类类型,然后 要求用户重写和实现该方法。​​getSupportedClasses()​​​​org.springframework.session.Session​​​​getSupportedClasses()​​​​DataSerializer​​​​getSupportedClasses()​

3.7. HTTPSESSION集成的工作原理

幸运的是,bothand(用于 获取 an) 是接口。这意味着我们可以为每个 API 提供自己的实现。​​javax.servlet.http.HttpSession​​​​javax.servlet.http.HttpServletRequest​​​​HttpSession​

本节介绍春季会话如何提供透明的集成。 目的是让用户了解引擎盖下发生的事情。此功能已实现 并集成,因此您无需自己实现此逻辑。​​javax.servlet.http.HttpSession​

首先,我们创建一个 customReturna 的自定义实现。它看起来像下面这样:​​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 ...
}

任何返回 anis 的方法都被重写。所有其他方法都由原始实现实现,并简单地委托给原始实现。​​javax.servlet.http.HttpSession​​​​javax.servlet.http.HttpServletRequestWrapper​​​​javax.servlet.http.HttpServletRequest​

我们使用 Servletcall 替换实现。伪代码可以在下面找到:​​javax.servlet.http.HttpServletRequest​​​​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​​​​FilterChain​​​​Filter​​​​javax.servlet.http.HttpSession​

这突出了为什么春季会议必须放在任何事情之前很重要 与交互。​​SessionRepositoryFilter​​​​javax.servlet.http.HttpSession​

3.8. HttpSessionListener

春季会议通过翻译和声明支持。​​HttpSessionListener​​​​SessionCreatedEvent​​​​SessionDestroyedEvent​​​​HttpSessionEvent​​​​SessionEventHttpSessionListenerAdapter​

要使用此支持,您需要:

  • 确保您的实现支持并配置为触发和“会话已销毁事件”。SessionRepositorySessionCreatedEvent
  • 配置为春豆。SessionEventHttpSessionListenerAdapter
  • 将每个注入HttpSessionListenerSessionEventHttpSessionListenerAdapter

如果您使用的是HttpSession with Apache Geode 中记录的配置支持, 然后,您需要做的就是注册每个豆子。​​HttpSessionListener​

例如,假设您想要支持 Spring 安全性的并发控制并需要使用, 然后你可以简单地添加一个豆子。​​HttpSessionEventPublisher​​​​HttpSessionEventPublisher​

3.9. 会话

A是简化的键/值对,支持过期。​​Session​​​​Map​

3.10. 会话存储库

Ais 负责创建、持久化和访问实例和状态。​​SessionRepository​​​​Session​

如果可能,开发人员不应直接与 aor a 交互。相反,开发人员 应该更喜欢通过和集成间接地与之交互。​​SessionRepository​​​​Session​​​​SessionRepository​​​​Session​​​​javax.servlet.http.HttpSession​​​​WebSocket​​​​WebSession​

3.11. 查找按索引名称会话存储库

Spring Session 使用 ais 的最基本 API。该 API 有意非常简单 以便轻松提供具有基本功能的其他实现。​​Session​​​​SessionRepository​

某些实现可能会选择实现。 例如,Spring Session的Apache Geode支持实现。​​SessionRepository​​​​FindByIndexNameSessionRepository​​​​FindByIndexNameSessionRepository​

添加单个方法来查找特定用户的所有会话。 这是通过确保使用用户名填充具有名称的会话属性来完成的。开发人员有责任确保填充属性,因为 Spring 会话不知道正在使用的身份验证机制。​​FindByIndexNameSessionRepository​​​​FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME​


某些实现将提供钩子来自动索引其他会话属性。 例如,许多实现将自动确保当前 Spring 安全性用户名的索引为 索引名称。​​FindByIndexNameSessionRepository​​​​FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME​


3.12. 启用弹簧 httpSession

注释可以添加到任何类中,以在名为“springSessionRepositoryFilter”的Spring容器中公开Bean。​​@EnableSpringHttpSession​​​​@Configuration​​​​SessionRepositoryFilter​

为了利用注释,必须提供单豆。​​SessionRepository​

3.13. 启用宝石火 httpSession

可以将 theannotation 添加到任何类中来代替 theannotation,以在 Spring 容器中公开一个名为 bean, “springSessionRepositoryFilter”,并将 Apache Geode 定位为管理状态的提供者。​​@EnableGemFireHttpSession​​​​@Configuration​​​​@EnableSpringHttpSession​​​​SessionRepositoryFilter​​​​javax.servlet.http.HttpSession​

使用注释时,其他配置是开箱即用的导入的,这些配置也 提供了名为 Apache Geode 的接口的特定实现。​​@EnableGemFireHttpSession​​​​SessionRepository​​​​GemFireOperationsSessionRepository​

3.14. 宝石火操作会话存储库

​GemFireOperationsSessionRepository​​是使用春季会话实现的实现 对于Apache Geode's_。​​SessionRepository​​​​GemFireOperationsSessionRepository​

在 Web 环境中,此存储库与 一起使用。​​SessionRepositoryFilter​

此实现支持,并贯穿始终。​​SessionCreatedEvents​​​​SessionDeletedEvents​​​​SessionDestroyedEvents​​​​SessionEventHttpSessionListenerAdapter​

3.14.1. 在 Apache Geode 中使用索引

虽然关于正确定义对Apache Geode性能产生积极影响的索引的最佳实践 超出了本文档的范围,重要的是要认识到 Apache Geode 的春季会话创建 并使用索引有效地查询和查找会话。

开箱即用的 Apache Geode 春季会话在主体名称上创建 1 个哈希类型索引。有两个 用于查找主体名称的不同内置策略。第一个策略是会话的价值 具有名称的属性将被索引到相同的 索引名称。​​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 安全性结合使用

或者,Apache Geode 的春季会议将映射 Spring Security 的当前 指数。​​Authentication#getName()​​​​FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME​

例如,如果您使用的是 Spring 安全性,则可以使用以下方法查找当前用户的会话:

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​

此外,Apache Geode 的春季会议将在实施会话的 映射类型属性(即在任何任意会话属性上),当开发人员识别 1 个或多个时 应由 Apache Geode 编制索引的命名会话属性。​​attributes​

索引的会话属性可以使用注释上的属性指定。开发人员将此注释添加到他们的 Spring 应用程序类中,当他/她希望启用 Spring 会话的支持时,由 Apache Geode。​​indexableSessionAttributes​​​​@EnableGemFireHttpSession​​​​@Configuration​​​​HttpSession​

String indexName = "name1";

session.setAttribute(indexName, indexValue);
Map<String, Session> idToSessions =
this.sessionRepository.findByIndexNameAndIndexValue(indexName, indexValue);

只有在注释的属性中标识的会话属性名称才会定义索引。不会为所有其他会话属性编制索引。​​@EnableGemFireHttpSession​​​​indexableSessionAttributes​

但是,有一个问题。存储在可索引会话属性中的任何值都必须实现接口。如果这些对象值没有实现,则 Apache Geode 为具有持久会话数据的区域定义索引时,或者在尝试时,将在启动时引发错误 在运行时进行,以为可索引会话属性分配一个不是的值,并且会话被保存 到阿帕奇·乔德。​​java.lang.Comparable<T>​​​​Comparable​​​​Comparable​

任何未编制索引的会话属性都可以存储非值。​​Comparable​

要了解有关 Apache Geode 基于范围的索引的更多信息,请参阅在地图字段上创建索引。

要了解有关 Apache Geode 索引的更多信息,请参阅使用索引。

4. 春季会议社区

我们很高兴将您视为我们社区的一部分。 请在下面找到更多信息。

4.1. 支持

您可以通过在* 上使用标签spring-session 提问来获得帮助。 同样,我们鼓励通过回答*上的问题来帮助他人。

4.2. 源代码

源代码可以在GitHub上找到,网址为https://github.com/spring-projects/spring-session-data-geode

4.3. 问题跟踪

我们在 GitHub 问题中跟踪问题https://github.com/spring-projects/spring-session-data-geode/issues

4.4. 贡献

我们感谢拉取请求。

4.5. 许可

Apache Geode 的春季会议和 Pivotal GemFire 的春季会议是开源软件 在Apache 2.0 许可证下发布。

5. 最低要求

春季课程的最低要求是:

  • 爪哇 8+
  • 如果您在 Servlet 容器中运行(不是必需的),Servlet 2.5+
  • 如果您使用的是其他 Spring 库(不是必需的),则所需的最低版本是 Spring Framework 5.0.x。
  • ​@EnableGemFireHttpSession​​需要 Apache Geode 2.0.x 的 Spring Data 和 Pivotal GemFire 2.0.x 的 Spring Data。
  • ​@EnableGemFireHttpSession​​需要 Apache Geode 1.2.x 或 Pivotal GemFire 9.1.x。


春季会议的核心只有必需的依赖关系。​​spring-jcl​