参考指南
4. 文档结构
以下章节解释了 Spring Data for Apache Geode 提供的核心功能:
-
使用 Spring 容器引导 Apache Geode 描述了为配置、初始化和访问提供的配置支持 Apache Geode 缓存、区域和相关的分布式系统组件。
-
使用 Apache Geode API 介绍了 Apache Geode API 与各种数据访问功能之间的集成 在 Spring 中可用,例如基于模板的数据访问、异常转换、事务管理和缓存。
-
使用 Apache Geode 序列化介绍了 Apache Geode 对托管对象的序列化和反序列化的增强功能。
-
POJO 映射描述了使用 Spring Data 对存储在 Apache Geode 中的 POJO 的持久性映射。
-
Spring Data for Apache Geode 存储库描述了如何创建和使用 Spring Data Repositories 来访问数据 使用基本 CRUD 和简单的查询操作存储在 Apache Geode 中。
-
函数执行的注释支持描述了如何使用注释创建和使用 Apache Geode 函数 在数据所在的位置执行分布式计算。
-
连续查询 (CQ) 介绍如何使用 Apache Geode 的连续查询 (CQ) 功能 根据 Apache Geode 的 OQL(对象查询语言)。
-
在 Apache Geode 中引导 Spring ApplicationContext 介绍了如何使用配置和引导在 Apache Geode 服务器中运行的 Spring。
ApplicationContext
Gfsh
-
示例应用程序 描述了随发行版提供的示例,以说明各种功能 在 Spring Data for Apache Geode 中可用。
5. 使用 Spring 容器引导 Apache Geode
Spring Data for Apache Geode 提供 Apache Geode 内存数据网格 (IMDG) 的完整配置和初始化 使用 Spring IoC 容器。该框架包含多个类,以帮助简化 Apache Geode 组件,包括:缓存、区域、索引、DiskStores、函数、WAN 网关、 持久化备份和其他几个分布式系统组件,以支持各种应用程序用例 以最小的努力。
本部分假定您对 Apache Geode 有基本的了解。有关更多信息,请参阅 Apache Geode 产品文档。 |
5.1. 使用 Spring 而不是 Apache Geode 的优势cache.xml
Spring Data for Apache Geode 的 XML 命名空间支持 Apache Geode 内存数据网格 (IMDG) 的完整配置。 XML 命名空间是在 Spring 上下文中配置 Apache Geode 以正确管理 Spring 容器中的 Apache Geode 生命周期。在 Spring 中配置 Apache Geode 的另一种方法 context 使用基于 annotation 的配置。
虽然由于遗留原因,对 Apache Geode 本机的支持仍然存在,但 Apache Geode 应用程序开发人员
鼓励使用 XML 配置的人在 Spring XML 中执行所有操作,以利用许多美妙的功能
Spring 必须提供诸如模块化 XML 配置、属性占位符和覆盖之类的功能,
SPEL (Spring Expression Language) 和环境配置文件。
在 XML 命名空间的背后,Spring Data for Apache Geode 广泛使用 Spring 的模式来简化创建,
配置和 Apache Geode 组件的初始化。cache.xml
FactoryBean
Apache Geode 提供了多个回调接口,例如 、 、 和 、
允许开发人员添加自定义事件处理程序。使用 Spring 的 IoC 容器,你可以配置这些回调
作为普通的 Spring bean 并将它们注入到 Apache Geode 组件中。这是一个显著的改进
native ,它提供的配置选项相对有限,并且需要回调来实现
Apache Geode 的接口(参见 连接可声明
的组件 以了解你如何在 Spring 的容器中仍然使用)。CacheListener
CacheLoader
CacheWriter
cache.xml
Declarable
Declarables
此外,IDE (如 Spring Tool Suite(STS))为 Spring XML 名称空间提供了出色的支持。 包括代码补全、弹出注释和实时验证。
5.2. 使用 Core 命名空间
为了简化配置, Spring Data for Apache Geode 提供了一个专用的 XML 命名空间,用于配置核心 Apache Geode
组件。可以使用 Spring 的标准定义直接配置 bean。然而
所有 Bean 属性都是通过 XML 名称空间公开的,因此使用原始 Bean 定义几乎没有什么好处。<bean>
有关 Spring 中基于 XML Schema 的配置的更多信息,请参阅 Spring Framework 参考文档中的附录。 |
Spring Data Repository 支持使用单独的 XML 命名空间。有关更多信息,请参阅 Spring Data for Apache Geode 存储库 了解如何为 Apache Geode 存储库配置 Spring Data。 |
要使用 Spring Data for Apache Geode XML 命名空间,请在 Spring XML 配置元数据中声明它。 如下例所示:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:gfe="https://www.springframework.org/schema/geode" (1)(2)
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/geode https://www.springframework.org/schema/geode/spring-geode.xsd (3)
">
<bean id ... >
<gfe:cache ...> (4)
</beans>
1 | Spring Data for Apache Geode XML 命名空间前缀。任何名称都有效,但在整个参考文档中,使用的是 name。gfe |
2 | XML 命名空间前缀映射到 URI。 |
3 | XML 命名空间 URI 位置。请注意,即使该位置指向外部地址(确实存在 并且有效),则 Spring 在本地解析模式,因为它包含在 Spring Data for Apache Geode 库中。 |
4 | 使用带有前缀的 XML 命名空间的示例声明。gfe |
您可以将默认命名空间从 更改为 。这对于主要由
Apache Geode 组件,因为它避免了声明前缀。为此,请交换命名空间前缀声明
如以下示例所示:
|
5.3. 使用数据访问命名空间
除了核心 XML 命名空间 () 之外,Spring Data for Apache Geode 还提供了数据访问 XML 命名空间 ()、
这主要是为了简化 Apache Geode 客户端应用程序的开发。此命名空间
当前包含对 Apache Geode 存储库和函数执行的支持,以及一个提供便捷连接方式的标记
Apache Geode 集群。gfe
gfe-data
<datasource>
5.3.1. 连接到 Apache Geode 的简单方法
对于许多应用程序,使用默认值与 Apache Geode 数据网格的基本连接就足够了。
Spring Data for Apache Geode 的标签提供了一种访问数据的简单方法。数据源将创建 and 连接 。此外,它还会查询集群服务器中所有现有的根区域,并在
每个客户端都有一个(空的)客户端区域代理。<datasource>
ClientCache
Pool
<gfe-data:datasource>
<locator host="remotehost" port="1234"/>
</gfe-data:datasource>
该标记在语法上类似于 .它可以配置一个或多个嵌套 or 元素以连接到现有数据网格。此外,所有属性都可用于配置池
受支持。此配置会自动为集群成员上定义的每个区域创建 Client 端 Region bean
连接到 Locator,以便它们可以被 Spring Data 映射注释无缝引用 ()
并自动连接到应用程序类中。<datasource>
<gfe:pool>
locator
server
GemfireTemplate
当然,您可以显式配置客户端区域。例如,如果要在本地内存中缓存数据, 如下例所示:
<gfe-data:datasource>
<locator host="remotehost" port="1234"/>
</gfe-data:datasource>
<gfe:client-region id="Example" shortcut="CACHING_PROXY"/>
5.4. 配置缓存
要使用 Apache Geode,您需要创建新缓存或连接到现有缓存。使用当前版本
中,每个 VM 只能有一个打开的缓存(更严格地说,每个 )。在大多数情况下,
缓存只能创建一次。ClassLoader
本节介绍如何创建和配置适用于对等 (P2P) 的对等成员
拓扑和缓存服务器。成员还可用于独立应用程序和集成测试。
但是,在典型的生产系统中,大多数应用程序进程充当缓存客户端,而是创建一个实例。配置 Apache Geode ClientCache 和 Client Region 部分中对此进行了介绍。Cache Cache ClientCache |
可以使用以下简单声明创建具有 default configuration 的 Peer 节点:Cache
<gfe:cache/>
在 Spring 容器初始化期间,任何包含此缓存定义的内容都会注册一个,该 bean 将创建一个名为 的 Spring bean,该 bean 引用 Apache Geode 实例。
此 bean 引用现有的 bean,如果尚不存在,则引用新创建的 bean。由于没有
其他属性,则新创建的将应用默认缓存配置。ApplicationContext
CacheFactoryBean
gemfireCache
Cache
Cache
Cache
所有依赖于 the 的 Spring Data for Apache Geode 组件都遵循此命名约定,因此您无需显式声明
依赖性。如果您愿意,可以使用提供的 attribute 来显式依赖项
通过各种 SDG XML 命名空间元素。此外,您可以使用属性
如下:Cache
Cache
cache-ref
id
<gfe:cache id="myCache"/>
可以使用 Spring 完全配置 Apache Geode。但是,Apache Geode 的本机 XML 配置
file 、 。对于需要本地配置 Apache Geode 缓存的情况,
您可以使用属性
如下:Cache
cache.xml
cache-xml-location
<gfe:cache id="cacheConfiguredWithNativeCacheXml" cache-xml-location="classpath:cache.xml"/>
在此示例中,如果需要创建缓存,它将使用位于 Classpath 根目录中的名为
进行配置。cache.xml
该配置使用 Spring 的 Resource 抽象来定位文件。抽象允许使用各种搜索模式,具体取决于运行时环境
或在资源位置中指定的前缀(如果有)。Resource |
除了引用外部 XML 配置文件之外,您还可以指定使用 Spring 的任何支持功能的 Apache Geode System 属性。Properties
例如,你可以使用 namespace 中定义的元素来直接定义
或从属性文件加载属性,如下所示:properties
util
Properties
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:gfe="https://www.springframework.org/schema/geode"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/geode https://www.springframework.org/schema/geode/spring-geode.xsd
http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd
">
<util:properties id="gemfireProperties" location="file:/path/to/gemfire.properties"/>
<gfe:cache properties-ref="gemfireProperties"/>
</beans>
建议使用属性文件来外部化特定于环境的设置 在应用程序配置之外。
仅当需要创建新缓存时,缓存设置才适用。如果 VM 中已存在打开的缓存,则 这些设置将被忽略。 |
5.4.1. 高级缓存配置
对于高级缓存配置,该元素提供了许多作为属性公开的配置选项
或子元素,如下清单所示:cache
(1)
<gfe:cache
cache-xml-location=".."
properties-ref=".."
close="false"
copy-on-read="true"
critical-heap-percentage="90"
eviction-heap-percentage="70"
enable-auto-reconnect="false" (2)
lock-lease="120"
lock-timeout="60"
message-sync-interval="1"
pdx-serializer-ref="myPdxSerializer"
pdx-persistent="true"
pdx-disk-store="diskStore"
pdx-read-serialized="false"
pdx-ignore-unread-fields="true"
search-timeout="300"
use-bean-factory-locator="true" (3)
use-cluster-configuration="false" (4)
>
<gfe:transaction-listener ref="myTransactionListener"/> (5)
<gfe:transaction-writer> (6)
<bean class="org.example.app.gemfire.transaction.TransactionWriter"/>
</gfe:transaction-writer>
<gfe:gateway-conflict-resolver ref="myGatewayConflictResolver"/> (7)
<gfe:jndi-binding jndi-name="myDataSource" type="ManagedDataSource"/> (8)
</gfe:cache>
1 | 属性支持各种缓存选项。有关此示例中所示任何内容的更多信息,
请参阅 Apache Geode 产品文档。
该属性确定在关闭 Spring 应用程序上下文时是否应关闭缓存。
默认值为 .但是,对于多个应用程序上下文使用缓存
(常见于 Web 应用程序),请将此值设置为 .close true false |
2 | 将属性设置为 (默认值为 ) 可允许断开连接的 Apache Geode 成员
自动重新连接并重新加入 Apache Geode 集群。
有关更多详细信息,请参阅 Apache Geode 产品文档。enable-auto-reconnect true false |
3 | 将属性设置为 (默认为 ) 仅在
Spring (XML) 配置元数据和 Apache Geode 用于配置 Apache Geode 缓存节点
(无论是客户端还是对等体)。此选项允许 Apache Geode 组件(例如 )与 Spring 应用程序上下文中定义的 bean(例如 )自动连接。此选项通常为
与 结合使用。use-bean-factory-locator true false cache.xml CacheLoader cache.xml DataSource cache-xml-location |
4 | 将属性设置为 (默认值为 ) 可使 Apache Geode 成员能够
从 Locator 中检索基于集群的常见共享配置。
有关更多详细信息,请参阅 Apache Geode 产品文档。use-cluster-configuration true false |
5 | 使用 Bean 引用的回调声明示例。引用的 Bean 必须实现 TransactionListener。
可以实现 A 来处理与事务相关的事件(例如 afterCommit 和 afterRollback)。TransactionListener TransactionListener |
6 | 使用内部 Bean 声明的回调声明示例。Bean 必须实现 TransactionWriter。
这是一个可以否决交易的回调。TransactionWriter TransactionWriter |
7 | 使用 Bean 引用的回调声明示例。引用的 Bean
必须实现 https://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/util/GatewayConflictResolver.html [GatewayConflictResolver]。
A 是一个 -level 插件,用于决定如何处理事件
源自其他系统并通过 WAN 网关 到达。
它提供分布式 Region 创建服务。GatewayConflictResolver GatewayConflictResolver Cache |
8 | 声明 JNDI 绑定以在 Apache Geode 事务中登记外部 DataSource。 |
启用 PDX 序列化
前面的示例包括许多与 Apache Geode 的增强序列化框架 PDX 相关的属性。
虽然对 PDX 的完整讨论超出了本参考指南的范围,但重要的是要注意 PDX
通过注册 来启用,该 是通过设置属性来指定的。PdxSerializer
pdx-serializer
Apache Geode 提供了一个实现类 (),该类使用
Java 反射。但是,开发人员通常会提供自己的实现。属性的值
只是对实现该接口的 Spring bean 的引用。org.apache.geode.pdx.ReflectionBasedAutoSerializer
PdxSerializer
有关序列化支持的更多信息,请参阅使用 Apache Geode 序列化。
启用自动重新连接
将属性设置为 时应小心。<gfe:cache enable-auto-reconnect="[true|false*]>
true
通常,只有在使用 Spring Data for Apache Geode 的 XML 命名空间来配置
并引导添加到集群的新非应用程序 Apache Geode 服务器。换句话说,“auto-reconnect”
当 Spring Data for Apache Geode 用于开发和构建 Apache Geode 应用程序时,不应启用该
成为 Apache Geode 集群的对等成员。Cache
此限制的主要原因是,大多数 Apache Geode 应用程序使用对 Apache Geode 或 Region 的引用来执行数据访问操作。这些引用由 Spring 容器 “注入”
到应用程序组件(如 Repositories)中供应用程序使用。当对等成员强制
与集群的其余部分断开连接,可能是因为 Peer 成员变得无响应,或者
网络分区将一个或多个对等成员分成一个组,该组太小而无法作为独立的
分布式系统、对等成员关闭以及所有 Apache Geode 组件引用(缓存、区域、
和其他)变为无效。Cache
本质上,每个 peer member 中的当前 forced disconnect processing logic 从头开始拆除系统。 JGroups 堆栈关闭,分布式系统处于关闭状态,最后,高速缓存关闭。 实际上,所有内存引用都会过时并丢失。
与分布式系统断开连接后,对等成员会进入 “reconnecting” 状态,并定期 尝试重新加入分布式系统。如果对等成员成功重新连接,则该成员将重建其 “视图” 的分布式系统,并接收新的分布式系统 ID。此外,所有缓存 区域和其他 Apache Geode 组件将被重建。因此,所有旧的引用,可能已经 由 Spring 容器注入到应用程序中,现在已过时且不再有效。
Apache Geode 不保证(即使使用 Apache Geode 公共 Java API)应用程序缓存、 区域或其他组件引用由 reconnect 操作自动刷新。因此,Apache Geode 应用程序必须注意刷新自己的引用。
遗憾的是,无法收到断开连接事件的通知,也无法收到随后的重新连接事件的通知。
如果是这种情况,您将有一种清晰的方法来知道何时调用 ,
如果它甚至适用于应用程序这样做,这就是为什么 Apache Geode 的这个“功能”不是
推荐用于对等应用程序。ConfigurableApplicationContext.refresh()
Cache
有关“自动重新连接”的更多信息,请参阅 Apache Geode 的产品文档。
使用基于集群的配置
Apache Geode 的集群配置服务是加入集群的任何对等成员都可以获取的便捷方式 集群的 “一致视图” ,方法是使用由 Locator 维护的共享持久配置。 使用基于集群的配置可确保对等成员的配置与 Apache Geode 兼容 成员加入时的分布式系统。
Spring Data for Apache Geode 的此功能(将属性设置为 )的工作方式相同
作为属性,除了 Apache Geode 配置元数据的来源
通过定位器从网络,而不是驻留在本地文件系统中的本机文件。use-cluster-configuration
true
cache-xml-location
cache.xml
所有 Apache Geode 本机配置元数据,无论是来自还是来自 Cluster Configuration Service,
在任何 Spring (XML) 配置元数据之前应用。因此, Spring 的配置用于“增强”这个
本机 Apache Geode 配置元数据,并且很可能特定于应用程序。cache.xml
同样,要启用此功能,请在 Spring XML 配置中指定以下内容:
<gfe:cache use-cluster-configuration="true"/>
虽然某些 Apache Geode 工具(例如 Gfsh)在类似架构的更改时会“记录”其操作
创建(例如),Spring Data for Apache Geode 的配置元数据
未录制。直接使用 Apache Geode 的公共 Java API 时也是如此。它也没有被记录下来。gfsh>create region --name=Example --type=PARTITION |
有关 Apache Geode 的集群配置服务的更多信息,请参阅产品文档。
5.4.2. 配置 Apache Geode CacheServer
Spring Data for Apache Geode 包括对配置 CacheServer 的专门支持, 允许通过 Spring 容器完成配置,如下例所示:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:gfe="https://www.springframework.org/schema/geode"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
https://www.springframework.org/schema/geode https://www.springframework.org/schema/geode/spring-geode.xsd
">
<gfe:cache/>
<!-- Example depicting serveral Apache Geode CacheServer configuration options -->
<gfe:cache-server id="advanced-config" auto-startup="true"
bind-address="localhost" host-name-for-clients="localhost" port="${gemfire.cache.server.port}"
load-poll-interval="2000" max-connections="22" max-message-count="1000" max-threads="16"
max-time-between-pings="30000" groups="test-server">
<gfe:subscription-config eviction-type="ENTRY" capacity="1000" disk-store="file://${java.io.tmpdir}"/>
</gfe:cache-server>
<context:property-placeholder location="classpath:cache-server.properties"/>
</beans>
前面的配置显示了元素和许多可用选项。cache-server
此配置不是对端口进行硬编码,而是使用 Spring 的上下文名称空间来声明 .属性占位符读取一个或多个属性文件,然后在运行时将属性占位符替换为值。这样做可以让管理员
更改值,而不必触摸主应用程序配置。Spring 还提供了 SPEL 和环境抽象,以支持从主代码库外部化特定于环境的属性,从而简化跨多台机器的部署。property-placeholder |
为避免初始化问题,由 Spring Data for Apache Geode 启动的 API 在 Spring 容器之后启动
已完全初始化。这样做可以让定义
以声明方式在服务器开始接受连接之前完全初始化和注册。请记住这一点
以编程方式配置这些元素时,因为服务器可能在组件之前启动,因此看不到
通过客户端立即连接。CacheServer |
5.4.3. 配置 Apache Geode ClientCache
除了定义 Apache Geode 对等缓存
之外,
Spring Data for Apache Geode 还支持在 Spring 容器中定义 Apache Geode ClientCache
。定义在配置和使用上类似于 Apache Geode 对等缓存,并且受 .ClientCache
org.springframework.data.gemfire.client.ClientCacheFactoryBean
使用默认配置的 Apache Geode 缓存客户端的最简单定义如下:
<beans>
<gfe:client-cache/>
</beans>
client-cache
支持许多与 Cache 元素相同的选项。然而,与
对于成熟的对等成员,缓存客户端通过 Pool 连接到远程缓存服务器。默认情况下,
创建一个池以连接到在端口 上运行并侦听 port 的服务器。使用默认 Pool
由所有客户端区域分配,除非该区域配置为使用特定池。Cache
localhost
40404
可以使用 element 定义池。此客户端 Pool 可用于配置直接连接到
通过一个或多个 Locator 为单个实体或整个缓存提供的服务器。pool
例如,要自定义 使用的默认 Pool,开发人员需要定义一个 Pool 并将其连线
添加到缓存定义中,如下例所示:client-cache
<beans>
<gfe:client-cache id="myCache" pool-name="myPool"/>
<gfe:pool id="myPool" subscription-enabled="true">
<gfe:locator host="${gemfire.locator.host}" port="${gemfire.locator.port}"/>
</gfe:pool>
</beans>
该元素还具有一个属性。如果该属性设置为 ,则客户端缓存
初始化包括对 ClientCache.readyForEvents() 的
调用。<client-cache>
ready-for-events
true
Client Region 更详细地介绍了客户端配置。
Apache Geode 的 DEFAULT 池和 Spring Data for Apache Geode 池定义
如果 Apache Geode 仅限本地使用,则不需要 Pool 定义。例如,您可以定义
以下内容:ClientCache
<gfe:client-cache/>
<gfe:client-region id="Example" shortcut="LOCAL"/>
在这种情况下,“示例”区域是,并且没有数据在客户端和服务器之间分发。因此
不需要 Pool。这适用于由 Apache Geode 的 ClientRegionShortcut
(所有快捷方式)定义的任何客户端仅限本地的区域。LOCAL
LOCAL_*
但是,如果客户端区域是服务器端区域的(缓存)代理,则需要 Pool。在这种情况下, 有几种方法可以定义和使用池。
当 a 、 一个 Pool 和基于代理的区域都已定义但未明确标识时, Spring Data for Apache Geode
自动解析引用,如下例所示:ClientCache
<gfe:client-cache/>
<gfe:pool>
<gfe:locator host="${geode.locator.host}" port="${geode.locator.port}"/>
</gfe:pool>
<gfe:client-region id="Example" shortcut="PROXY"/>
在前面的示例中,将 标识为 ,将 池标识为 、
将客户区域设置为 “Example”。但是,初始化 Apache Geode 的池
from ,客户端区域在客户端之间分配数据时使用
和服务器。ClientCache
gemfireCache
gemfirePool
ClientCache
DEFAULT
gemfirePool
gemfirePool
基本上,Spring Data for Apache Geode 将上述配置解析为以下内容:
<gfe:client-cache id="gemfireCache" pool-name="gemfirePool"/>
<gfe:pool id="gemfirePool">
<gfe:locator host="${geode.locator.host}" port="${geode.locator.port}"/>
</gfe:pool>
<gfe:client-region id="Example" cache-ref="gemfireCache" pool-name="gemfirePool" shortcut="PROXY"/>
Apache Geode 仍会创建一个名为 .Spring Data for Apache Geode 会导致池初始化
从 .在定义了多个 Pools 并且 client Region 的情况下,这样做非常有用
使用单独的 Pools,或者根本不声明 Pool。DEFAULT
DEFAULT
gemfirePool
请考虑以下事项:
<gfe:client-cache pool-name="locatorPool"/>
<gfe:pool id="locatorPool">
<gfe:locator host="${geode.locator.host}" port="${geode.locator.port}"/>
</gfe:pool>
<gfe:pool id="serverPool">
<gfe:server host="${geode.server.host}" port="${geode.server.port}"/>
</gfe:pool>
<gfe:client-region id="Example" pool-name="serverPool" shortcut="PROXY"/>
<gfe:client-region id="AnotherExample" shortcut="CACHING_PROXY"/>
<gfe:client-region id="YetAnotherExample" shortcut="LOCAL"/>
在此设置中,Apache Geode 池从 、
由 属性指定。没有 Spring Data for Apache Geode-defined ,因为两个 Pools
分别被明确标识(命名)和 。client-cache
DEFAULT
locatorPool
pool-name
gemfirePool
locatorPool
serverPool
“示例”区域明确引用并专门使用 .区域使用
Apache Geode 的 Pool,同样,它是从客户端缓存配置的
bean 定义的属性。serverPool
AnotherExample
DEFAULT
locatorPool
pool-name
最后,Region 不使用 Pool,因为它是 。YetAnotherExample
LOCAL
区域将首先查找名为 的 Pool Bean,但这需要
匿名 Pool bean (即 ) 或显式命名的 Pool bean 的定义 (例如。 )。AnotherExample gemfirePool <gfe:pool/> gemfirePool <gfe:pool id="gemfirePool"/> |
如果我们更改了 的名称 或 使 Pool bean 定义为匿名,
它将具有与前面的配置相同的效果。locatorPool gemfirePool |
5.5. 配置区域
需要一个区域来存储和检索缓存中的数据。 是一个接口
使用熟悉的键值语义扩展并启用基本数据访问。界面
连接到需要它的应用程序类中,因此实际的 Region 类型与编程模型分离。
通常,每个区域都与一个域对象相关联,类似于关系数据库中的表。org.apache.geode.cache.Region
java.util.Map
Region
Apache Geode 实现以下类型的区域:
-
REPLICATE – 在定义区域的集群中的所有缓存成员之间复制数据。这提供了 读取性能非常高,但执行复制需要更长的时间。
-
PARTITION - 数据在集群中的许多缓存成员中分区(分片),这些缓存成员定义 区域。这提供了较高的读写性能,适用于过大的大型数据集 对于单个节点。
-
LOCAL - 数据仅存在于本地节点上。
-
客户端 – 从技术上讲,客户区域是充当 REPLICATE 或 PARTITION 区域的代理的 LOCAL 区域 托管在集群中的缓存服务器上。它可以保存在本地创建或获取的数据。或者,它可以为空。 本地更新将同步到缓存服务器。此外,客户区域可以订阅事件,以便 与来自访问同一服务器区域的远程进程的更改保持同步(同步)。
有关各种区域类型及其功能以及配置选项的更多信息, 请参阅 Apache Geode 的 Region Types 文档。
5.5.1. 使用外部配置的 Region
要引用已在 Apache Geode 本机文件中配置的区域,请使用 element.
只需使用 attribute 声明目标 Region 名称即可。例如,要声明标识的 bean 定义
对于名为 的现有 Region,您可以使用以下 bean 定义:cache.xml
lookup-region
name
ordersRegion
Orders
<gfe:lookup-region id="ordersRegion" name="Orders"/>
如果未指定,则 Bean 将用作 Region 的名称。上面的示例变为:name
id
<!-- lookup for a Region called 'Orders' -->
<gfe:lookup-region id="Orders"/>
如果 Region 不存在,则会引发初始化异常。要配置新区域, 请继续阅读下面的相应部分。 |
在前面的示例中,由于没有明确定义缓存名称,因此默认的命名约定 ()
被使用。或者,可以使用以下属性引用缓存 Bean:gemfireCache
cache-ref
<gfe:cache id="myCache"/>
<gfe:lookup-region id="ordersRegion" name="Orders" cache-ref="myCache"/>
lookup-region
允许您检索现有的预配置区域,而无需公开区域语义
或设置基础设施。
5.5.2. 自动区域查找
auto-region-lookup
用于将 Apache Geode 本机文件中定义的所有区域导入到
一个 Spring。cache.xml
ApplicationContext
cache-xml-location
<gfe:cache>
例如,请考虑以下文件:cache.xml
<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="https://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">
<region name="Parent" refid="REPLICATE">
<region name="Child" refid="REPLICATE"/>
</region>
</cache>
您可以按如下方式导入上述文件:cache.xml
<gfe:cache cache-xml-location="cache.xml"/>
然后,您可以使用元素(例如 )来引用
特定 Region 作为 Spring 容器中的 bean,或者您可以选择使用以下命令导入中定义的所有 Region:<gfe:lookup-region>
<gfe:lookup-region id="Parent"/>
cache.xml
<gfe:auto-region-lookup/>
Spring Data for Apache Geode 会自动为 中定义的所有尚未定义的 Apache Geode 区域创建 bean
使用显式 bean 声明显式添加到 Spring 容器中。cache.xml
<gfe:lookup-region>
重要的是要认识到 Spring Data for Apache Geode 在创建和初始化缓存后使用 Spring BeanPostProcessor 对缓存进行后处理,以确定 Apache Geode 中定义的区域
以在 Spring 中添加为 bean 。ApplicationContext
您可以像注入 Spring 中定义的任何其他 bean 一样注入这些 “auto-looked-up” 区域 ,
但有一个例外:您可能需要定义与 'gemfireCache' bean 的关联,如下所示:ApplicationContext
depends-on
package example;
@Repository("appDao")
@DependsOn("gemfireCache")
public class ApplicationDao extends DaoSupport {
@Resource(name = "Parent")
private Region<?, ?> parent;
@Resource(name = "/Parent/Child")
private Region<?, ?> child;
...
}
前面的示例仅在您使用 Spring 的功能时适用。component-scan
如果使用 Spring XML 配置声明组件,则将执行以下操作:
<bean class="example.ApplicationDao" depends-on="gemfireCache"/>
这样做可确保 Apache Geode 缓存和中定义的所有区域在之前创建
使用元素时具有自动连线参考的任何元件。cache.xml
<gfe:auto-region-lookup>
5.5.3. 配置区域
Spring Data for Apache Geode 通过以下元素为配置任何类型的区域提供全面支持:
-
本地区域:
<local-region>
-
PARTITION 区域:
<partitioned-region>
-
REPLICATE 区域:
<replicated-region>
-
客户区域:
<client-region>
请参阅 Apache Geode 文档,了解区域类型的全面说明。
公共区域属性
下表列出了可用于所有 Region 类型的属性:
名字 | 值 | 描述 |
---|---|---|
缓存引用 |
Apache Geode Cache Bean 参考 |
定义 Apache Geode Cache 的 Bean 的名称(默认情况下为 'gemfireCache')。 |
已启用克隆 |
boolean (默认值: |
当 时,更新将应用于该值的克隆,然后将克隆保存到缓存中。当 时,该值将在缓存中就地修改。 |
关闭 |
boolean (默认值: |
确定是否应在关闭时关闭区域。 |
已启用并发检查 |
boolean (默认值: |
确定成员是否执行检查以对分布式区域的并发更新或无序更新提供一致的处理。 |
数据策略 |
请参阅 Apache Geode 的数据策略。 |
区域的数据策略。请注意,并非每种区域类型都支持所有数据策略。 |
摧毁 |
boolean (默认值: |
确定是否应在关闭时销毁区域。 |
磁盘存储引用 |
已配置磁盘存储的名称。 |
对通过元素创建的 Bean 的引用。 |
磁盘同步 |
boolean (默认值: |
确定磁盘存储写入是否同步。 |
身份证 |
任何有效的 bean 名称。 |
如果未指定属性,则为默认区域名称。 |
忽略 if exists |
boolean (默认值: |
如果缓存中已存在区域,则忽略此 bean 定义,从而导致查找。 |
忽略 JTA |
boolean (默认值: |
确定此区域是否参与 JTA(Java 事务 API)事务。 |
索引更新类型 |
|
确定在创建条目时是同步更新还是异步更新 Indices。 |
初始容量 |
integer (默认值: 16) |
Region 条目数的初始内存分配。 |
键约束 |
任何有效的、完全限定的 Java 类名。 |
预期的密钥类型。 |
负载系数 |
float (默认值: .75) |
设置用于存储区域条目的基础上的初始参数。 |
名字 |
任何有效的区域名称。 |
区域的名称。如果未指定,则采用属性的值(即 Bean 名称)。 |
持续 |
*boolean (默认值: |
确定区域是否将条目保存到本地磁盘(磁盘存储)。 |
捷径 |
查看 https://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/RegionShortcut.html |
对于这个地区。允许根据预定义的默认值轻松初始化区域。 |
统计学 |
boolean (默认值: |
确定区域是否报告统计信息。 |
模板 |
区域模板的名称。 |
对通过其中一个元素创建的 bean 的引用。 |
值约束 |
任何有效的、完全限定的 Java 类名。 |
预期值类型。 |
CacheListener
实例
CacheListener
实例注册到 Region 以处理 Region 事件,例如在创建条目时,
updated、destroyed 等。A 可以是实现 CacheListener
接口的任何 bean。
一个 Region 可以有多个侦听器,这些侦听器使用嵌套在包含元素中的元素进行声明。CacheListener
cache-listener
*-region
以下示例有两个声明的 .第一个引用了一个命名的顶级 Spring bean。
第二个是匿名的内部 Bean 定义。CacheListener’s
<bean id="myListener" class="org.example.app.geode.cache.SimpleCacheListener"/>
<gfe:replicated-region id="regionWithListeners">
<gfe:cache-listener>
<!-- nested CacheListener bean reference -->
<ref bean="myListener"/>
<!-- nested CacheListener bean definition -->
<bean class="org.example.app.geode.cache.AnotherSimpleCacheListener"/>
</gfe:cache-listener>
</gfe:replicated-region>
下面的示例使用具有 attribute 的元素的替代形式。
这样做可以在定义单个 .cache-listener
ref
CacheListener
注意:XML 命名空间只允许单个元素,因此
必须使用前面的示例或以下示例中的 style。cache-listener
<beans>
<gfe:replicated-region id="exampleReplicateRegionWithCacheListener">
<gfe:cache-listener ref="myListener"/>
</gfe:replicated-region>
<bean id="myListener" class="example.CacheListener"/>
</beans>
在元素中使用 和 嵌套声明是非法的。
这两个选项是互斥的,在同一元素中同时使用这两个选项会导致异常。ref cache-listener |
Bean 引用约定
该元素是 Apache Geode 任何位置的 XML 命名空间中使用的常见模式的示例
提供要实现的回调接口,以便调用自定义代码以响应缓存或 Region 事件。
当您使用 Spring 的 IoC 容器时,实现是标准的 Spring bean。为了简化配置,
架构允许元素的单个出现,但是,如果允许多个实例,则
它可以包含嵌套 Bean 引用和内部 Bean 定义的任意组合。惯例是使用
单数形式(即 VS ),反映最常见的情况是
实际上,一个实例。我们已经在 advanced cache configuration 示例中看到了这种模式的示例。 |
CacheLoader 和 CacheWriters
与 类似,XML 命名空间提供 and 元素来注册
区域的这些 Apache Geode 组件。cache-listener
cache-loader
cache-writer
在缓存未命中时调用 A,以允许从外部数据源(如数据库)加载条目。
在创建或更新条目之前调用 A,以允许将条目同步到外部
数据源。主要区别在于,Apache Geode 最多支持每个区域的单个实例。但是,可以使用任一声明样式。CacheLoader
CacheWriter
CacheLoader
CacheWriter
以下示例声明一个同时具有 a 和 a 的 Region :CacheLoader
CacheWriter
<beans>
<gfe:replicated-region id="exampleReplicateRegionWithCacheLoaderAndCacheWriter">
<gfe:cache-loader ref="myLoader"/>
<gfe:cache-writer>
<bean class="example.CacheWriter"/>
</gfe:cache-writer>
</gfe:replicated-region>
<bean id="myLoader" class="example.CacheLoader">
<property name="dataSource" ref="mySqlDataSource"/>
</bean>
<!-- DataSource bean definition -->
</beans>
有关更多详细信息,请参阅 Apache Geode 文档中的 CacheLoader
和 CacheWriter
。
5.5.4. 压缩
Apache Geode 区域也可以进行压缩,以减少 JVM 内存消耗和可能的压力 避免全局 GC。当您为区域启用压缩时,存储在该区域内存中的所有值都将被压缩。 而键和索引保持未压缩状态。新值在放入 Region 时被压缩,所有值 在从区域读回时自动解压缩。值在持久保存到磁盘时不压缩 或者通过网络发送给其他对等成员或客户端时。
以下示例显示了启用了压缩的区域:
<beans>
<gfe:replicated-region id="exampleReplicateRegionWithCompression">
<gfe:compressor>
<bean class="org.apache.geode.compression.SnappyCompressor"/>
</gfe:compressor>
</gfe:replicated-region>
</beans>
有关区域压缩的更多信息,请参阅 Apache Geode 的文档。
5.5.5. 堆外
Apache Geode 区域也可以配置为将 Region 值存储在堆外内存中,堆外内存是 不受垃圾回收 (GC) 约束的 JVM 内存。通过避免昂贵的 GC 周期,您的应用 可以将更多时间花在重要的事情上,比如处理请求。
使用堆外内存非常简单,只需声明要使用的内存量,然后启用您的区域 使用堆外内存,如以下配置所示:
<util:properties id="gemfireProperties">
<prop key="off-heap-memory-size">200G</prop>
</util:properties>
<gfe:cache properties-ref="gemfireProperties"/>
<gfe:partitioned-region id="ExampleOffHeapRegion" off-heap="true"/>
您可以通过设置以下 Apache Geode 配置来控制堆外内存管理的其他方面
使用 element:s 的属性<gfe:cache>
<gfe:cache critical-off-heap-percentage="90" eviction-off-heap-percentage"80"/>
Apache Geode将使用这两个阈值(& )以几乎相同的方式更有效地管理堆外内存
就像 JVM 在管理堆内存时所做的那样。Apache Geode 将阻止缓存
避免通过逐出旧数据来消耗过多的堆外内存。如果 off-heap manager 无法跟上,
然后 Refuses 向 cache 添加内容,直到 off-heap memory manager 释放为止
足够的内存量。ResourceManager
critical-off-heap-percentage
eviction-off-heap-percentage
ResourceManager
ResourceManager
有关管理堆和堆外内存的更多信息,请参阅 Apache Geode 的文档。
具体来说,请阅读 管理堆外内存 部分。
5.5.6. 子区域
Spring Data for Apache Geode 还支持子区域,允许以分层关系排列区域。
例如,Apache Geode 允许一个区域和一个不同的区域。
此外,子区域可能有自己的子区域和配置。子区域不继承属性
从其父区域。区域类型可以根据 Apache Geode 约束进行混合和匹配。A 子区域
自然声明为 Region 的子元素。Sub-Region 的属性是简单名称。
前面的示例可能配置如下:/Customer/Address
/Employee/Address
name
<beans>
<gfe:replicated-region name="Customer">
<gfe:replicated-region name="Address"/>
</gfe:replicated-region>
<gfe:replicated-region name="Employee">
<gfe:replicated-region name="Address"/>
</gfe:replicated-region>
</beans>
请注意,Sub-Region 不允许使用该属性。使用 Bean 名称创建 Sub-Region
(在本例中分别为 /Customer/Address 和 /Employee/Address)。因此,它们可能会被注入到其他应用程序中
bean (例如 a ),这些 bean 通过使用 Region 的完整路径名需要它们。完整路径名
还应在 OQL 查询字符串中使用。Monospaced ([id])
GemfireTemplate
5.5.7. 区域模板
Spring Data for Apache Geode 还支持区域模板。
此功能允许开发人员一次性定义通用区域配置和属性,然后重用配置
在 Spring 中声明的许多 Region bean 定义中。ApplicationContext
Spring Data for Apache Geode 在其命名空间中包含五个区域模板标签:
标签名称 | 描述 |
---|---|
|
定义常见的通用 Region 属性。在 XML 命名空间中扩展。 |
|
定义常见的 'Local' Region 属性。在 XML 命名空间中扩展。 |
|
定义常见的 'PARTITION' Region 属性。在 XML 命名空间中扩展。 |
|
定义常见的 'REPLICATE' Region 属性。在 XML 命名空间中扩展。 |
|
定义常见的 'Client' Region 属性。在 XML 命名空间中扩展。 |
除了标签之外,具体元素(以及抽象元素)
具有一个属性,用于定义 Region 从中继承其配置的区域模板。
区域模板甚至可以从其他区域模板继承。<gfe:*-region>
<gfe:*-region-template>
template
以下示例显示了一种可能的配置:
<beans>
<gfe:async-event-queue id="AEQ" persistent="false" parallel="false" dispatcher-threads="4">
<gfe:async-event-listener>
<bean class="example.AeqListener"/>
</gfe:async-event-listener>
</gfe:async-event-queue>
<gfe:region-template id="BaseRegionTemplate" initial-capacity="51" load-factor="0.85" persistent="false" statistics="true"
key-constraint="java.lang.Long" value-constraint="java.lang.String">
<gfe:cache-listener>
<bean class="example.CacheListenerOne"/>
<bean class="example.CacheListenerTwo"/>
</gfe:cache-listener>
<gfe:entry-ttl timeout="600" action="DESTROY"/>
<gfe:entry-tti timeout="300 action="INVLIDATE"/>
</gfe:region-template>
<gfe:region-template id="ExtendedRegionTemplate" template="BaseRegionTemplate" load-factor="0.55">
<gfe:cache-loader>
<bean class="example.CacheLoader"/>
</gfe:cache-loader>
<gfe:cache-writer>
<bean class="example.CacheWriter"/>
</gfe:cache-writer>
<gfe:async-event-queue-ref bean="AEQ"/>
</gfe:region-template>
<gfe:partitioned-region-template id="PartitionRegionTemplate" template="ExtendedRegionTemplate"
copies="1" load-factor="0.70" local-max-memory="1024" total-max-memory="16384" value-constraint="java.lang.Object">
<gfe:partition-resolver>
<bean class="example.PartitionResolver"/>
</gfe:partition-resolver>
<gfe:eviction type="ENTRY_COUNT" threshold="8192000" action="OVERFLOW_TO_DISK"/>
</gfe:partitioned-region-template>
<gfe:partitioned-region id="TemplateBasedPartitionRegion" template="PartitionRegionTemplate"
copies="2" local-max-memory="8192" persistent="true" total-buckets="91"/>
</beans>
区域模板也适用于子区域。请注意,'TemplateBasedPartitionRegion' 扩展了 'PartitionRegionTemplate', 它扩展了 'ExtendedRegionTemplate',它扩展了 'BaseRegionTemplate'。中定义的属性和子元素 随后,继承的 Region bean 定义将覆盖父 bean 中的内容。
模板的工作原理
Spring Data for Apache Geode 在解析 Spring 配置元数据时应用区域模板,因此,
区域模板必须按继承顺序声明。换句话说,父模板必须在
子模板。这样做可以确保应用正确的配置,尤其是在元素属性
或子元素被覆盖。ApplicationContext
同样重要的是要记住,Region 类型只能从其他类型相似的 Region 继承。
例如,a 不可能从 继承 。<gfe:replicated-region> <gfe:partitioned-region-template> |
区域模板是单继承的。 |
关于区域、子区域和查找的注意事项
以前,,
Spring Data for Apache Geode XML 命名空间中的元素在尝试之前先执行查找
创建一个区域。如果 Region 已经存在,则执行此操作,如果定义了 Region,则会出现这种情况
在导入的 Apache Geode 本机配置文件中。因此,首先执行查找
以避免任何错误。这是设计使然,可能会发生变化。replicated-region
partitioned-region
local-region
client-region
cache.xml
此行为已更改,现在的默认行为是先创建 Region。如果区域
already exists,则创建逻辑会快速失败并引发相应的异常。但是,与 DDL 语法非常相似,Spring Data for Apache Geode XML 命名空间元素现在包括
一个属性,它通过首先执行现有 Region 的查找来恢复旧行为
在尝试创建区域之前按名称标识。如果按名称找到现有 Region 并将其设置为 ,则忽略 Spring 配置中定义的 Region bean 定义。CREATE TABLE IF NOT EXISTS …
<gfe:*-region>
ignore-if-exists
ignore-if-exists
true
Spring 团队强烈建议将 、 、 、 、
和 XML 命名空间元素严格用于定义新区域。可能出现的一个问题
当这些元素定义的 Region 已存在并且 Region 元素首先执行查找时,如果
您在
application config,则区域定义可能不匹配,并且可能会表现出与所需定义相反的行为
由应用程序。更糟糕的是,您可能希望将 Region 定义为分布式 Region(例如,)
而实际上,现有 Region 定义仅为本地定义。replicated-region partitioned-region local-region client-region PARTITION |
建议的做法 - 仅使用 、 、 和 XML 命名空间元素来定义新区域。replicated-region partitioned-region local-region client-region |
请考虑以下本机 Apache Geode 配置文件:cache.xml
<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="https://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">
<region name="Customers" refid="REPLICATE">
<region name="Accounts" refid="REPLICATE">
<region name="Orders" refid="REPLICATE">
<region name="Items" refid="REPLICATE"/>
</region>
</region>
</region>
</cache>
此外,假设您可能已定义应用程序 DAO,如下所示:
public class CustomerAccountDao extends GemDaoSupport {
@Resource(name = "Customers/Accounts")
private Region customersAccounts;
...
}
在这里,我们在应用程序 DAO 中注入对 Region 的引用。因此,它是
开发人员在 Spring XML 配置中为部分或全部 Region 定义 bean 的情况并不少见
元数据,如下所示:Customers/Accounts
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:gfe="https://www.springframework.org/schema/geode"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/geode https://www.springframework.org/schema/geode/spring-geode.xsd
">
<gfe:cache cache-xml-location="classpath:cache.xml"/>
<gfe:lookup-region name="Customers/Accounts"/>
<gfe:lookup-region name="Customers/Accounts/Orders"/>
</beans>
和 Region 在 Spring 容器中被引用为 bean
as 和 ,分别。使用元素和相应的语法(如前所述)的好处是,它允许您直接引用子区域,而无需
不必要地为父 Region 定义一个 Bean(在本例中)。Customers/Accounts
Customers/Accounts/Orders
Customers/Accounts
Customers/Accounts/Orders
lookup-region
Customers
请考虑以下错误示例,该示例将配置元数据语法更改为使用嵌套格式:
<gfe:lookup-region name="Customers">
<gfe:lookup-region name="Accounts">
<gfe:lookup-region name="Orders"/>
</gfe:lookup-region>
</gfe:lookup-region>
现在考虑另一个错误的示例,它使用 top-level 元素和
属性设置为 Perform a lookup first:replicated-region
ignore-if-exists
<gfe:replicated-region name="Customers" persistent="true" ignore-if-exists="true">
<gfe:replicated-region name="Accounts" persistent="true" ignore-if-exists="true">
<gfe:replicated-region name="Orders" persistent="true" ignore-if-exists="true"/>
</gfe:replicated-region>
</gfe:replicated-region>
Spring 中定义的 Region bean 包括以下内容:这意味着依赖项注入引用
前面的示例中显示的(即 )现在已损坏,因为实际上没有定义具有 name 的 bean。因此,您不应按照
前面的两个示例。ApplicationContext
{ "Customers", "/Customers/Accounts", "/Customers/Accounts/Orders" }.
@Resource(name = "Customers/Accounts")
Customers/Accounts
Apache Geode 可以灵活地引用父区域和子区域,带或不带前导
斜线。例如,父项可以作为 or 引用,子项可以作为 or 引用。但是, Spring Data for Apache Geode 在以 Region 命名 bean 时非常具体。它总是
使用正斜杠 (/) 表示子区域(例如)。/Customers
Customers
/Customers/Accounts
Customers/Accounts
/Customers/Accounts
因此,您应该使用前面显示的非嵌套语法,或者使用
前导正斜杠 (/),如下所示:lookup-region
<gfe:lookup-region name="/Customers/Accounts"/>
<gfe:lookup-region name="/Customers/Accounts/Orders"/>
前面的示例(其中嵌套元素用于引用 Sub-Region)显示了
前面提到的问题。客户、账户和订单区域以及子区域是否持久?
它们不是持久的,因为区域是在本机 Apache Geode 配置文件中定义的
as 和 exist 在缓存 bean 初始化之前(一旦元素被处理)。replicated-region
cache.xml
REPLICATE
<gfe:cache>
5.5.8. 数据驱逐(使用 Overflow)
根据各种约束,每个区域都可以有一个驱逐策略,用于从内存中驱逐数据。 目前,在 Apache Geode 中,驱逐适用于最近最少使用的条目(也称为 LRU)。被逐出的条目将被销毁 或分页到磁盘(称为“溢出到磁盘”)。
Spring Data for Apache Geode 支持 PARTITION 区域、REPLICATE 区域、
和 client、local Region。eviction
例如,要将 PARTITION 区域配置为在内存大小超过 512 MB 时溢出到磁盘, 您可以指定以下配置:
<gfe:partitioned-region id="examplePartitionRegionWithEviction">
<gfe:eviction type="MEMORY_SIZE" threshold="512" action="OVERFLOW_TO_DISK"/>
</gfe:partitioned-region>
副本不能使用驱逐,因为这会使它们失效。
有关更多信息,请参阅 Apache Geode 文档。local destroy |
在配置 Region for overflow 时,您应该通过元素
以实现最高效率。disk-store
有关逐出策略的详细说明,请参阅有关逐出的 Apache Geode 文档。
5.5.9. 数据过期
Apache Geode 允许您控制条目在缓存中存在的时间。过期由经过的时间驱动, 与逐出相反,逐出由条目计数或堆或内存使用情况驱动。条目过期后, 可能无法再从缓存中访问它。
Apache Geode 支持以下过期类型:
-
生存时间 (TTL):对象在上次创建后可以在缓存中保留的时间(以秒为单位) 或 Update 进行更新。对于条目,create 和 put 操作的计数器设置为零。区域计数器在以下情况下重置 创建 Region,并在条目重置其计数器时。
-
空闲超时 (TTI):对象在最后一次访问后可以在缓存中保留的时间(以秒为单位)。 每当重置对象的 TTL 计数器时,都会重置对象的 Idle Timeout 计数器。此外,条目的 每当通过 get 操作或 . 每当重置某个区域的某个条目的 Idle Timeout 时,该区域的 Idle Timeout 计数器就会重置。
netSearch
其中每个选项都可以应用于区域本身或区域中的条目。Spring Data for Apache Geode 提供 、 、 和 Region 子元素来指定超时值和过期操作。<region-ttl>
<region-tti>
<entry-ttl>
<entry-tti>
以下示例显示了设置了过期值的 Region:PARTITION
<gfe:partitioned-region id="examplePartitionRegionWithExpiration">
<gfe:region-ttl timeout="30000" action="INVALIDATE"/>
<gfe:entry-tti timeout="600" action="LOCAL_DESTROY"/>
</gfe:replicated-region>
有关过期策略的详细说明,请参阅有关过期的 Apache Geode 文档。
基于注释的数据过期
使用 Spring Data for Apache Geode,您可以定义各个区域条目值的过期策略和设置(或者,将 它以不同的方式直接在应用程序域对象上)。例如,您可以在 基于 Session 的应用程序域对象,如下所示:
@Expiration(timeout = "1800", action = "INVALIDATE")
public class SessionBasedApplicationDomainObject {
...
}
您还可以分别使用空闲超时 (TTI) 和生存时间 (TTL) 过期的注释,在区域条目上指定过期类型特定设置。
如下例所示:@IdleTimeoutExpiration
@TimeToLiveExpiration
@TimeToLiveExpiration(timeout = "3600", action = "LOCAL_DESTROY")
@IdleTimeoutExpiration(timeout = "1800", action = "LOCAL_INVALIDATE")
@Expiration(timeout = "1800", action = "INVALIDATE")
public class AnotherSessionBasedApplicationDomainObject {
...
}
Both 和 优先于泛型注释
当指定了多个 Expiration 注释类型时,如前面的示例所示。既不 nor 覆盖另一个。相反,他们互相赞美
当配置了不同的区域入口过期策略(如 TTL 和 TTI)时。@IdleTimeoutExpiration
@TimeToLiveExpiration
@Expiration
@IdleTimeoutExpiration
@TimeToLiveExpiration
All based 注释仅适用于 Region 条目值。区域的过期时间不包括在
Spring Data for Apache Geode 的过期注释支持。但是,Apache Geode 和 Spring Data for Apache Geode 允许您设置区域过期时间
通过使用 SDG XML 命名空间,如下所示:
|
Spring Data for Apache Geode 的注释支持是通过 Apache Geode 的 CustomExpiry
接口实现的。
有关更多详细信息,请参阅有关配置数据过期的 Apache Geode 文档@Expiration
Spring Data for Apache Geode 类(和实现)负责处理
SDG 注释并为区域适当应用过期策略配置
根据要求进入过期。AnnotationBasedExpiration
CustomExpiry
@Expiration
使用 Spring Data for Apache Geode 配置特定的 Apache Geode 区域,以适当地将过期策略应用于
使用基于 的注释注释的应用程序域对象,您必须:@Expiration
-
使用适当的 constructor 或方便的工厂方法之一。为特定过期类型配置过期时, 例如空闲超时 (TTI) 或生存时间 (TTL),您应该使用 类,如下所示:
ApplicationContext
AnnotationBasedExpiration
AnnotationBasedExpiration
<bean id="ttlExpiration" class="org.springframework.data.gemfire.expiration.AnnotationBasedExpiration" factory-method="forTimeToLive"/> <gfe:partitioned-region id="Example" persistent="false"> <gfe:custom-entry-ttl ref="ttlExpiration"/> </gfe:partitioned-region>
要改为配置空闲超时 (TTI) 过期,请使用工厂方法 以及设置 TTI 的元素。
forIdleTimeout
<gfe:custom-entry-tti ref="ttiExpiration"/>
-
(可选)使用过期策略对存储在区域中的应用程序域对象进行注释 以及使用 Spring Data for Apache Geode 的注释之一进行自定义设置:、 、 或
@Expiration
@Expiration
@IdleTimeoutExpiration
@TimeToLiveExpiration
-
(可选)如果特定应用程序域对象根本没有使用 Spring Data for Apache Geode 的注释进行注释,但 Apache Geode 区域配置为使用 SDG 的自定义类来确定存储在区域中的对象的过期策略和设置, 您可以通过执行以下操作在 Bean 上设置“default”过期属性:
@Expiration
AnnotationBasedExpiration
AnnotationBasedExpiration
<bean id="defaultExpirationAttributes" class="org.apache.geode.cache.ExpirationAttributes">
<constructor-arg value="600"/>
<constructor-arg value="#{T(org.apache.geode.cache.ExpirationAction).DESTROY}"/>
</bean>
<bean id="ttiExpiration" class="org.springframework.data.gemfire.expiration.AnnotationBasedExpiration"
factory-method="forIdleTimeout">
<constructor-arg ref="defaultExpirationAttributes"/>
</bean>
<gfe:partitioned-region id="Example" persistent="false">
<gfe:custom-entry-tti ref="ttiExpiration"/>
</gfe:partitioned-region>
您可能已经注意到 Spring Data for Apache Geode 的注释使用 a 作为属性类型,而不是
而不是,也许更恰当地是强类型——例如,“timeout”和 SDG's 的“action”。为什么?@Expiration
String
int
ExpirationActionType
好吧,输入 Spring Data for Apache Geode 的其他功能之一,利用 Spring 的核心基础结构来方便配置: 属性占位符和 Spring 表达式语言 (SpEL) 表达式。
例如,开发人员可以使用属性占位符指定过期 'timeout' 和 'action'
在 annotation 属性中,如下例所示:@Expiration
@TimeToLiveExpiration(timeout = "${geode.region.entry.expiration.ttl.timeout}"
action = "${geode.region.entry.expiration.ttl.action}")
public class ExampleApplicationDomainObject {
...
}
然后,在 Spring XML 配置或 JavaConfig 中,你可以声明以下 bean:
<util:properties id="expirationSettings">
<prop key="geode.region.entry.expiration.ttl.timeout">600</prop>
<prop key="geode.region.entry.expiration.ttl.action">INVALIDATE</prop>
...
</util:properties>
<context:property-placeholder properties-ref="expirationProperties"/>
当多个应用程序域对象可能共享类似的过期策略时,以及 您希望将配置外部化。
但是,您可能希望由正在运行的系统的状态确定更多的动态过期配置。这是 SpEL 的强大功能开始发挥作用,实际上是推荐的方法。您不仅可以指 bean 在 Spring 容器中并访问 Bean 属性、invoke 方法等,但 expiration 的值 'timeout' 而 'action' 可以是强类型。请考虑以下示例(基于前面的示例):
<util:properties id="expirationSettings">
<prop key="geode.region.entry.expiration.ttl.timeout">600</prop>
<prop key="geode.region.entry.expiration.ttl.action">#{T(org.springframework.data.gemfire.expiration.ExpirationActionType).DESTROY}</prop>
<prop key="geode.region.entry.expiration.tti.action">#{T(org.apache.geode.cache.ExpirationAction).INVALIDATE}</prop>
...
</util:properties>
<context:property-placeholder properties-ref="expirationProperties"/>
然后,在您的应用程序域对象上,您可以定义超时和操作,如下所示:
@TimeToLiveExpiration(timeout = "@expirationSettings['geode.region.entry.expiration.ttl.timeout']"
action = "@expirationSetting['geode.region.entry.expiration.ttl.action']")
public class ExampleApplicationDomainObject {
...
}
你可以想象 'expirationSettings' bean 可能是一个更有趣、更有用的对象,而不是一个简单的
的实例。在前面的示例中,元素 () 使用 SpEL
使 action 值基于实际的枚举类型,从而快速导致已识别的失败
如果枚举类型发生更改。java.util.Properties
properties
expirationSettings
ExpirationAction
例如,所有这些都已在 Spring Data for Apache Geode 测试套件中进行了演示和测试。有关更多详细信息,请参阅源代码。
5.5.10. 数据持久化
区域可以是持久性的。Apache Geode 可确保您放入已配置的区域中的所有数据 ,因为持久性以下次重新创建区域时可恢复的方式写入磁盘。这样做让我们 在机器或进程发生故障后,甚至在有序关闭并随后重新启动 Apache Geode 数据节点。
要使用 Spring Data for Apache Geode 启用持久性,请在任何元素上将属性设置为
如下例所示:persistent
true
<*-region>
<gfe:partitioned-region id="examplePersitentPartitionRegion" persistent="true"/>
也可以通过设置 属性来配置 Persistence。为此,请将该属性的值设置为 Apache Geode 的 DataPolicy 设置之一
如下例所示:data-policy
<gfe:partitioned-region id="anotherExamplePersistentPartitionRegion" data-policy="PERSISTENT_PARTITION"/>
必须与 Region 类型匹配,并且还必须与该属性一致(如果它还匹配)
显式设置。如果属性设置为但指定了 persistent (如 或 ),则会引发初始化异常。DataPolicy
persistent
persistent
false
DataPolicy
PERSISTENT_REPLICATE
PERSISTENT_PARTITION
为了在持久保存区域时实现最高效率,您应该通过该元素配置存储。
使用 属性引用 。此外,该区域可能会执行磁盘写入
同步或异步。以下示例显示了一个 synchronous :disk-store
DiskStore
disk-store-ref
DiskStore
<gfe:partitioned-region id="yetAnotherExamplePersistentPartitionRegion" persistent="true"
disk-store-ref="myDiskStore" disk-synchronous="true"/>
这将在配置 DiskStore 中进一步讨论。
5.5.11. 订阅策略
Apache Geode 允许配置点对点 (P2P) 事件消息传递,以控制区域接收的进入事件。Spring Data for Apache Geode 提供了子元素来设置
和 Regions 上的订阅策略设置为 或 。以下示例
显示其订阅策略设置为 :<gfe:subscription/>
REPLICATE
PARTITION
ALL
CACHE_CONTENT
CACHE_CONTENT
<gfe:partitioned-region id="examplePartitionRegionWithCustomSubscription">
<gfe:subscription type="CACHE_CONTENT"/>
</gfe:partitioned-region>
5.5.12. 本地区域
Spring Data for Apache Geode 提供了用于创建本地区域的专用元素。Local Region,顾名思义,
是独立的,这意味着它们不与任何其他分布式系统成员共享数据。除此之外,所有
常见的区域配置选项适用。local-region
以下示例显示了一个最小声明(同样,该示例依赖于 Spring Data for Apache Geode XML 命名空间命名 连接缓存的约定):
<gfe:local-region id="exampleLocalRegion"/>
在前面的示例中,创建了一个本地 Region(如果不存在同名的 Region)。的名称
Region 与 Bean ID () 相同,并且 Bean 假定存在 Apache Geode
名为 的缓存。exampleLocalRegion
gemfireCache
5.5.13. 复制区域
常见的 Region 类型之一是 Region 或 “replica”。简而言之,当区域配置为
a 中,托管该区域的每个成员都会在本地存储该区域条目的副本。对
区域将分发到该区域的所有副本。创建副本时,它将通过
初始化阶段,在该阶段中,它会发现其他副本并自动复制所有条目。
当一个副本正在初始化时,您仍然可以继续使用其他副本。REPLICATE
REPLICATE
REPLICATE
所有常见配置选项都可用于 REPLICATE 区域。Spring Data for Apache Geode 提供了一个元素。
以下示例显示了一个 minimal 声明:replicated-region
<gfe:replicated-region id="exampleReplica"/>
有关更多详细信息,请参阅有关分布式和复制区域的 Apache Geode 文档。
5.5.14. 分区区域
Spring Data for Apache Geode XML 命名空间还支持区域。PARTITION
引用 Apache Geode 文档:
“分区区域是指在托管该区域的对等服务器之间划分数据的区域,以便每个对等服务器都 存储数据的子集。使用分区区域时,应用程序会显示一个逻辑视图 的区域,看起来像一个包含区域中所有数据的地图。读取或写入此映射 透明地路由到托管作为操作目标的条目的对等体。Apache Geode 将哈希码的域划分为多个 bucket。每个存储桶都分配给特定的对等体,但可以重新定位 随时连接到另一个对等节点,以提高整个集群的资源利用率。
Region 是使用元素创建的。它的配置选项类似于
通过添加特定于分区的功能(例如冗余副本的数量)、
Total Maximum memory(总最大内存)、Bucket Number of Bucket(存储桶数)、Partition Resolver(分区解析程序)等。PARTITION
partitioned-region
replicated-region
以下示例显示如何设置具有两个冗余副本的区域:PARTITION
<gfe:partitioned-region id="examplePartitionRegion" copies="2" total-buckets="17">
<gfe:partition-resolver>
<bean class="example.PartitionResolver"/>
</gfe:partition-resolver>
</gfe:partitioned-region>
有关更多详细信息,请参阅 Apache Geode 的分区区域文档。
分区区域属性
下表提供了特定于 Region (区域) 的配置选项的快速概述。
这些选项是对常见区域配置选项的补充
前面描述过。PARTITION
名字 | 值 | 描述 |
---|---|---|
副本 |
0..4 |
每个分区的 cop 数,以实现高可用性。默认情况下,不会创建任何副本。 这意味着没有冗余。每个副本都提供额外的备份,但会占用额外的存储空间。 |
colocated-with (共址) |
有效的区域名称 |
与此新创建的 Region 并置的区域的名称。 |
本地最大内存 |
正整数 |
区域在此进程中使用的最大内存量 (以 MB 为单位)。 |
total-max-memory (总最大内存) |
任何整数值 |
区域在所有进程中使用的最大内存量 (以 MB 为单位)。 |
分区侦听器 |
Bean 名称 |
此区域用于处理分区事件的名称。 |
分区解析器 |
Bean 名称 |
此区域用于自定义分区的名称。 |
恢复延迟 |
任何长值 |
现有成员在另一个成员崩溃后等待满足冗余的延迟(以毫秒为单位)。 -1(默认值)表示故障后不恢复冗余。 |
启动恢复延迟 |
任何长值 |
新成员在满足冗余之前等待的延迟(以毫秒为单位)。 -1 表示添加新成员不会触发冗余恢复。默认设置是恢复冗余 在添加新成员时立即。 |
5.5.15. 客户区域
Apache Geode 支持用于管理和分发数据的各种部署拓扑。主题 Apache Geode 拓扑超出了本文档的范围。然而,快速回顾一下,Apache Geode 的 支持的拓扑可分为:点对点 (P2P)、客户端-服务器和广域网 (WAN)。在最后 两种配置,通常声明连接到缓存服务器的客户端区域。
Spring Data for Apache Geode 通过其 client-cache 元素为每个配置提供专用支持:和 。顾名思义,定义客户端 Region,而定义
由各个客户端区域使用和共享的连接池。client-region
pool
client-region
pool
以下示例显示了典型的客户端区域配置:
<bean id="myListener" class="example.CacheListener"/>
<!-- client Region using the default SDG gemfirePool Pool -->
<gfe:client-region id="Example">
<gfe:cache-listener ref="myListener"/>
</gfe:client-region>
<!-- client Region using its own dedicated Pool -->
<gfe:client-region id="AnotherExample" pool-name="myPool">
<gfe:cache-listener ref="myListener"/>
</gfe:client-region>
<!-- Pool definition -->
<gfe:pool id="myPool" subscription-enabled="true">
<gfe:locator host="remoteHost" port="12345"/>
</gfe:pool>
与其他区域类型一样,支持实例以及 a 和 .它还需要一个连接来连接到一组定位器或服务器。
每个客户端区域都可以有自己的 ,也可以共享同一个区域。如果未指定 Pool,则
将使用 “DEFAULT” 池。client-region
CacheListener
CacheLoader
CacheWriter
Pool
Pool
在前面的示例中,配置了 Locator。Locator 是用于发现
缓存分布式系统中的服务器和对等数据成员,建议用于生产系统。它也是
可以配置 直接连接到一个或多个缓存服务器 通过使用 元素.Pool Pool server |
有关要在客户端上设置的选项的完整列表,尤其是在 上,请参阅
Spring Data for Apache Geode 架构(“Spring Data for Apache Geode 架构”)和 Apache Geode 的客户端-服务器配置文档。Pool
客户利益
为了最小化网络流量,每个客户端可以单独定义自己的 interest 策略,指示 Apache Geode 它实际需要的数据。在 Spring Data for Apache Geode 中,可以为每个客户区域定义“兴趣” 分别。支持基于键和基于正则表达式的兴趣类型。
以下示例显示了基于键和基于正则表达式的类型:interest
<gfe:client-region id="Example" pool-name="myPool">
<gfe:key-interest durable="true" result-policy="KEYS">
<bean id="key" class="java.lang.String">
<constructor-arg value="someKey"/>
</bean>
</gfe:key-interest>
<gfe:regex-interest pattern=".*" receive-values="false"/>
</gfe:client-region>
特殊键 ,表示为所有键注册了 'interest'。同样也可以实现
通过使用正则表达式 .ALL_KEYS
".\*"
key 和 regular expression 元素支持三个属性:、 、
和。<gfe:*-interest>
durable
receive-values
result-policy
durable
指示在客户端连接时是否为客户端创建的 'interest' 策略和订阅队列
到集群中的一个或多个服务器,则跨客户端会话进行维护。如果客户离开又回来,
当客户端断开连接时,客户端服务器上的订阅队列将保持。当
client reconnects,则 client 会收到 client 与 服务器断开连接时发生的任何事件
在集群中。durable
集群中服务器上的订阅队列是为客户端中定义的每个连接维护的
其中,也为该 “启用”了订阅。订阅队列用于存储(并且可能
conflate) 事件。如果订阅队列是持久的,则它在客户端会话之间持续存在
(即 connections),可能达到指定的超时。如果客户端在给定的时间范围内未返回
客户端池订阅队列被销毁,以减少集群中服务器上的资源消耗。
如果订阅队列不是 ,则当客户端断开连接时,它会立即销毁。您需要决定
您的客户端是否应该接收断开连接时出现的事件,或者它是否只需要接收最新的
事件。Pool
Pool
durable
该属性指示是否接收 create 和 update 事件的条目值。
如果 ,则接收到值。如果 ,则仅接收失效事件。receive-values
true
false
最后,'result-policy' 是以下各项的枚举: , , 和 .默认值为 .
它控制客户端首次连接以初始化本地缓存时的初始转储,
实质上是用与 INTEREST 策略匹配的所有条目的事件作为 Client 端的种子。KEYS
KEYS_VALUE
NONE
KEYS_VALUES
result-policy
如前所述,如果不在 上启用 订阅,客户端兴趣登记就不会有太大好处。
事实上,在未启用订阅的情况下尝试兴趣登记是错误的。以下示例显示了
如何操作:Pool
<gfe:pool ... subscription-enabled="true">
...
</gfe:pool>
除了 之外,您还可以设置 、 和 。 用于控制
订阅队列的许多副本应由集群中的服务器维护。如果 redundancy 大于
一个,并且 “primary” 订阅队列(即 server)宕机,然后是 “Secondary” 订阅队列
接管,从而防止客户端在 HA 场景中丢失事件。subscription-enabled
subscription-ack-interval
subscription-message-tracking-timeout
subscription-redundancy
subscription-redundancy
除了设置之外,服务器端区域还使用附加属性 ,
来控制发送到客户端的事件的合并。这也有助于进一步减少网络流量
,并且在应用程序只关心条目的最新值的情况下很有用。但是,当
应用程序会保留发生的事件的时间序列,合并会阻碍该用例。默认值
是。以下示例显示了服务器上的区域配置,其中客户端包含一个
对此服务器区域中的密钥感兴趣的相应 client Region:Pool
enable-subscription-conflation
false
[CACHING_]PROXY
<gfe:partitioned-region name="ServerSideRegion" enable-subscription-conflation="true">
...
</gfe:partitioned-region>
控制在客户端
断开与集群中的服务器的连接,按如下方式设置元素上的属性:durable-client-timeout
<gfe:client-cache>
<gfe:client-cache durable-client-timeout="600">
...
</gfe:client-cache>
对客户利益如何运作和能力的全面、深入的讨论超出了本文档的范围。
有关更多详细信息,请参阅 Apache Geode 的 Client-to-Server Event Distribution 文档。
5.5.16. JSON 支持
Apache Geode 支持在区域中缓存 JSON 文档,并能够查询存储的 JSON
使用 Apache Geode OQL(对象查询语言)的文档。JSON 文档在内部存储为 PdxInstance 类型
通过使用 JSONFormatter 类
执行与 JSON 文档之间的转换(作为 )。String
Spring Data for Apache Geode 提供了使 AOP 组件能够建议适当的代理区域操作的元素。
它有效地封装了 ,从而让您的应用程序直接使用 JSON 字符串。<gfe-data:json-region-autoproxy/>
JSONFormatter
此外,写入 JSON 配置区域的 Java 对象会使用 Jackson 的 .当这些值被读回时,它们将作为 JSON 字符串返回。ObjectMapper
默认情况下,对所有 Region 执行转换。应用此功能
到选定的 Region,请在属性中提供以逗号分隔的 Region bean ID 列表。
其他属性包括标志(默认为 )和 .<gfe-data:json-region-autoproxy/>
region-refs
pretty-print
false
convert-returned-collections
此外,默认情况下,和 Region 操作的结果会转换为已配置的 Region。
这是通过在本地内存中创建并行数据结构来完成的。这可能会导致大型
收藏集,因此,如果要禁用自动转换,请将 设置为
对于这些区域操作。getAll()
values()
convert-returned-collections
false
某些区域操作(特别是那些使用 Apache Geode 专有的操作,例如:和类型)不是 AOP 建议的目标。另外
该方法(返回 ) 也不受影响。Region.Entry entries(boolean) entrySet(boolean) getEntry() entrySet() Set<java.util.Map.Entry<?, ?>> |
以下示例配置显示如何设置 and 属性:pretty-print
convert-returned-collections
<gfe-data:json-region-autoproxy region-refs="myJsonRegion" pretty-print="true" convert-returned-collections="false"/>
此功能还可以与操作无缝协作,前提是模板已声明
作为 Spring bean 进行。目前不支持本机操作。GemfireTemplate
QueryService
5.6. 配置索引
Apache Geode 允许在区域数据上创建索引(有时也复数为索引) 以提高 OQL (Object Query Language) 查询的性能。
在 Spring Data for Apache Geode 中,索引是使用 element 声明的,如下例所示:index
<gfe:index id="myIndex" expression="someField" from="/SomeRegion" type="HASH"/>
在 Spring Data for Apache Geode 的 XML 模式(也称为 SDG XML 命名空间)中,未绑定 bean 声明
添加到区域,这与 Apache Geode 的本机不同。相反,它们是类似于 element 的顶级元素。这允许您在任何 Region 上声明任意数量的索引,无论它们是刚刚创建的
或已经存在 - 这是对 Apache Geode 原生格式的重大改进。index
cache.xml
<gfe:cache>
cache.xml
必须有一个名称。您可以使用 attribute 为 它指定一个显式名称。
否则,Bean 定义的 Bean 名称(即属性的值)将用作
名称。Index
Index
name
id
index
Index
子句 and 构成了 的主要组件 ,用于标识要索引的数据
(即子句中标识的区域)以及使用的条件(即 )
为数据编制索引。应基于谓词中使用的应用程序域对象字段
用于查询和查找存储在区域中的对象的应用程序定义的 OQL 查询。expression
from
Index
from
expression
expression
请考虑以下示例,该示例具有 property:lastName
@Region("Customers")
class Customer {
@Id
Long id;
String lastName;
String firstName;
...
}
现在考虑以下示例,该示例具有应用程序定义的 SDG 存储库
要查询对象:Customer
interface CustomerRepository extends GemfireRepository<Customer, Long> {
Customer findByLastName(String lastName);
...
}
SDG 存储库查找器/查询方法会导致生成并运行以下 OQL 语句:
SELECT * FROM /Customers c WHERE c.lastName = '$1'
因此,您可能希望创建类似于以下内容的 with 语句:Index
<gfe:index id="myIndex" name="CustomersLastNameIndex" expression="lastName" from="/Customers" type="HASH"/>
该子句必须引用有效的现有区域,并且是 an 应用于区域的方式。
这并非特定于 Spring Data for Apache Geode。这是 Apache Geode 的一项功能。from
Index
这可能是 Spring Data for Apache Geode 的 IndexType
枚举定义的三个枚举值之一:、 和 。Index
type
FUNCTIONAL
HASH
PRIMARY_KEY
每个枚举值对应于在要创建 actual(或“defined” — 您可以找到)时调用的 QueryService
方法之一
下一节将详细介绍如何“定义”索引)。例如,如果 is ,则调用 QueryService.createKeyIndex(..) 来创建 .create[|Key|Hash]Index
Index
IndexType
PRIMARY_KEY
KEY
Index
默认值为 and 导致调用其中一个方法。请参阅
Spring Data for Apache Geode XML 架构,以获取一整套选项。FUNCTIONAL
QueryService.createIndex(..)
有关 Apache Geode 中索引的详细信息,请参阅“使用索引” 在 Apache Geode 的用户指南中。
5.6.1. 定义索引
除了在 Spring 容器上处理 Bean 定义时预先创建索引之外
初始化后,您还可以使用 Attribute 在创建应用程序索引之前定义所有应用程序索引,如下所示:Index
define
<gfe:index id="myDefinedIndex" expression="someField" from="/SomeRegion" define="true"/>
当设置为 (默认为 ) 时,它实际上不会在该时刻创建 。
所有 “defined” 索引都是在 Spring 被 “刷新” 时一次性创建的,或者,换句话说
不同的是,当 a 由 Spring 容器发布时。Spring Data for Apache Geode 将自身注册为
一个监听 .触发时, Spring Data for Apache Geode 会调用 QueryService.createDefinedIndexes()。
define
true
false
Index
ApplicationContext
ContextRefreshedEvent
ApplicationListener
ContextRefreshedEvent
定义索引并一次性创建索引可以提高创建索引的速度和效率。
请参见一次创建多个索引 了解更多详情。
5.6.2. 和IgnoreIfExists
Override
两个 Spring Data for Apache Geode 配置选项值得特别提及: 和 。Index
ignoreIfExists
override
这些选项对应于元素上的 and 属性
分别在 Spring Data 中为 Apache Geode 的 XML 命名空间。ignore-if-exists
override
<gfe:index>
在使用这些选项中的任何一个之前,请确保您完全了解自己在做什么。这些选项可以
影响应用程序在运行时消耗的性能和资源(例如内存)。因此,两者
默认情况下,这些选项在 SDG 中处于禁用状态(设置为 )。false |
这些选项仅在 Spring Data for Apache Geode 中可用,用于解决 Apache Geode 的已知限制。 Apache Geode 没有等效的选项或功能。 |
每个选项的行为都存在显著差异,并且完全取决于 Apache Geode 异常的类型
扔。这也意味着,如果未引发 Apache Geode 索引类型异常,则这两个选项都不起作用。
这些选项专门用于处理 Apache Geode 和实例,这些原因可能由于各种有时不明原因而发生。异常的原因如下:Index
IndexExistsException
IndexNameConflictException
-
当存在另一个具有相同定义但名称不同的 IndexExistsException 时,将引发
IndexExistsException
创建一个 .Index
Index
-
如果存在另一个具有相同名称但定义可能不同的
IndexNameConflictException
,则在尝试 创建一个 .Index
Index
Spring Data for Apache Geode 的默认行为是始终快速失败。因此,默认情况下,两个 Exception 都不会被 “处理”。
这些异常被包装在 SDG 中并重新抛出。如果您希望使用 Spring Data for Apache Geode
要为您处理这些问题,可以将这些 Bean 定义选项中的任何一个设置为 。Index
Index
GemfireIndexException
Index
true
IgnoreIfExists
始终优先于 ,主要是因为它使用的资源较少,这仅仅是因为
在两种特殊情况下,它都会返回 “existing”。Override
Index
IgnoreIfExists
行为
当 an 被抛出并设置为 (或 ),
那么,这个 bean 定义或声明本来会创建的 that 就会被简单地忽略,
并返回 existing 。IndexExistsException
ignoreIfExists
true
<gfe:index ignore-if-exists="true">
Index
index
Index
返回现有的 ,由于 bean 定义是相同的,
由 Apache Geode 本身决定,而不是 SDG。Index
index
但是,这也意味着 no 与 bean 定义或声明中指定的 “name”
实际上从 Apache Geode 的角度来看是存在的(即,使用 QueryService.getIndexes()
)。
因此,在编写使用查询提示(尤其是查询提示)的 OQL 查询语句时应小心
,这表示被忽略的应用程序。这些查询提示需要更改。Index
index
Index
当 an 被抛出并设置为 (或 ),
由此 bean 定义或声明创建的 bean 也会被忽略,
并且 “existing” 再次返回,就像抛出 an 时一样。IndexNameConflictException
ignoreIfExists
true
<gfe:index ignore-if-exists="true">
Index
index
Index
IndexExistsException
但是,返回 existing 并忽略应用程序对 when an 的定义存在更大的风险。对于 a ,虽然名称冲突
索引相同,但定义可能不同。这种情况可能会对 OQL 查询产生影响
特定于应用程序,其中您可以假定索引是专门使用应用程序定义的
考虑数据访问模式和查询。但是,如果同名索引的定义不同,则可能不是
案子。因此,您应该验证您的姓名。Index
Index
IndexNameConflictException
IndexNameConflictException
Index
SDG 会尽最大努力在被忽略的情况明显不同时通知用户
在其定义中,来自现有的 .然而,为了让 SDG 实现这一目标,它必须能够
查找现有 ,该 是使用 Apache Geode API(唯一可用的方法)查找的。Index Index Index |
Override
行为
当 an 被抛出并设置为 (或 ),
实际上已重命名。请记住,当存在多个索引时,会抛出
具有相同的定义,但名称不同。IndexExistsException
override
true
<gfe:index override="true">
Index
IndexExistsExceptions
Spring Data for Apache Geode 只能通过使用 Apache Geode 的 API 来实现此目的,首先删除现有的 API,然后使用新名称重新创建。remove 或后续的 create 调用
可能会失败。无法以原子方式执行这两个操作,并在任何一个操作失败时回滚此联合操作。Index
Index
但是,如果它成功,那么您的选项会遇到与以前相同的问题。任何现有的 OQL
查询语句使用引用旧 by name 的查询提示。ignoreIfExists
Index
当 an 被抛出并设置为 (或 ),
existing 可能会被重新定义。我们说“潜在”是因为同名的
existing 在引发 an 时具有完全相同的定义和名称。IndexNameConflictException
override
true
<gfe:index override="true">
Index
Index
IndexNameConflictException
如果是这样,则 SDG 是智能的,即使在 上也是如此,也会按原样返回现有 。没有害处
在此行为中,因为名称和定义完全相同。当然,SDG 只能
当 SDG 能够找到依赖于 Apache Geode API 的现有 时,即可完成此操作。
如果找不到,则不会发生任何事情,并且会抛出一个 SDG,将 .Index
override
Index
GemfireIndexException
IndexNameConflictException
但是,当 existing 的定义不同时,SDG 会尝试使用 bean 定义中指定的定义重新创建 。确保这是您想要的,并确保
Bean 定义符合您的期望和应用程序要求。Index
Index
Index
index
index
实际上是如何发生的?IndexNameConflictExceptions
抛出 for 可能并不少见,尤其是当多个配置
sources 用于配置 Apache Geode(Spring Data for Apache Geode、Apache Geode Cluster Config、Apache Geode native、API 等)。您绝对应该更喜欢一种配置方法并坚持下去。IndexExistsExceptions
cache.xml
但是,什么时候会抛出呢?IndexNameConflictException
一个特定案例是在 Region (PR) 上定义。在 Region 上定义 时
(例如,),Apache Geode 将定义(和名称)分发给其他对等成员
在同样托管同一区域(即“X”)的集群中。此定义的分布
到和随后由对等成员创建此内容是在需要知道的基础上(即,由对等成员托管
相同的 PR)异步执行。Index
PARTITION
Index
PARTITION
X
Index
PARTITION
Index
Index
在此时间窗口内,Apache Geode 可能无法识别这些待处理的 PR — 例如使用 QueryService.getIndexes(:Region) 调用 QueryService.getIndexes()。
甚至使用
QueryService.getIndex(:Region, indexName:String)
来获取。Indexes
因此,SDG 或其他 Apache Geode 缓存客户端应用程序的唯一方法(不涉及 Spring)
要确定,就是尝试创建 .如果失败时显示 or 偶数
an 时,应用程序知道存在问题。这是因为
等待待处理的定义,而其他 Apache Geode API 调用则不会。Index
IndexNameConflictException
IndexExistsException
QueryService
Index
Index
无论如何,SDG 都会尽最大努力并尝试告知您已经发生或正在发生的事情,并告诉您
纠正措施。鉴于所有 Apache Geode 方法都是同步的,
blocking 操作,则 Apache Geode 的状态应该是一致的,并且在这些索引类型中的任何一个之后都可以访问
异常。因此,SDG 可以检查系统的状态并采取相应的行动,
根据您的配置。QueryService.createIndex(..)
在所有其他情况下,SDG 都采用快速失败策略。
5.7. 配置 DiskStore
Spring Data for Apache Geode 支持通过元素
如下例所示:DiskStore
disk-store
<gfe:disk-store id="Example" auto-compact="true" max-oplog-size="10"
queue-size="50" time-interval="9999">
<gfe:disk-dir location="/disk/location/one" max-size="20"/>
<gfe:disk-dir location="/disk/location/two" max-size="20"/>
</gfe:disk-store>
DiskStore
区域使用实例进行文件系统持久备份和逐出条目的溢出
以及 WAN 网关的持久备份。多个 Apache Geode 组件可能共享相同的 .
此外,可以为单个 定义多个文件系统目录,如
前面的示例。DiskStore
DiskStore
请参阅 Apache Geode 的文档,了解有关实例上的 Persistence 和 Overflow 以及配置选项的完整说明。DiskStore
5.8. 配置 Snapshot 服务
Spring Data for Apache Geode 使用 Apache Geode 的快照服务支持缓存和区域快照。 开箱即用的快照服务支持提供了多项便捷的功能,以简化 Apache Geode 缓存和区域快照服务 API 的使用。
正如 Apache Geode 文档所解释的那样, 快照允许您保存并随后重新加载缓存的数据,这对于在两者之间移动数据非常有用 环境,例如从生产环境到暂存或测试环境,以便重现与数据相关的问题 在受控的环境中。您可以结合 Spring Data for Apache Geode 的快照服务支持 使用 Spring 的 bean 定义配置文件来根据需要加载特定于环境的快照数据。
Spring Data for Apache Geode 对 Apache Geode 快照服务的支持以元素
从 XML 命名空间。<gfe-data:snapshot-service>
<gfe-data>
例如,您可以使用几个快照导入来定义要加载和保存的缓存范围的快照 以及数据导出定义,如下所示:
<gfe-data:snapshot-service id="gemfireCacheSnapshotService">
<gfe-data:snapshot-import location="/absolute/filesystem/path/to/import/fileOne.snapshot"/>
<gfe-data:snapshot-import location="relative/filesystem/path/to/import/fileTwo.snapshot"/>
<gfe-data:snapshot-export
location="/absolute/or/relative/filesystem/path/to/export/directory"/>
</gfe-data:snapshot-service>
您可以根据需要定义任意数量的导入和导出。您可以仅定义导入或仅导出。文件位置 目录路径可以是绝对路径,也可以是相对于 Spring Data for Apache Geode 应用程序的路径路径,后者是 JVM 进程的 working 目录中。
前面的示例非常简单,在本例中定义的 Snapshot Service 引用 Apache Geode
cache 实例,默认名称为 (如配置缓存中所述)。如果您将缓存命名为
bean 定义,你可以使用该属性来引用缓存 bean
按名称,如下所示:gemfireCache
cache-ref
<gfe:cache id="myCache"/>
...
<gfe-data:snapshot-service id="mySnapshotService" cache-ref="myCache">
...
</gfe-data:snapshot-service>
您还可以通过指定属性为特定区域定义快照服务,如下所示:region-ref
<gfe:partitioned-region id="Example" persistent="false" .../>
...
<gfe-data:snapshot-service id="gemfireCacheRegionSnapshotService" region-ref="Example">
<gfe-data:snapshot-import location="relative/path/to/import/example.snapshot/>
<gfe-data:snapshot-export location="/absolute/path/to/export/example.snapshot/>
</gfe-data:snapshot-service>
指定属性后,Spring Data for Apache Geode 会将属性值解析为 Spring 容器中定义的 Region Bean,并创建 RegionSnapshotService
。
快照导入和导出定义的工作方式相同。但是,必须引用一个文件
在导出时。region-ref
SnapshotServiceFactoryBean
region-ref
location
Apache Geode 对导入的快照文件在引用之前实际存在的要求非常严格。 对于导出,Apache Geode 会创建快照文件。如果要导出的快照文件已存在,则 数据将被覆盖。 |
Spring Data for Apache Geode 在元素上包含一个属性
以禁止配置的 Snapshot Service 在初始化时尝试将数据导入缓存或区域。
这样做非常有用,例如,当从一个 Region 导出的数据用于馈送另一个 Region 的导入时。suppress-import-on-init <gfe-data:snapshot-service> |
5.8.1. 快照位置
使用基于缓存的 Snapshot Service
(即 CacheSnapshotService
)
您通常会向其传递一个包含所有要加载的快照文件的目录,而不是单个快照文件。
如 API 中的 overloaded load
方法所示。CacheSnapshotService
当然,你可以使用 overloaded 方法获取特定的
了解要加载到 Apache Geode 缓存中的快照文件。load(:File[], :SnapshotFormat, :SnapshotOptions) |
但是,Spring Data for Apache Geode 认识到典型的开发人员工作流可能是提取和导出数据 从一个环境到多个快照文件中,将它们全部压缩起来,然后方便地移动 zip 文件 导入到另一个环境中进行导入。
因此, Spring Data for Apache Geode 允许您在导入时为基于 Snapshot Service 指定 jar 或 zip 文件,如下所示:cache
<gfe-data:snapshot-service id="cacheBasedSnapshotService" cache-ref="gemfireCache">
<gfe-data:snapshot-import location="/path/to/snapshots.zip"/>
</gfe-data:snapshot-service>
Spring Data for Apache Geode 可以方便地提取提供的 zip 文件,并将其视为目录导入(加载)。
5.8.2. 快照过滤器
定义多个快照导入和导出的真正功能是通过使用快照过滤器来实现的。
快照过滤器实现 Apache Geode 的 SnapshotFilter
接口
,用于筛选区域条目,以便在导入时包含在区域中,并包含在快照中
导出时。
Spring Data for Apache Geode 允许您在导入和导出时使用快照过滤器,方法是使用属性或匿名
嵌套 bean 定义,如下例所示:filter-ref
<gfe:cache/>
<gfe:partitioned-region id="Admins" persistent="false"/>
<gfe:partitioned-region id="Guests" persistent="false"/>
<bean id="activeUsersFilter" class="example.gemfire.snapshot.filter.ActiveUsersFilter/>
<gfe-data:snapshot-service id="adminsSnapshotService" region-ref="Admins">
<gfe-data:snapshot-import location="/path/to/import/users.snapshot">
<bean class="example.gemfire.snapshot.filter.AdminsFilter/>
</gfe-data:snapshot-import>
<gfe-data:snapshot-export location="/path/to/export/active/admins.snapshot" filter-ref="activeUsersFilter"/>
</gfe-data:snapshot-service>
<gfe-data:snapshot-service id="guestsSnapshotService" region-ref="Guests">
<gfe-data:snapshot-import location="/path/to/import/users.snapshot">
<bean class="example.gemfire.snapshot.filter.GuestsFilter/>
</gfe-data:snapshot-import>
<gfe-data:snapshot-export location="/path/to/export/active/guests.snapshot" filter-ref="activeUsersFilter"/>
</gfe-data:snapshot-service>
此外,您还可以使用类来表示更复杂的快照筛选条件。
此类实现 Apache Geode 的 SnapshotFilter 接口
以及 Composite 软件设计模式。ComposableSnapshotFilter
简而言之,Composite 软件设计模式允许您 组合多个相同类型的对象,并将聚合视为对象类型的单个实例 — 一个 强大而有用的抽象。
ComposableSnapshotFilter
有两个工厂方法,而 .它们允许您以逻辑方式组合单个快照
filters 分别使用 AND 和 OR 逻辑运算符。工厂方法采用 .and
or
SnapshotFilters
以下示例显示了 的定义 :ComposableSnapshotFilter
<bean id="activeUsersSinceFilter" class="org.springframework.data.gemfire.snapshot.filter.ComposableSnapshotFilter"
factory-method="and">
<constructor-arg index="0">
<list>
<bean class="org.example.app.gemfire.snapshot.filter.ActiveUsersFilter"/>
<bean class="org.example.app.gemfire.snapshot.filter.UsersSinceFilter"
p:since="2015-01-01"/>
</list>
</constructor-arg>
</bean>
然后,您可以继续使用 将 与另一个过滤器结合使用,如下所示:activesUsersSinceFilter
or
<bean id="covertOrActiveUsersSinceFilter" class="org.springframework.data.gemfire.snapshot.filter.ComposableSnapshotFilter"
factory-method="or">
<constructor-arg index="0">
<list>
<ref bean="activeUsersSinceFilter"/>
<bean class="example.gemfire.snapshot.filter.CovertUsersFilter"/>
</list>
</constructor-arg>
</bean>
5.8.3. 快照事件
默认情况下,Spring Data for Apache Geode 在启动时使用 Apache Geode 的快照服务来导入数据,并在关闭时使用 以导出数据。但是,您可能希望触发基于事件的定期快照,以便进行导入或导出。 从 Spring 应用程序中。
为此,Spring Data for Apache Geode 定义了两个额外的 Spring 应用程序事件,分别扩展了 Spring 的 ApplicationEvent
类以进行导入和导出:和 .ImportSnapshotApplicationEvent
ExportSnapshotApplicationEvent
这两个应用程序事件可以针对整个 Apache Geode 缓存或单个 Apache Geode
地区。这些类中的构造函数接受可选的 Region 路径名(例如 )以及零
或更多实例。/Example
SnapshotMetadata
数组将覆盖由 和 sub 元素定义的快照元数据,这些元素用于快照应用程序事件不
显式提供 .每个单独的实例都可以定义自己的 and 属性。SnapshotMetadata
<gfe-data:snapshot-import>
<gfe-data:snapshot-export>
SnapshotMetadata
SnapshotMetadata
location
filters
Spring 中定义的所有快照服务 bean 都会接收导入和导出快照
应用程序事件。但是,只有匹配的 Snapshot Service Bean 才会处理导入和导出事件。ApplicationContext
如果 Snapshot Service Bean 定义了
是 a 及其 Region 引用(由属性确定)匹配项
区域的路径名,由 snapshot 应用程序事件指定。[Import|Export]SnapshotApplicationEvent
RegionSnapshotService
region-ref
基于缓存的(即没有区域路径名的快照应用程序事件)
触发所有快照服务 Bean(包括任何 Bean)以执行导入或导出,
分别。[Import|Export]SnapshotApplicationEvent
RegionSnapshotService
你可以使用 Spring 的ApplicationEventPublisher
接口从你的应用程序触发导入和导出快照应用程序事件,如下所示:
@Component
public class ExampleApplicationComponent {
@Autowired
private ApplicationEventPublisher eventPublisher;
@Resource(name = "Example")
private Region<?, ?> example;
public void someMethod() {
...
File dataSnapshot = new File(System.getProperty("user.dir"), "/path/to/export/data.snapshot");
SnapshotFilter myFilter = ...;
SnapshotMetadata exportSnapshotMetadata =
new SnapshotMetadata(dataSnapshot, myFilter, null);
ExportSnapshotApplicationEvent exportSnapshotEvent =
new ExportSnapshotApplicationEvent(this, example.getFullPath(), exportSnapshotMetadata)
eventPublisher.publishEvent(exportSnapshotEvent);
...
}
}
在前面的示例中,只有 Region 的 Snapshot Service Bean 选取并处理 export 事件
将筛选后的 “/Example” Region 的数据保存到应用程序的
working 目录中。/Example
data.snapshot
使用 Spring 应用程序事件和消息传递子系统是保持应用程序松散耦合的好方法。 您还可以使用 Spring 的 Scheduling 服务来触发 定期快照应用程序事件。
5.9. 配置 Function Service
Spring Data for Apache Geode 为实现、注册和执行提供 Comments 支持 Apache Geode 函数。
Spring Data for Apache Geode 还提供 XML 命名空间支持,用于注册 Apache Geode 函数以进行远程函数执行。
有关函数执行框架的更多信息,请参阅 Apache Geode 的文档。
Apache Geode 函数声明为 Spring bean,并且必须实现接口或 extend 。org.apache.geode.cache.execute.Function
org.apache.geode.cache.execute.FunctionAdapter
命名空间使用熟悉的模式来声明 Functions,如下例所示:
<gfe:function-service>
<gfe:function>
<bean class="example.FunctionOne"/>
<ref bean="function2"/>
</gfe:function>
</gfe:function-service>
<bean id="function2" class="example.FunctionTwo"/>
5.10. 配置 WAN 网关
WAN 网关 提供了一种跨地理位置同步 Apache Geode 分布式系统的方法。 Spring Data for Apache Geode 为配置 WAN 网关提供了 XML 命名空间支持,如以下示例所示。
5.10.1. Apache Geode 7.0 中的 WAN 配置
在以下示例中,通过添加子元素为 Region 配置
( 和 ) 添加到区域。A 可以注册 和 。GatewaySenders
PARTITION
gateway-sender
gateway-sender-ref
GatewaySender
EventFilters
TransportFilters
以下示例还显示了 的 配置示例,该配置也必须自动连接
到一个区域(未显示):AsyncEventQueue
<gfe:partitioned-region id="region-with-inner-gateway-sender" >
<gfe:gateway-sender remote-distributed-system-id="1">
<gfe:event-filter>
<bean class="org.springframework.data.gemfire.example.SomeEventFilter"/>
</gfe:event-filter>
<gfe:transport-filter>
<bean class="org.springframework.data.gemfire.example.SomeTransportFilter"/>
</gfe:transport-filter>
</gfe:gateway-sender>
<gfe:gateway-sender-ref bean="gateway-sender"/>
</gfe:partitioned-region>
<gfe:async-event-queue id="async-event-queue" batch-size="10" persistent="true" disk-store-ref="diskstore"
maximum-queue-memory="50">
<gfe:async-event-listener>
<bean class="example.AsyncEventListener"/>
</gfe:async-event-listener>
</gfe:async-event-queue>
<gfe:gateway-sender id="gateway-sender" remote-distributed-system-id="2">
<gfe:event-filter>
<ref bean="event-filter"/>
<bean class="org.springframework.data.gemfire.example.SomeEventFilter"/>
</gfe:event-filter>
<gfe:transport-filter>
<ref bean="transport-filter"/>
<bean class="org.springframework.data.gemfire.example.SomeTransportFilter"/>
</gfe:transport-filter>
</gfe:gateway-sender>
<bean id="event-filter" class="org.springframework.data.gemfire.example.AnotherEventFilter"/>
<bean id="transport-filter" class="org.springframework.data.gemfire.example.AnotherTransportFilter"/>
a 的另一端是对应的接收 Gateway 事件。
也可以使用 和 进行配置,如下所示:GatewaySender
GatewayReceiver
GatewayReceiver
EventFilters
TransportFilters
<gfe:gateway-receiver id="gateway-receiver" start-port="12345" end-port="23456" bind-address="192.168.0.1">
<gfe:transport-filter>
<bean class="org.springframework.data.gemfire.example.SomeTransportFilter"/>
</gfe:transport-filter>
</gfe:gateway-receiver>
有关所有配置选项的详细说明,请参阅 Apache Geode 文档。
6. 使用注释通过 Spring 容器引导 Apache Geode
Spring Data for Apache Geode (SDG) 2.0 引入了一种新的基于注释的配置模型 以使用 Spring 容器配置和引导 Apache Geode。
引入基于注释的方法来配置 Apache Geode 的主要动机 在 Spring 上下文中,使 Spring 应用程序开发人员能够尽可能快速、轻松地启动和运行。
让我们开始吧!
如果您想更快地开始,请参阅 Quick Start 部分。 |
6.1. 简介
Apache Geode 以及 Spring Data for Apache Geode 提供了许多配置选项:
此外,Apache Geode 和 Spring Data for Apache Geode 都支持不同的拓扑:
在设置和使用 正确地使用 Apache Geode。Spring Data for Apache Geode 基于注释的配置模型旨在 简化拓扑上下文中的配置,以及更多。
基于注释的配置模型是使用 Spring Data for Apache Geode 的 XML 命名空间的基于 XML 的配置的替代方法。
使用 XML,您可以使用 XML 架构进行配置,使用 XML 架构进行数据访问。
有关更多详细信息,请参阅“使用 Spring 容器引导 Apache Geode”。gfe
gfe-data
从 SDG 2.0 开始,基于注释的配置模型尚不支持 Apache Geode 的 WAN 组件和拓扑。 |
与 Spring Boot 一样,Spring Data for Apache Geode 基于注释的配置模型被设计为一种固执己见的 convention-over-configuration 方法。事实上,这种基于 Comments 的配置模型 的灵感来自 Spring Boot 以及其他几个 Spring 和 Spring Data 项目。
按照惯例,所有 Comments 都为所有配置属性提供合理且合理的默认值。 给定 annotation 属性的默认值直接对应于 Apache Geode 的配置属性。
目的是让您通过声明适当的
注解,而无需不必要地配置
大量属性仅用于使用功能或服务。@Configuration
@SpringBootApplication
同样,快速、轻松地开始是主要目标。
但是,如果需要,可以选择自定义 Apache Geode 的配置元数据和行为。 Spring Data for Apache Geode 基于注释的配置悄悄地退缩了。您只需指定配置属性 您希望进行调整。此外,正如我们将在本文档后面看到的那样,有几种方法可以配置 Apache Geode feature 或 embedded service 结合使用。
您可以在包中找到所有新的 SDG Java。Annotations
org.springframework.data.gemfire.config.annotation
6.2. 使用 Spring 配置 Apache Geode 应用程序
与所有 Spring Boot 应用程序一样,它们首先使用 ,
Spring Boot 应用程序可以通过声明以下三个中的任何一个来轻松成为 Apache Geode 缓存应用程序
主要注释:@SpringBootApplication
-
@ClientCacheApplication
-
@PeerCacheApplication
-
@CacheServerApplication
这三个注释是 Spring 应用程序开发人员在使用 Apache Geode 时的起点。
要实现这些 Comments 背后的意图,您必须了解有两种类型的缓存实例 可以使用 Apache Geode 创建:客户端缓存或对等缓存。
您可以将 Spring Boot 应用程序配置为 Apache Geode 缓存客户端,实例为 ,
它可以与用于管理应用程序数据的现有 Apache Geode 服务器集群进行通信。
客户端-服务器拓扑是使用 Apache Geode 时最常用的系统架构,您可以
使 Spring Boot 应用程序成为具有实例的缓存客户端,只需用 .ClientCache
ClientCache
@ClientCacheApplication
或者,Spring Boot 应用程序可以是 Apache Geode 集群的对等成员。即应用程序
它本身只是服务器集群中管理数据的另一台服务器。Spring Boot 应用程序创建
一个“嵌入式”对等实例(当您使用 .Cache
@PeerCacheApplication
通过扩展,对等缓存应用程序也可以充当 too,允许缓存客户端连接
并在服务器上执行数据访问操作。这是通过用 代替 来注释应用程序类来实现的,这会创建一个对等实例以及
允许缓存客户端连接的。CacheServer
@CacheServerApplication
@PeerCacheApplication
Cache
CacheServer
默认情况下,Apache Geode 服务器不一定是缓存服务器。也就是说,服务器不一定是
设置为仅因为它是服务器而为 Cache 客户端提供服务。Apache Geode 服务器可以是对等成员(数据节点)
的集群在不为任何客户端提供服务的情况下管理数据,而集群中的其他对等成员确实已设置
除了管理数据之外,还为客户提供服务。还可以将集群中的某些 Peer 成员设置为
非数据节点,称为数据访问器,
它们不存储数据,但充当代理,以 .许多不同的拓扑
和 cluster arrangement 受 Apache Geode 支持,但不在本文档的讨论范围之内。CacheServers |
例如,如果要创建 Spring Boot 缓存客户端应用程序,请从以下内容开始:
ClientCache
@SpringBootApplication
@ClientCacheApplication
class ClientApplication { .. }
或者,如果要创建具有嵌入式对等实例的 Spring Boot 应用程序,则您的应用程序
将是 Apache Geode 形成的集群(分布式系统)的服务器和对等成员,
从以下内容开始:Cache
Cache
@SpringBootApplication
@PeerCacheApplication
class ServerApplication { .. }
或者,您也可以使用 annotation 代替 来创建
嵌入式对等实例以及正在运行的 ,侦听默认的
缓存服务器端口,如下所示:@CacheServerApplication
@PeerCacheApplication
Cache
CacheServer
localhost
40404
Cache
CacheServer
@SpringBootApplication
@CacheServerApplication
class ServerApplication { .. }
6.3. 客户端/服务器应用程序详细信息
客户端可以通过多种方式连接到 Apache Geode 集群中的服务器并与之通信。 最常见和推荐的方法是使用 Apache Geode 定位器。
缓存客户端可以连接到 Apache Geode 群集中的一个或多个定位器,而不是直接连接到 .与直接连接相比,使用 Locator 的优势在于 Locator 提供元数据
关于客户端连接到的集群。此元数据包括哪些服务器包含
感兴趣的数据或哪些服务器的负载最小。客户端与 Locator 结合使用
还提供 A 崩溃时的故障转移功能。通过启用区域 (PR)
单跳功能,客户端将直接路由到包含所请求数据的服务器
并且客户需要。CacheServer CacheServer Pool CacheServer PARTITION Pool |
定位器也是集群中的对等成员。定位器实际上构成了 Apache Geode 节点。也就是说,由 Locator 连接的所有节点都是集群中的 Peer 节点,并且是新成员 使用 Locators 加入集群并查找其他成员。 |
默认情况下,Apache Geode 会设置一个 “DEFAULT” 连接到正在运行的 、
在创建实例时侦听 port。A 侦听端口 ,
接受所有系统 NIC 上的连接。您无需执行任何特殊操作即可使用客户端-服务器拓扑。
只需使用 和 Client 端 Comments 服务器端 Spring Boot 应用程序
Spring Boot 应用程序,然后您就可以开始了。Pool
CacheServer
localhost
40404
ClientCache
CacheServer
40404
@CacheServerApplication
@ClientCacheApplication
如果您愿意,您甚至可以使用 Gfsh 的命令启动您的服务器。无论 Spring Boot 是如何启动的,它仍然可以连接到服务器。但是,您可能更愿意配置和启动
servers 结合使用 Spring Data for Apache Geode 方法,因为正确注释的 Spring Boot 应用程序类要直观得多
并且更易于调试。start server
@ClientCacheApplication
作为应用程序开发人员,您无疑希望自定义 Apache Geode 设置的“DEFAULT”
可能连接到一个或多个 Locator,如下例所示:Pool
ClientCache
@SpringBootApplication
@ClientCacheApplication(locators = {
@Locator(host = "boombox" port = 11235),
@Locator(host = "skullbox", port = 12480)
})
class ClientApplication { .. }
除了 attribute,annotation 也有一个 attribute。
该属性可用于指定一个或多个嵌套 Comments,这些 Comments 允许缓存客户端
如有必要,请直接连接到一个或多个服务器。locators
@ClientCacheApplication
servers
servers
@Server
您可以使用 or 属性,但不能同时使用两者(这是由 Apache Geode 强制执行的)。locators servers |
您还可以配置其他实例(Apache Geode 提供的“DEFAULT”除外
当使用注释创建实例时),通过使用 AND 注释。Pool
Pool
ClientCache
@ClientCacheApplication
@EnablePool
@EnablePools
@EnablePools 是一个复合注释,它聚合了
单个类。Java 8 及更早版本不允许声明多个相同类型的 Comments
在单个类上。@EnablePool |
以下示例使用 and 注释:@EnablePool
@EnablePools
ClientCache
Pools
@SpringBootApplication
@ClientCacheApplication(logLevel = "info")
@EnablePool(name = "VenusPool", servers = @Server(host = "venus", port = 48484),
min-connections = 50, max-connections = 200, ping-internal = 15000,
prSingleHopEnabled = true, readTimeout = 20000, retryAttempts = 1,
subscription-enable = true)
@EnablePools(pools = {
@EnablePool(name = "SaturnPool", locators = @Locator(host="skullbox", port=20668),
subsription-enabled = true),
@EnablePool(name = "NeptunePool", severs = {
@Server(host = "saturn", port = 41414),
@Server(host = "neptune", port = 42424)
}, min-connections = 25))
})
class ClientApplication { .. }
该属性是注释的唯一必需属性。正如我们稍后将看到的,值
对应于在 Spring 容器中创建的 bean 的名称以及
用于引用相应配置属性的名称。它也是已注册
并由 Apache Geode 使用。name
@EnablePool
name
Pool
Pool
同样,在服务器上,您可以配置客户端可以连接到的多个,如下所示:CacheServers
CacheServer
CacheServers
@SpringBootApplication
@CacheSeverApplication(logLevel = "info", autoStartup = true, maxConnections = 100)
@EnableCacheServer(name = "Venus", autoStartup = true,
hostnameForClients = "venus", port = 48484)
@EnableCacheServers(servers = {
@EnableCacheServer(name = "Saturn", hostnameForClients = "saturn", port = 41414),
@EnableCacheServer(name = "Neptune", hostnameForClients = "neptune", port = 42424)
})
class ServerApplication { .. }
Like ,是一个复合注释,用于在单个类上聚合多个注释。同样,Java 8 及更早版本不允许多个相同类型的注释
在单个类上声明。@EnablePools @EnableCacheServers @EnableCacheServer |
细心的读者可能已经注意到的一件事是,在所有情况下,您都为所有 主机名、端口和面向配置的 annotation 属性。当应用程序获得 提升并部署到不同的环境,例如从 DEV 到 QA 到 STAGING 再到 PROD。
下一节介绍如何处理在运行时确定的动态配置。
6.4. 配置和引导定位器
除了 Apache Geode Cache 应用程序,您还可以创建 Apache Geode Locator 应用程序。
Apache Geode 定位器是一个 JVM 进程,它允许节点作为对等成员加入 Apache Geode 集群。 定位器还使客户端能够发现集群中的服务器。Locator 将元数据提供给客户端,以统一 在集群中的成员之间平衡负载,启用单跳数据访问操作以及其他操作。
对 Locator 的完整讨论超出了本文档的范围。鼓励读者阅读 Apache Geode 用户指南,了解有关定位器及其在集群中的角色的更多详细信息。
要配置和引导独立的 Locator 进程,请执行以下操作:
@SpringBootApplication
@LocatorApplication(port = 12345)
class LocatorApplication { ... }
您可以在集群中启动多个 Locator。唯一的要求是成员名称必须是唯一的
在集群中。使用注释的属性将成员命名为 Locator
在集群中。或者,您可以在 Spring Boot 的 .name
@LocatorApplication
spring.data.gemfire.locator.name
application.properties
此外,如果您在同一个 Locator 上分叉多个 Locator,则必须确保每个 Locator 都从唯一的端口开始
机器。设置 annotation 属性或 property。port
spring.data.gemfire.locator.port
然后,您可以在集群中启动 1 个或多个 Apache Geode 对等缓存成员,这些成员由 Locator 或 Locator 联接。 也使用 Spring 进行配置和引导,如下所示:
CacheServer
localhost
12345
@SpringBootApplication
@CacheServerApplication(locators = "localhost[12345]")
class ServerApplication { ... }
同样,您可以根据需要开始任意数量的课程,并通过上面的定位器加入。
您只需确保成员具有唯一名称。ServerApplication
@LocatorApplication
用于配置和引导独立的 Apache Geode Locator 应用程序进程。
此进程只能是 Locator,不能是其他进程。如果您尝试使用缓存实例启动 Locator,SDG 将
throw 一个错误。
如果你想同时启动缓存实例和嵌入的 Locator,那么你应该使用
而 annotation 则被替换。@EnableLocator
在开发过程中,启动嵌入式 Locator 非常方便。但是,强烈建议您独立运行 生产中的定位器进程以实现高可用性。如果集群中的所有 Locator 都已关闭,则集群 将保持不变,但是,没有新成员能够加入集群,这对于线性扩展很重要 以满足需求。
有关更多详细信息,请参阅配置嵌入式定位器部分。
6.5. 运行时配置Configurers
设计基于 Comments 的配置模型时的另一个目标是在 Comments 中保持类型安全
属性。例如,如果 configuration 属性可以表示为 an(例如端口号),则
则属性的类型应为 .int
int
不幸的是,这不利于运行时的动态和可解析配置。
Spring 的一个更精细的功能是能够使用属性占位符和 SPEL 表达式
在 Spring 容器中配置 bean 时,在配置元数据的属性或属性中。
但是,这将要求所有 annotation 属性都是 type ,从而放弃类型安全,
这是不可取的。String
因此,Spring Data for Apache Geode 借鉴了 Spring 中的另一种常用模式。Spring Web MVC 中提供了许多不同的接口,包括org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer
。Configurers
Configurer
该设计模式使应用程序开发人员能够接收回调以自定义配置
的组件或 Bean 中。框架回调用户提供的代码来调整配置
在运行时。此模式更常见的用途之一是提供基于
应用程序的运行时环境。Configurers
Spring Data for Apache Geode 提供了多个回调接口来自定义基于 Comments 的不同方面
配置元数据,在 Comments 创建的 Spring managed bean 初始化之前:Configurer
-
CacheServerConfigurer
-
ClientCacheConfigurer
-
ContinuousQueryListenerContainerConfigurer
-
DiskStoreConfigurer
-
IndexConfigurer
-
PeerCacheConfigurer
-
PoolConfigurer
-
RegionConfigurer
-
GatewayReceiverConfigurer
-
GatewaySenderConfigurer
例如,您可以使用 和 自定义端口号
分别由 Spring Boot 和应用程序使用。CacheServerConfigurer
ClientCacheConfigurer
CacheServer
ClientCache
请考虑以下来自服务器应用程序的示例:
CacheServer
CacheServerConfigurer
@SpringBootApplication
@CacheServerApplication(name = "SpringServerApplication")
class ServerApplication {
@Bean
CacheServerConfigurer cacheServerPortConfigurer(
@Value("${gemfire.cache.server.host:localhost}") String cacheServerHost
@Value("${gemfire.cache.server.port:40404}") int cacheServerPort) {
return (beanName, cacheServerFactoryBean) -> {
cacheServerFactoryBean.setBindAddress(cacheServerHost);
cacheServerFactoryBean.setHostnameForClients(cacheServerHost);
cacheServerFactoryBean.setPort(cacheServerPort);
};
}
}
接下来,考虑以下来自客户端应用程序的示例:
ClientCache
ClientCacheConfigurer
@SpringBootApplication
@ClientCacheApplication
class ClientApplication {
@Bean
ClientCacheConfigurer clientCachePoolPortConfigurer(
@Value("${gemfire.cache.server.host:localhost}") String cacheServerHost
@Value("${gemfire.cache.server.port:40404}") int cacheServerPort) {
return (beanName, clientCacheFactoryBean) ->
clientCacheFactoryBean.setServers(Collections.singletonList(
new ConnectionEndpoint(cacheServerHost, cacheServerPort)));
}
}
通过使用提供的 ,您可以接收回调以进一步自定义配置
这是在运行时启动期间由关联的注释启用的。Configurers
此外,当 在 Spring 容器中声明为 bean 时,bean 定义可以利用
其他 Spring 容器功能,例如属性占位符、使用注释的 SPEL 表达式
on factory method 参数,依此类推。Configurer
@Value
Spring Data for Apache Geode 提供的所有内容在回调中获取两位信息:创建的 bean 的名称
在 Spring 容器中,通过注释和对 using 的引用由注释发送到
创建并配置 Apache Geode 组件(例如,创建一个实例
并配置了 )。Configurers
FactoryBean
ClientCache
ClientCacheFactoryBean
SDG 是 SDG 公共 API 的一部分,如果这个新的基于 Comments 的
配置模型。事实上,注解本身也在使用这些相同的配置。因此,从本质上讲,注解是一个提供额外的抽象层的门面
为了方便。FactoryBeans FactoryBeans |
鉴于 a 可以像任何其他 POJO 一样被声明为常规的 bean 定义,你可以将不同的
Spring 配置选项,例如使用 Spring Profiles 和 同时使用两个属性占位符
和 SpEL 表达式。这些和其他漂亮的功能让您可以创建更复杂、更灵活的配置。Configurer
Conditions
但是,并不是唯一的选择。Configurers
6.6. 运行时配置Properties
除了 之外,基于注释的配置模型中的每个 annotation 属性都与
相应的配置属性(前缀为 ),可以在Spring Boot文件中声明。Configurers
spring.data.gemfire.
application.properties
在前面的示例的基础上,客户端的文件将定义以下内容
属性集:application.properties
application.properties
spring.data.gemfire.cache.log-level=info
spring.data.gemfire.pool.Venus.servers=venus[48484]
spring.data.gemfire.pool.Venus.max-connections=200
spring.data.gemfire.pool.Venus.min-connections=50
spring.data.gemfire.pool.Venus.ping-interval=15000
spring.data.gemfire.pool.Venus.pr-single-hop-enabled=true
spring.data.gemfire.pool.Venus.read-timeout=20000
spring.data.gemfire.pool.Venus.subscription-enabled=true
spring.data.gemfire.pool.Saturn.locators=skullbox[20668]
spring.data.gemfire.pool.Saturn.subscription-enabled=true
spring.data.gemfire.pool.Neptune.servers=saturn[41414],neptune[42424]
spring.data.gemfire.pool.Neptune.min-connections=25
相应服务器的文件将定义以下属性:application.properties
application.properties
spring.data.gemfire.cache.log-level=info
spring.data.gemfire.cache.server.port=40404
spring.data.gemfire.cache.server.Venus.port=43434
spring.data.gemfire.cache.server.Saturn.port=41414
spring.data.gemfire.cache.server.Neptune.port=41414
然后,您可以将类简化为以下内容:@ClientCacheApplication
@ClientCacheApplication
@SpringBootApplication
@ClientCacheApplication
@EnablePools(pools = {
@EnablePool(name = "Venus"),
@EnablePool(name = "Saturn"),
@EnablePool(name = "Neptune")
})
class ClientApplication { .. }
此外,该类将变为以下内容:@CacheServerApplication
@CacheServerApplication
@SpringBootApplication
@CacheServerApplication(name = "SpringServerApplication")
@EnableCacheServers(servers = {
@EnableCacheServer(name = "Venus"),
@EnableCacheServer(name = "Saturn"),
@EnableCacheServer(name = "Neptune")
})
class ServerApplication { .. }
前面的示例说明了为什么“命名”基于 Comments 的 bean 很重要(除了因为它是必需的 在某些情况下)。这样做可以从 XML、properties、 和 Java。甚至可以将 Comments 定义的 bean 注入到应用程序类中,无论出于何种目的, 如下例所示:
@Component
class MyApplicationComponent {
@Resource(name = "Saturn")
CacheServer saturnCacheServer;
...
}
同样,命名注解定义的 bean 允许您编写代码 a 来自定义特定的 “命名” bean
由于 IS 是传递给回调的 2 个参数中的 1 个。Configurer
beanName
通常,关联的 annotation 属性属性有两种形式:“named” 属性以及 “未命名”属性。
以下示例显示了这种安排:
spring.data.gemfire.cache.server.bind-address=10.105.20.1
spring.data.gemfire.cache.server.Venus.bind-address=10.105.20.2
spring.data.gemfire.cache.server.Saturn...
spring.data.gemfire.cache.server.Neptune...
虽然上面有三个命名的属性,但还有一个未命名的属性提供
该属性的任何未指定值的默认值,即使对于 “named” 也是如此。所以,虽然“维纳斯”
设置并覆盖其自己的 “Saturn” 和 “Neptune” 继承自 “unnamed” 属性。CacheServers
CacheServer
CacheServers
bind-address
spring.data.gemfire.cache.server.bind-address
请参阅 annotation 的 Javadoc 以了解哪些 annotation 属性支持基于属性的配置 以及它们是否支持“命名”属性而不是默认的“未命名”属性。
的 6.6.1.Properties
Properties
在通常的 Spring 时尚中,您甚至可以用 其他 来表达 ,无论是通过
以下示例显示了在文件中设置的嵌套属性:Properties
Properties
application.properties
spring.data.gemfire.cache.server.port=${gemfire.cache.server.port:40404}
以下示例显示了在 Java 中设置的嵌套属性:
@Bean
CacheServerConfigurer cacheServerPortConfigurer(
@Value("${gemfire.cache.server.port:${some.other.property:40404}}")
int cacheServerPort) {
...
}
属性占位符嵌套的深度可以是任意的。 |
6.7. 配置嵌入式服务
Apache Geode 提供了启动应用程序所需的许多不同的嵌入式服务的能力, 取决于用例。
6.7.1. 配置嵌入式定位器
如前所述,客户端使用 Apache Geode 定位器连接到集群中的服务器并查找服务器。 此外,加入现有集群的新成员使用 Locator 查找其对等节点。
对于应用程序开发人员来说,这通常很方便,因为他们正在开发 Spring Boot 和 Spring Data for Apache Geode
应用程序来启动一个由两个或三个 Apache Geode 服务器组成的小型集群。而不是开始
一个单独的 Locator 进程,你可以用 ,
如下:@CacheServerApplication
@EnableLocator
CacheServer
@SpringBootApplication
@CacheServerApplication
@EnableLocator
class ServerApplication { .. }
该注释在 Spring Apache Geode 应用程序中启动一个嵌入式 Locator
在 上运行,侦听默认定位器端口 。您可以自定义 (bind address)
以及嵌入的 Locator 通过使用相应的 annotation 属性绑定到的 Locator。@EnableLocator
CacheServer
localhost
10334
host
port
或者,您也可以通过在 中设置相应的 和 属性来设置属性。@EnableLocator
spring.data.gemfire.locator.host
spring.data.gemfire.locator.port
application.properties
然后,您可以通过连接到此
定位器具有以下功能:@CacheServerApplication
CacheServer
@SpringBootApplication
@CacheServerApplication(locators = "localhost[10334]")
class ServerApplication { .. }
您甚至可以将前面显示的两个应用程序类合并到一个类中,并使用 IDE 创建不同的 运行 profile configurations 以启动同一类的不同实例,但配置略有修改 通过使用 Java 系统属性,如下所示:
CacheServer
@SpringBootApplication
@CacheServerApplication(locators = "localhost[10334]")
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class);
}
@EnableLocator
@Profile("embedded-locator")
static class Configuration { }
}
然后,对于每个运行配置文件,您可以设置和更改以下系统属性:
spring.data.gemfire.name=SpringCacheServerOne
spring.data.gemfire.cache.server.port=41414
spring.profiles.active=embedded-locator
该类的 1 个运行配置文件应设置 Java system 属性。然后,您可以更改其他每个运行配置文件的 和
并在您的本地系统上运行一个小型 Apache Geode 服务器集群(分布式系统)。ServerApplication
-Dspring.profiles.active=embedded-locator
..name
..cache.server.port
该注释只是开发时注释,而不是其他内容
应用程序开发人员将在生产中使用。我们强烈建议将 Locator 作为独立 Locator 运行,
集群中的独立进程。@EnableLocator |
有关 Apache Geode Locators 工作原理的更多详细信息,请参阅此处。
6.7.2. 配置嵌入式管理器
Apache Geode Manager 是集群中负责集群“管理”的另一个对等成员或节点。
管理包括创建 、 、 、 等,以及监控运行时
集群组件的操作和行为。Regions
Indexes
DiskStores
Manager 允许支持 JMX 的客户端(例如 Gfsh shell 工具)连接到 Manager 以管理集群。 也可以使用 JDK 提供的工具(如 JConsole 或 JVisualVM)连接到 Manager,前提是它们是 两个支持 JMX 的客户端也是如此。
也许您还希望启用前面显示为 Manager 的 Spring。为此,
用 .@CacheServerApplication
@Configuration
@SpringBootApplication
@EnableManager
默认情况下,Manager 绑定到 ,侦听默认的 Manager 端口 。的几个方面
可以使用 Comments 属性或相应的属性配置 Manager。localhost
1099
以下示例显示了如何在 Java 中创建嵌入式 Manager:
CacheServer
@SpringBootApplication
@CacheServerApplication(locators = "localhost[10334]")
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class);
}
@EnableLocator
@EnableManager
@Profile("embedded-locator-manager")
static class Configuration { }
}
通过前面的类,您甚至可以使用 Gfsh 连接到小型集群并对其进行管理,如下所示:
$ gfsh
_________________________ __
/ _____/ ______/ ______/ /____/ /
/ / __/ /___ /_____ / _____ /
/ /__/ / ____/ _____/ / / / /
/______/_/ /______/_/ /_/ 1.2.1
Monitor and Manage {data-store-name}
gfsh>connect
Connecting to Locator at [host=localhost, port=10334] ..
Connecting to Manager at [host=10.99.199.5, port=1099] ..
Successfully connected to: [host=10.99.199.5, port=1099]
gfsh>list members
Name | Id
---------------------- | ----------------------------------------------------
SpringCacheServerOne | 10.99.199.5(SpringCacheServerOne:14842)<ec><v0>:1024
SpringCacheServerTwo | 10.99.199.5(SpringCacheServerTwo:14844)<v1>:1025
SpringCacheServerThree | 10.99.199.5(SpringCacheServerThree:14846)<v2>:1026
由于我们还启用了嵌入式定位器,因此我们可以通过定位器间接连接到 Manager。 定位器允许 JMX 客户端连接并在集群中查找 Manager。如果不存在,则 Locator 将承担该角色 的经理。但是,如果不存在 Locator,则需要使用以下命令直接连接到 Manager:
connect
gfsh>connect --jmx-manager=localhost[1099]
与 annotation 一样,annotation 也意味着开发时
只有 annotation,而不是应用程序开发人员在生产环境中使用的东西。我们强烈建议
Manager 与 Locator 一样,是集群中独立、独立和专用的进程。@EnableLocator @EnableManager |
有关 Apache Geode 管理和监控的更多详细信息,请参阅此处。
6.7.3. 配置嵌入式 HTTP 服务器
Apache Geode 还能够运行嵌入式 HTTP 服务器。当前的实现由 Eclipse Jetty 提供支持。
嵌入式 HTTP 服务器用于托管 Apache Geode 的管理(管理员)REST API(不是公开宣传的 API), 开发人员 REST API, 以及 Pulse Monitoring Web 应用程序。
但是,要使用这些 Apache Geode 提供的 Web 应用程序,您必须完整安装
Apache Geode 已安装在您的系统上,并且必须将环境变量设置为
您的安装目录。GEODE_HOME
要启用嵌入式 HTTP 服务器,请将注释添加到任意或带注释的类,如下所示:@EnableHttpService
@PeerCacheApplication
@CacheServerApplication
CacheServer
@SpringBootApplication
@CacheServerApplication
@EnableHttpService
public class ServerApplication { .. }
默认情况下,嵌入式 HTTP 服务器在 port 上侦听 HTTP 客户端请求。当然,您可以使用
annotation 属性或相应的配置属性,以根据需要调整端口。7070
有关HTTP支持和所提供服务的更多详细信息,请访问前面的链接。
6.7.4. 配置嵌入式 Memcached 服务器 (Gemcached)
Apache Geode 还实现了 Memcached 协议,能够为 Memcached 客户端提供服务。那是 Memcached 客户端可以连接到 Apache Geode 集群并执行 Memcached 操作,就像 集群中的 Apache Geode 服务器是实际的 Memcached 服务器。
要启用嵌入式 Memcached 服务,请将注释添加到任意或带注释的类,如下所示:@EnableMemcachedServer
@PeerCacheApplication
@CacheServerApplication
CacheServer
@SpringBootApplication
@CacheServerApplication
@EnabledMemcachedServer
public class ServerApplication { .. }
有关 Apache Geode 的 Memcached 服务(称为“Gemcached”)的更多详细信息,请参阅此处。
6.7.5. 配置嵌入式 Redis 服务器
Apache Geode 还实现了 Redis 服务器协议,使 Redis 客户端能够连接到并进行通信 使用 Apache Geode 服务器集群来发出 Redis 命令。在撰写本文时,Redis 服务器协议 Apache Geode 中的支持仍处于试验阶段。
要启用嵌入式 Redis 服务,请将注释添加到任意类或带注释的类,如下所示:@EnableRedisServer
@PeerCacheApplication
@CacheServerApplication
CacheServer
@SpringBootApplication
@CacheServerApplication
@EnableRedisServer
public class ServerApplication { .. }
您必须在 Spring [Boot] 应用程序上显式声明该模块
classpath 的org.apache.geode:geode-redis |
有关 Apache Geode 的 Redis 适配器的更多详细信息,请参阅此处。
6.8. 配置日志记录
通常,有必要打开日志记录,以便准确了解 Apache Geode 正在做什么以及何时执行。
要启用 Logging,请使用并设置适当的属性来注释您的应用程序类
或关联的属性,如下所示:@EnableLogging
ClientCache
@SpringBootApplication
@ClientCacheApplication
@EnableLogging(logLevel="info", logFile="/absolute/file/system/path/to/application.log)
public class ClientApplication { .. }
虽然可以使用所有基于缓存的应用程序注释来指定该属性
(例如,),使用
注释。logLevel
@ClientCacheApplication(logLevel="info")
@EnableLogging
此外,您还可以通过设置属性
在。log-level
spring.data.gemfire.logging.level
application.properties
有关更多详细信息,请参阅 @EnableLogging
注释 Javadoc。
6.9. 配置统计信息
要在运行时更深入地了解 Apache Geode,您可以启用统计信息。收集统计数据 在复杂问题(通常分布在自然界中)时,便于系统分析和故障排除 在时间是关键因素的地方,就会发生。
启用统计信息后,您可以使用 Apache Geode 的 VSD(可视化统计信息显示)工具 以分析收集的统计数据。
要启用统计信息,请使用 . 注释您的应用程序类,如下所示:@EnableStatistics
ClientCache
@SpringBootApplication
@ClientCacheApplication
@EnableStatistics
public class ClientApplication { .. }
在评估性能时,在服务器上启用统计信息特别有价值。为此,
用 .@PeerCacheApplication
@CacheServerApplication
@EnableStatistics
您可以使用 annotation 属性或关联的属性进行自定义
统计信息收集和收集过程。@EnableStatistics
有关更多详细信息,请参阅 @EnableStatistics
注释 Javadoc。
有关 Apache Geode 统计数据的更多详细信息,请点击此处。
6.10. 配置 PDX
Apache Geode 更强大的功能之一是 PDX 序列化。 虽然对 PDX 的完整讨论超出了本文档的范围,但使用 PDX 进行序列化要好得多 Java 序列化的替代方案,具有以下优势:
-
PDX 使用集中式类型注册表来使对象的序列化字节更加紧凑。
-
PDX 是一种中性序列化格式,允许 Java 和 Native 客户端对同一数据集进行操作。
-
PDX 支持版本控制,并允许添加或删除对象字段,而不会影响现有应用程序 使用已更改的 PDX 序列化对象的旧版本或新版本,而不会丢失数据。
-
PDX 允许在 OQL 查询投影和谓词中单独访问对象字段,而无需对象 需要先反序列化。
通常,每当数据传入或传出客户端和服务器时,都需要在 Apache Geode 中进行序列化 或者在正常的分发和复制过程中以及数据溢出时,集群中的对等节点之间 或持久化到磁盘。
启用 PDX 序列化比修改所有应用程序域对象类型以实现要简单得多,尤其是当不希望对
应用程序域模型,或者您无法控制要序列化的对象,这尤其
true(例如,考虑具有类型的地理空间 API)。java.io.Serializable
Coordinate
要启用 PDX,请使用 . 注释您的应用程序类,如下所示:@EnablePdx
ClientCache
@SpringBootApplication
@ClientCacheApplication
@EnablePdx
public class ClientApplication { .. }
通常,应用程序的域对象类型要么实现 org.apache.geode.pdx.PdxSerializable
接口,要么您可以实现并注册 org.apache.geode.pdx.PdxSerializer
接口的非侵入性实现,以处理需要序列化的所有应用程序域对象类型。
不幸的是,Apache Geode 只允许注册一个,这意味着所有应用程序
Domain 对象类型需要由单个实例处理。然而,这是一个严重的反模式
以及无法维持的做法。PdxSerializer
PdxSerializer
尽管只能向 Apache Geode 注册单个实例,但创建
每个应用程序域对象类型的单个实施。PdxSerializer
PdxSerializer
通过使用复合软件设计模式,您可以提供
接口的实现,它聚合了所有特定于 Application Domain Object Type 的实例,但充当单个实例并注册它。PdxSerializer
PdxSerializer
PdxSerializer
您可以在 Spring 容器中将此组合声明为托管 Bean,并使用该属性在注释中通过其 Bean 名称引用此组合。适用于 Apache Geode 的 Spring Data
代表您向 Apache Geode 注册它。PdxSerializer
PdxSerializer
@EnablePdx
serializerBeanName
以下示例显示如何创建自定义复合 :PdxSerializer
ClientCache
PdxSerializer
@SpringBootApplication
@ClientCacheApplication
@EnablePdx(serializerBeanName = "compositePdxSerializer")
public class ClientApplication {
@Bean
PdxSerializer compositePdxSerializer() {
return new CompositePdxSerializerBuilder()...
}
}
也可以在 Spring 上下文中将 Apache Geode 的 org.apache.geode.pdx.ReflectionBasedAutoSerializer
声明为 bean 定义。
或者,您应该使用 Spring Data for Apache Geode 更强大的 org.springframework.data.gemfire.mapping.MappingPdxSerializer
。
它使用 Spring Data 映射元数据和应用于序列化过程的基础设施来提高效率
处理而不是单独的反射。
PDX 的许多其他方面和功能都可以通过 annotation 属性进行调整
或关联的配置属性。@EnablePdx
有关更多详细信息,请参见 @EnablePdx
注释 Javadoc。
6.11. 配置 Apache Geode 属性
虽然许多 gemfire.properties 可以方便地封装在基于 SDG 注释的 SDG 中并通过注释进行抽象
配置模型,则仍可从
注释。@EnableGemFireProperties
使用注释应用程序类很方便,并且是创建
文件或将 Apache Geode 属性设置为命令行上的 Java 系统属性
启动应用程序时。@EnableGemFireProperties
gemfire.properties
建议在部署时在文件中设置这些 Apache Geode 属性
将应用程序投入生产。但是,在开发时,单独设置这些属性会很方便。
根据需要,用于原型设计、调试和测试目的。gemfire.properties |
您通常无需担心的一些不太常见的 Apache Geode 属性的一些示例包括:
但不限于:、 和其他。ack-wait-threshold
disable-tcp
socket-buffer-size
要单独设置任何 Apache Geode 属性,请使用要更改的 Apache Geode 属性来批注应用程序类,并从 Apache Geode 设置的默认值中设置 Apache Geode 属性
替换为相应的属性,如下所示:@EnableGemFireProperties
ClientCache
@SpringBootApplication
@ClientCacheApplication
@EnableGemFireProperties(conflateEvents = true, socketBufferSize = 16384)
public class ClientApplication { .. }
请记住,某些 Apache Geode 属性是特定于客户端的(例如, ),
而其他 Cookie 则特定于服务器 (例如 、 等)。conflateEvents
distributedSystemId
enableNetworkPartitionDetection
enforceUniqueHost
memberTimeout
redundancyZone
有关 Apache Geode 属性的更多详细信息,请参阅此处。
6.12. 配置区域
到目前为止,在 PDX 之外,我们的讨论主要集中在配置 Apache Geode 的更多管理功能上:
创建缓存实例、启动嵌入式服务、启用日志记录和统计信息、配置 PDX 以及 用于影响低级配置和行为。虽然所有这些配置选项都很重要,
它们都与您的应用程序没有直接关系。换句话说,我们仍然需要一些地方来存储我们的应用程序数据
并使其普遍可用和可访问。gemfire.properties
Apache Geode 将缓存中的数据组织到区域中。 您可以将 Region 视为关系数据库中的表。通常,Region 应该只存储一种类型的对象 这使得它更有利于构建有效的索引和编写查询。我们稍后会介绍索引。
以前,Spring Data for Apache Geode 用户需要显式定义和声明其应用程序用于存储数据的区域
通过编写非常详细的 Spring 配置元数据,无论是使用 API 中的 SDG
使用 Spring 的基于 Java 的容器配置或使用 XML。FactoryBeans
以下示例演示了如何在 Java 中配置 Region Bean:
@Configuration
class GemFireConfiguration {
@Bean("Example")
PartitionedRegionFactoryBean exampleRegion(GemFireCache gemfireCache) {
PartitionedRegionFactoryBean<Long, Example> exampleRegion =
new PartitionedRegionFactoryBean<>();
exampleRegion.setCache(gemfireCache);
exampleRegion.setClose(false);
exampleRegion.setPersistent(true);
return exampleRegion;
}
...
}
以下示例演示了如何在 XML 中配置相同的 Region Bean:
<gfe:partitioned-region id="exampleRegion" name="Example" persistent="true">
...
</gfe:partitioned-region>
虽然 Java 和 XML 配置都不是那么难指定,但任何一个都可能很麻烦,尤其是在 应用程序需要大量 Region。许多基于关系数据库的应用程序可以有数百个 甚至数千张桌子。
手动定义和声明所有这些 Region 会很麻烦且容易出错。好吧,现在有更好的方法了。
现在,您可以根据区域的应用程序域对象(实体)本身定义和配置区域。现在不再
除非需要,否则您需要在 Spring 配置元数据中显式定义 bean 定义
更精细的控制。Region
为了简化区域创建,Spring Data for Apache Geode 将 Spring Data Repositories 的使用与富有表现力的
使用新注释的基于 Annotation 的配置的强大功能。@EnableEntityDefinedRegions
大多数 Spring Data 应用程序开发人员应该已经熟悉 Spring Data Repository 抽象和 Spring Data for Apache Geode 的实现 / 扩展。 它经过专门定制,以优化 Apache Geode 的数据访问操作。 |
首先,应用程序开发人员首先定义应用程序的域对象(实体),如下所示:
@Region("Books")
class Book {
@Id
private ISBN isbn;
private Author author;
private Category category;
private LocalDate releaseDate;
private Publisher publisher;
private String title;
}
接下来,通过扩展 Spring Data Commons 接口来定义一个基本存储库,如下所示:Books
org.springframework.data.repository.CrudRepository
interface BookRepository extends CrudRepository<Book, ISBN> { .. }
它是一个数据访问对象 (DAO),提供基本的数据访问
操作 (CRUD) 以及对简单查询的支持(例如 )。您可以定义附加的、
通过在存储库界面上声明查询方法进行更复杂的查询
(例如,)。org.springframe.data.repository.CrudRepository
findById(..)
List<BooK> findByAuthor(Author author);
在后台, Spring Data for Apache Geode 提供了应用程序存储库接口的实现,当 Spring 容器被引导。SDG 甚至会实现您定义的查询方法,只要您遵循 惯例。
现在,在定义类时,您还指定了映射(存储)实例的 Region
通过在实体的类型上声明 Spring Data for Apache Geode 映射注释。当然,如果实体类型 (,
在本例中)在 repository 接口的 type 参数中引用(在本例中为
未使用 进行注释,则名称派生自实体类型的简单类名(也称为
在本例中)。Book
Book
@Region
Book
BookRepository
@Region
Book
Spring Data for Apache Geode 使用映射上下文,其中包含应用程序中定义的所有实体的映射元数据。 以确定运行时需要的所有区域。
要启用和使用此功能,请使用 . 注释 application 类,如下所示:@EnableEntityDefinedRegions
@SpringBootApplication
@ClientCacheApplication
@EnableEntityDefinedRegions(basePackages = "example.app.domain")
@EnableGemfireRepositories(basePackages = "example.app.repo")
class ClientApplication { .. }
在应用程序中使用 Spring Data Repositories 时,从实体类创建 Region 最有用。
Spring Data for Apache Geode 的存储库支持是通过注释启用的,如
前面的示例。@EnableGemfireRepositories |
目前,扫描仅选取显式注释的实体类
,并将创建 Region。如果未显式映射实体类,则不会创建 Region。@Region @Region |
默认情况下,注解以递归方式扫描实体类,从
声明 annotation 的 Configuration 类的 package。@EnableEntityDefinedRegions
@EnableEntityDefinedRegions
但是,通常通过将属性设置为
包含应用程序实体类的包名称。basePackages
或者,您可以使用 more-type-safe 属性来指定要扫描的软件包
通过将属性设置为包含实体类的包中的实体类型,或使用非实体
placeholder 类,专门用于标识要扫描的包。basePackageClasses
以下示例显示如何指定要扫描的实体类型:
@SpringBootApplication
@ClientCacheApplication
@EnableGemfireRepositories
@EnableEntityDefinedRegions(basePackageClasses = {
example.app.books.domain.Book.class,
example.app.customers.domain.Customer.class
})
class ClientApplication { .. }
除了指定开始扫描的位置(如 Spring 的 Comments)之外,您还可以使用与 Comments 相同的语义指定和过滤。@ComponentScan
include
exclude
org.springframework.context.annotation.ComponentScan.Filter
有关更多详细信息,请参阅 @EnableEntityDefinedRegions
注释 Javadoc。
6.12.1. 配置特定于类型的区域
Apache Geode 支持许多不同类型的区域。
每种类型对应于区域的 DataPolicy
,
它准确决定了如何管理区域中的数据(即分布式、复制等)。
其他配置设置(例如区域的配置设置)也会影响数据的管理方式。
有关更多详细信息,请参阅 Apache Geode 用户指南 中的“存储和分发选项”。scope |
当您使用通用映射注释注释应用程序域对象类型时,Spring Data for Apache Geode 将决定
要创建的 Region 类型。SDG 的默认策略在以下情况下会考虑缓存类型
确定要创建的 Region 的类型。@Region
例如,如果使用 annotation 将应用程序声明为 a,
SDG 默认创建一个客户端。或者,如果您将应用程序声明为
peer 使用 OR 注解,
SDG 默认创建一个服务器。ClientCache
@ClientCacheApplication
PROXY
Region
Cache
@PeerCacheApplication
@CacheServerApplication
PARTITION
Region
当然,您始终可以在必要时覆盖默认值。要覆盖 Spring Data for Apache Geode 应用的默认值, 引入了四个新的区域映射注释:
-
@ClientRegion
-
@LocalRegion
-
@PartitionRegion
-
@ReplicateRegion
映射注释特定于客户端应用程序。所有其他区域映射注释
上面列出的只能在具有 Embedded Peer 的服务器应用程序中使用 .@ClientRegion
Cache
有时,客户端应用程序需要创建和使用仅限本地的区域,这可能是为了聚合数据 从其他区域,以便在本地分析数据并执行应用程序执行的某些功能 代表用户。在这种情况下,除非其他 应用程序需要访问结果。此区域甚至可能是临时的,并在使用后丢弃,这可能是 通过区域本身的空闲超时 (TTI) 和生存时间 (TTL) 过期策略完成。 (有关过期策略的更多信息,请参阅“配置过期”。
区域级空闲超时 (TTI) 和生存时间 (TTL) 过期策略独立于 入门级 TTI 和 TTL 过期策略。 |
在任何情况下,如果您想创建一个仅限本地的客户端区域,将数据不会分发回
服务器上对应的 Region 同名,可以声明 mapping annotation
并将属性设置为 ,如下所示:@ClientRegion
shortcut
ClientRegionShortcut.LOCAL
ClientCache
@ClientRegion(shortcut = ClientRegionShortcut.LOCAL)
class ClientLocalEntityType { .. }
所有特定于 Region 类型的注释都提供了在 Region 类型中通用的其他属性
以及仅特定于该类型的 Region。例如,和 属性
在注释中,Apply to server-side(仅适用于服务器端)、Regions only(仅限区域)。collocatedWith
redundantCopies
PartitionRegion
PARTITION
有关 Apache Geode Region 类型的更多详细信息,请参阅此处。
6.12.2. 配置的集群定义区域
除了注释之外,Spring Data for Apache Geode 还提供反向注释 .而不是将 Region 基于定义和驱动的实体类
您的应用程序用例 (UC) 和要求(最常见和合乎逻辑的方法),或者,您可以
从应用程序到的集群中已定义的区域中声明您的区域
将连接。@EnableEntityDefinedRegions
@EnableClusterDefinedRegions
ClientCache
这允许您使用服务器集群作为数据定义的主要来源来集中配置 并确保集群的所有客户端应用程序都具有一致的配置。这特别有用 当快速扩展同一客户端应用程序的大量实例以处理增加的负载时 在云托管环境中。
这个想法是,用户定义 Region,而不是由客户端应用程序驱动数据字典 使用 Apache Geode 的 Gfsh CLI shell 工具。这还有一个额外的优势,即当添加其他对等节点时 对于集群,它们也将拥有并共享相同的配置,因为它会被 Apache Geode 的 Cluster Configuration Service 记住。
例如,用户可以在 Gfsh 中定义一个区域,如下所示:
gfsh>create region --name=Books --type=PARTITION
Member | Status
--------- | --------------------------------------
ServerOne | Region "/Books" created on "ServerOne"
ServerTwo | Region "/Books" created on "ServerTwo"
gfsh>list regions
List of regions
---------------
Books
gfsh>describe region --name=/Books
..........................................................
Name : Books
Data Policy : partition
Hosting Members : ServerTwo
ServerOne
Non-Default Attributes Shared By Hosting Members
Type | Name | Value
------ | ----------- | ---------
Region | size | 0
| data-policy | PARTITION
使用 Apache Geode 的 Cluster Configuration Service,添加到服务器集群的任何其他对等成员 要处理增加的负载(在后端)也将具有相同的配置,例如:
gfsh>list members
Name | Id
--------- | ----------------------------------------------
Locator | 10.0.0.121(Locator:68173:locator)<ec><v0>:1024
ServerOne | 10.0.0.121(ServerOne:68242)<v3>:1025
ServerTwo | 10.0.0.121(ServerTwo:68372)<v4>:1026
gfsh>start server --name=ServerThree --log-level=config --server-port=41414
Starting a Geode Server in /Users/you/geode/cluster/ServerThree...
...
Server in /Users/you/geode/cluster/ServerThree... on 10.0.0.121[41414] as ServerThree is currently online.
Process ID: 68467
Uptime: 3 seconds
Geode Version: 1.2.1
Java Version: 1.8.0_152
Log File: /Users/you/geode/cluster/ServerThree/ServerThree.log
JVM Arguments: -Dgemfire.default.locators=10.0.0.121[10334]
-Dgemfire.use-cluster-configuration=true
-Dgemfire.start-dev-rest-api=false
-Dgemfire.log-level=config
-XX:OnOutOfMemoryError=kill -KILL %p
-Dgemfire.launcher.registerSignalHandlers=true
-Djava.awt.headless=true
-Dsun.rmi.dgc.server.gcInterval=9223372036854775806
Class-Path: /Users/you/geode/cluster/apache-geode-1.2.1/lib/geode-core-1.2.1.jar
:/Users/you/geode/cluster/apache-geode-1.2.1/lib/geode-dependencies.jar
gfsh>list members
Name | Id
----------- | ----------------------------------------------
Locator | 10.0.0.121(Locator:68173:locator)<ec><v0>:1024
ServerOne | 10.0.0.121(ServerOne:68242)<v3>:1025
ServerTwo | 10.0.0.121(ServerTwo:68372)<v4>:1026
ServerThree | 10.0.0.121(ServerThree:68467)<v5>:1027
gfsh>describe member --name=ServerThree
Name : ServerThree
Id : 10.0.0.121(ServerThree:68467)<v5>:1027
Host : 10.0.0.121
Regions : Books
PID : 68467
Groups :
Used Heap : 37M
Max Heap : 3641M
Working Dir : /Users/you/geode/cluster/ServerThree
Log file : /Users/you/geode/cluster/ServerThree/ServerThree.log
Locators : 10.0.0.121[10334]
Cache Server Information
Server Bind :
Server Port : 41414
Running : true
Client Connections : 0
如您所见,“ServerThree” 现在具有 “Books” 区域。如果任何或所有服务器宕机,他们将拥有 相同的配置以及 “Books” 区域。
在客户端,可能会启动许多 Book Store 客户端应用程序实例来处理书籍 Book Store 在线服务。“Books” 区域可能是需要实施的众多不同区域中的 1 个 Book Store 应用程序服务。无需单独创建和配置每个区域,SDG 方便地允许从集群定义客户端应用程序区域,如下所示:
@EnableClusterDefinedRegions
@ClientCacheApplication
@EnableClusterDefinedRegions
class BookStoreClientApplication {
public static void main(String[] args) {
....
}
...
}
@EnableClusterDefinedRegions 只能在客户端上使用。 |
您可以使用 annotation 属性来控制在客户端上创建的 Region 的类型。
默认情况下,将创建一个客户区域。设置为 以实现 “near caching”。此设置适用于从集群定义的区域创建的所有客户端区域。
如果要控制客户端的单个设置(如数据策略),则根据定义的区域创建
在 Cluster 上,那么您可以根据 Region 名称使用自定义逻辑实现 RegionConfigurer 。clientRegionShortcut PROXY clientRegionShortcut ClientRegionShortcut.CACHING_PROXY |
然后,在您的应用程序中使用 “Books” 区域就变得简单了。您可以注入 “Books” 区域 直接,如下所示:
@org.springframework.stereotype.Repository
class BooksDataAccessObject {
@Resource(name = "Books")
private Region<ISBN, Book> books;
// implement CRUD and queries with the "Books" Region
}
或者,甚至根据应用程序域类型(实体)定义 Spring Data Repository 定义
映射到 “Books” 区域,如下所示:Book
interface BookRepository extends CrudRepository<Book, ISBN> {
...
}
然后,您可以将自定义 或 注入到应用程序服务中
组件来执行任何业务功能所需的。BooksDataAccessObject
BookRepository
6.12.3. 配置 Eviction
使用 Apache Geode 管理数据是一项主动任务。通常需要调优,并且必须采用组合 的功能(例如,逐出和过期) 使用 Apache Geode 有效地管理内存中的数据。
鉴于 Apache Geode 是内存数据网格 (IMDG),数据在内存中进行管理并分发到其他节点 ,以最大限度地减少延迟、最大限度地提高吞吐量并确保数据高可用性。 由于并非所有应用程序的数据通常都适合内存(即使在整个节点集群中, 在单个节点上要少得多),您可以通过向集群添加新节点来增加容量。这通常是指 作为线性横向扩展(而不是纵向扩展,这意味着添加更多内存、更多 CPU、更多磁盘、 或更多的网络带宽 — 基本上是每个系统资源的更多,以便处理负载)。
尽管如此,即使对于节点集群,通常也必须只将最重要的数据保留在内存中。
内存耗尽,甚至接近满负荷冒险,很少(如果有的话)是一件好事。Stop-the-world GC
或者更糟糕的是,,将使你的应用程序戛然而止。OutOfMemoryErrors
因此,为了帮助管理内存并保留最重要的数据,Apache Geode 支持最近最少使用 (LRU) 驱逐。也就是说,Apache Geode 根据上次使用 Least Recently Used 算法。
要启用逐出,请使用 . 注释 application 类,如下所示:@EnableEviction
@SpringBootApplication
@PeerCacheApplication
@EnableEviction(policies = {
@EvictionPolicy(regionNames = "Books", action = EvictionActionType.INVALIDATE),
@EvictionPolicy(regionNames = { "Customers", "Orders" }, maximum = 90,
action = EvictionActionType.OVERFLOW_TO_DISK,
type = EvictonPolicyType.HEAP_PERCENTAGE)
})
class ServerApplication { .. }
驱逐策略通常在服务器中的区域上设置。
如前所述,该属性可以指定一个或多个嵌套 annotation,每个 annotation
单独满足需要应用驱逐策略的一个或多个区域。policies
@EvictionPolicy
此外,您可以引用 Apache Geode 的 org.apache.geode.cache.util.ObjectSizer
接口的自定义实现。
它可以定义为 Spring 容器中的 bean,并使用该属性按名称引用。objectSizerName
An 允许您定义用于评估和确定存储在区域中的对象大小的标准。ObjectSizer
有关逐出配置选项的完整列表,请参阅 @EnableEviction
注释 Javadoc。
有关 Apache Geode 逐出的更多详细信息,请参阅此处。
6.12.4. 配置 Expiration
除了驱逐之外,expiration 还可用于管理内存 允许存储在区域中的条目过期。Apache Geode 支持生存时间 (TTL) 和空闲超时 (TTI) 条目过期策略。
Spring Data for Apache Geode 基于注释的过期配置基于 Spring Data for Apache Geode 版本 1.5 中添加的早期和现有的条目过期注释支持。
从本质上讲,Spring Data for Apache Geode 的过期注释支持基于 Apache Geode 的 org.apache.geode.cache.CustomExpiry
接口的自定义实现。
此实现检查存储在区域中的用户应用程序域对象
对于类型级过期注释的存在。o.a.g.cache.CustomExpiry
Spring Data for Apache Geode 提供以下过期注释:
-
Expiration
-
IdleTimeoutExpiration
-
TimeToLiveExpiration
应用程序域对象类型可以使用一个或多个过期注释进行注释,如下所示:
@Region("Books")
@TimeToLiveExpiration(timeout = 30000, action = "INVALIDATE")
class Book { .. }
要启用过期,请使用 . 注释 application 类,如下所示:@EnableExpiration
@SpringBootApplication
@PeerCacheApplication
@EnableExpiration
class ServerApplication { .. }
除了应用程序域对象类型级别的过期策略之外,您还可以直接单独配置
使用注释按区域划分的过期策略,如下所示:@EnableExpiration
@SpringBootApplication
@PeerCacheApplication
@EnableExpiration(policies = {
@ExpirationPolicy(regionNames = "Books", types = ExpirationType.TIME_TO_LIVE),
@ExpirationPolicy(regionNames = { "Customers", "Orders" }, timeout = 30000,
action = ExpirationActionType.LOCAL_DESTROY)
})
class ServerApplication { .. }
前面的示例为 、 和 Region 设置过期策略。Books
Customers
Orders
过期策略通常在服务器中的区域上设置。
有关过期配置选项的完整列表,请参阅 @EnableExpiration
注释 Javadoc。
有关 Apache Geode 过期的更多详细信息,请参阅此处。
6.12.5. 配置压缩
Apache Geode 允许您使用可插拔 Compressor
或不同的压缩编解码器来压缩内存 Region 值。
默认情况下,Apache Geode 使用 Google 的 Snappy 压缩库。
要启用压缩,请使用 . 注释 application 类,如下所示:@EnableCompression
@SpringBootApplication
@ClientCacheApplication
@EnableCompression(compressorBeanName = "MyCompressor", regionNames = { "Customers", "Orders" })
class ClientApplication { .. }
不需要 the 和 the attributes。compressorBeanName regionNames |
默认值为 ,启用 Apache Geode 的 SnappyCompressor
。compressorBeanName
SnappyCompressor
该属性是一个区域名称数组,用于指定启用了压缩的区域。
默认情况下,如果未明确设置该属性,则所有 Region 都会压缩值。regionNames
regionNames
或者,您也可以在文件中使用 and 属性
以设置和配置这些 Annotation 属性的值。spring.data.gemfire.cache.compression.compressor-bean-name spring.data.gemfire.cache.compression.region-names application.properties @EnableCompression |
要使用 Apache Geode 的区域压缩功能,您必须包含依赖项
在应用程序的文件(对于 Maven)或文件(对于 Gradle)中。仅当使用
Apache Geode 对区域压缩的默认支持,默认情况下使用 SnappyCompressor 。
当然,如果您使用其他压缩库,则需要包含该压缩库的依赖项
在应用程序的 Classpath 上。此外,您需要实现 Apache Geode 的 Compressor 接口来调整压缩
库,在 Spring 压缩器中将其定义为 Bean,并将 设置为此自定义 Bean 定义。org.iq80.snappy:snappy pom.xml build.gradle compressorBeanName |
有关更多详细信息,请参见 @EnableCompression
注释 Javadoc。
有关 Apache Geode 压缩的更多详细信息,请参阅此处。
6.12.6. 配置堆外内存
减少 JVM 堆内存压力和最小化 GC 活动的另一种有效方法是使用 Apache Geode 的堆外内存支持。
条目不是存储在 JVM 堆上,而是存储在系统的主内存中。堆外内存 通常,当存储的对象大小一致、大多小于 128K 且不需要时效果最佳 进行频繁反序列化,如 Apache Geode 用户指南中所述。
要启用堆外,请使用 . 注释 application 类,如下所示:@EnableOffHeap
@SpringBootApplication
@PeerCacheApplication
@EnableOffHeap(memorySize = 8192m regionNames = { "Customers", "Orders" })
class ServerApplication { .. }
该属性是必需的。该属性的值指定主内存量
区域可以使用兆字节 () 或千兆字节 ()。memorySize
memorySize
m
g
该属性是一个区域名称数组,用于指定在主内存中存储条目的区域。
默认情况下,如果未明确设置属性,则所有区域都使用主内存。regionNames
regionNames
或者,您可以使用文件中的 和 属性来设置
并配置这些 annotation 属性的值。spring.data.gemfire.cache.off-heap.memory-size spring.data.gemfire.cache.off-heap.region-names application.properties @EnableOffHeap |
有关更多详细信息,请参见 @EnableOffHeap
注释 Javadoc。
6.12.7. 配置磁盘存储
或者,您也可以将 Region (区域) 配置为将数据保存到磁盘。您还可以将 Region 配置为溢出
数据到磁盘。在这两种情况下,都需要 a 来持久化和/或溢出
数据。当尚未为具有持久性或溢出的区域配置显式时,
Apache Geode 使用 .DiskStore
DiskStore
DEFAULT
DiskStore
我们建议在将数据持久保存和/或溢出到磁盘时定义 Region-specific。DiskStores
Spring Data for Apache Geode 通过使用 和 注释注释应用程序类,为定义和创建应用程序区域提供注释支持。DiskStores
@EnableDiskStore
@EnableDiskStores
@EnableDiskStores 是用于聚合一个或多个注释的复合注释。@EnableDiskStore |
例如,虽然信息可能主要由来自某个外部数据源的参考数据组成
(例如 Amazon),数据很可能是事务性的,并且是应用程序
将需要保留(如果交易量足够高,甚至可能溢出到磁盘)——或者无论如何,任何图书出版商和作者都希望如此。Book
Order
使用注释,您可以定义和创建如下:@EnableDiskStore
DiskStore
DiskStore
@SpringBootApplication
@PeerCacheApplication
@EnableDiskStore(name = "OrdersDiskStore", autoCompact = true, compactionThreshold = 70,
maxOplogSize = 512, diskDirectories = @DiskDiretory(location = "/absolute/path/to/order/disk/files"))
class ServerApplication { .. }
同样,可以使用 composite, annotation 定义多个 Comments。DiskStore
@EnableDiskStores
与 Spring Data for Apache Geode 基于注释的配置模型中的其他注释一样,两者 和 都具有许多属性以及要自定义的关联配置属性
在运行时创建。@EnableDiskStore
@EnableDiskStores
DiskStores
此外,注释还定义了某些通用属性,这些属性适用于从由注释本身组成的注释创建的所有注释。
单个配置会覆盖特定的全局设置,但注解
方便地定义应用于 Annotation 聚合的所有常见配置属性。@EnableDiskStores
DiskStore
DiskStores
@EnableDiskStore
@EnableDiskStores
DiskStore
@EnableDiskStores
DiskStores
Spring Data for Apache Geode 还提供了回调接口,可以在 Java 配置中声明该接口
,而不是配置属性来自定义 at runtime,如下例所示:DiskStoreConfigurer
DiskStore
@SpringBootApplication
@PeerCacheApplication
@EnableDiskStore(name = "OrdersDiskStore", autoCompact = true, compactionThreshold = 70,
maxOplogSize = 512, diskDirectories = @DiskDiretory(location = "/absolute/path/to/order/disk/files"))
class ServerApplication {
@Bean
DiskStoreConfigurer ordersDiskStoreDiretoryConfigurer(
@Value("${orders.disk.store.location}") String location) {
return (beanName, diskStoreFactoryBean) -> {
if ("OrdersDiskStore".equals(beanName) {
diskStoreFactoryBean.setDiskDirs(Collections.singletonList(new DiskDir(location));
}
}
}
}
请参阅 @EnableDiskStore
和 @EnableDiskStores
注释
Javadoc 了解有关可用属性以及相关配置属性的更多详细信息。
有关 Apache Geode Region 持久性和溢出(使用 DiskStores)的更多详细信息,请参阅此处。
6.12.8. 配置索引
除非可以访问数据,否则在 Region 中存储数据没有多大用处。
除了操作之外,尤其是在事先知道密钥时,通常会检索数据
通过在包含数据的区域上执行查询。使用 Apache Geode 时,查询是使用
表示对象查询语言 (OQL) 和客户希望访问的特定数据集
在查询的谓词中(例如 )。Region.get(key)
SELECT * FROM /Books b WHERE b.author.name = 'Jon Doe'
通常,没有索引的查询效率低下。在没有索引的情况下执行查询时,Apache Geode 执行等效于全表扫描。
Spring Data for Apache Geode 可以轻松地在存储和访问数据的区域上创建索引。而不是显式的
像以前一样使用 Spring config 声明 bean 定义,我们可以在 Java 中创建一个 bean 定义,
如下:Index
Index
@Bean("BooksIsbnIndex")
IndexFactoryBean bookIsbnIndex(GemFireCache gemfireCache) {
IndexFactoryBean bookIsbnIndex = new IndexFactoryBean();
bookIsbnIndex.setCache(gemfireCache);
bookIsbnIndex.setName("BookIsbnIndex");
bookIsbnIndex.setExpression("isbn");
bookIsbnIndex.setFrom("/Books"));
bookIsbnIndex.setType(IndexType.KEY);
return bookIsbnIndex;
}
或者,我们可以使用 XML 创建一个 bean 定义,如下所示:Index
<gfe:index id="BooksIsbnIndex" expression="isbn" from="/Books" type="KEY"/>
但是,现在您可以直接在您知道的应用程序域对象类型的字段上定义索引 将用于查询谓词中,以加快这些查询的速度。您甚至可以为生成的 OQL 查询应用索引 从应用程序存储库接口上的用户定义的查询方法。
重用前面的示例实体类,我们可以对我们知道使用的字段进行注释
在我们使用 Interface 中的 Query Methods 定义的查询中,如下所示:Book
Book
BookRepository
@Region("Books")
class Book {
@Id
private ISBN isbn;
@Indexed
private Author author;
private Category category;
private LocalDate releaseDate;
private Publisher publisher;
@LuceneIndexed
private String title;
}
在新的类定义中,我们使用 field 和 field 进行了注释
跟。此外,该字段之前已经使用 Spring Data 的注释
,它标识包含实例唯一标识符的字段,并且在 Spring Data for Apache Geode 中,带注释的字段或属性在存储条目时用作区域中的键。Book
author
@Indexed
title
@LuceneIndexed
isbn
@Id
Book
@Id
-
@Id
带注释的字段或属性会导致创建 Apache Geode 索引。KEY
-
@Indexed
带注释的字段或属性会导致创建 Apache Geode 索引(默认)。HASH
-
@LuceneIndexed
带注释的字段或属性会导致创建 Apache Geode Lucene 索引,该索引用于 使用 Apache Geode 的 Lucene 集成和支持进行基于文本的搜索。
如果在不设置任何属性的情况下使用注释,则索引 、 、 和 派生自已添加注释的类的字段或属性。这正是字段或属性的名称。的 是从
Domain 对象的类,或者 Domain Object 类的简单名称(如果未指定 Annotation)。@Indexed
name
expression
fromClause
@Indexed
expression
fromClause
@Region
@Region
当然,您可以显式设置任何 annotation 属性以覆盖默认值
由 Spring Data for Apache Geode 提供。@Indexed
@Region("Books")
class Book {
@Id
private ISBN isbn;
@Indexed(name = "BookAuthorNameIndex", expression = "author.name", type = "FUNCTIONAL")
private Author author;
private Category category;
private LocalDate releaseDate;
private Publisher publisher;
@LuceneIndexed(name = "BookTitleIndex", destory = true)
private String title;
}
的索引(在未显式设置时自动生成)也用作 bean 的名称
在 Spring 容器中为索引注册。如有必要,甚至可以按名称注入此索引 Bean
导入到另一个应用程序组件中。name
生成的索引名称遵循以下模式:.
例如,索引的名称为 .<Region Name><Field/Property Name><Index Type>Idx
author
BooksAuthorHashIdx
要启用索引,请使用 . 注释 application 类,如下所示:@EnableIndexing
@SpringBootApplication
@PeerCacheApplication
@EnableEntityDefinedRegions
@EnableIndexing
class ServerApplication { .. }
除非还声明了 the,否则 annotation 无效。
实质上,索引是从实体类类型的字段或属性定义的,并且必须扫描实体类
检查实体的字段和属性是否存在索引注释。如果不进行此扫描,则索引注释
找不到。我们还强烈建议您限制扫描范围。@EnablingIndexing @EnableEntityDefinedRegions |
虽然 Spring Data for Apache Geode 存储库(尚)不支持 Lucene 查询,但 SDG 确实为 Apache Geode 提供了全面的支持 Lucene 使用熟悉的 Spring 模板设计模式进行查询。
最后,我们在结束本节时,使用索引时要记住一些额外的提示:
-
虽然执行 OQL 查询不需要 OQL 索引,但执行 Lucene 需要 Lucene 索引 基于文本的搜索。
-
OQL 索引不会持久化到磁盘。它们仅保留在内存中。因此,当 Apache Geode node 重启时,必须重建索引。
-
您还需要了解维护索引的相关开销,尤其是在存储索引的情况下 仅在内存中,尤其是在更新区域条目时。索引 “maintenance” 可以配置为异步任务。
在必须重建索引的情况下,重新启动 Spring 应用程序时可以使用的另一个优化 是首先预先定义所有索引,然后一次创建所有索引,这在 Spring Data for Apache Geode 中发生 刷新 Spring 容器时。
您可以预先定义索引,然后通过将属性设置为
对 .define
@EnableIndexing
true
有关更多详细信息,请参阅 Apache Geode 用户指南中的“一次创建多个索引”。
创建合理的索引是一项重要的任务,因为设计不佳的索引可能会 弊大于利。
请参阅 @Indexed
注释
和 @LuceneIndexed
注释
Javadoc 获取配置选项的完整列表。
有关 Apache Geode OQL 查询的更多详细信息,请参阅此处。
有关 Apache Geode 索引的更多详细信息,请参阅此处。
有关 Apache Geode Lucene 查询的更多详细信息,请参阅此处。
6.13. 配置连续查询
Apache Geode 的另一个非常重要和有用的功能是连续查询。
在支持 Internet 的事物的世界中,事件和数据流来自四面八方。能够处理 处理大量数据流并实时响应事件是一项越来越重要的要求 适用于许多应用。一个例子是自动驾驶汽车。能够接收、过滤、转换、分析、 和 Act on Data in Real Time 是 Real Time 应用程序的一个关键区别和特征。
幸运的是,Apache Geode 在这方面领先于时代。通过使用连续查询 (CQ), 客户端应用程序可以表达它感兴趣的数据或事件,并注册侦听器以处理和处理 事件发生时。客户端应用程序可能感兴趣的数据表示为 OQL 查询 其中,查询谓词用于筛选或识别感兴趣的数据。更改或添加数据时 并且它与已注册 CQ 的查询谓词中定义的条件匹配,则会通知客户端应用程序。
Spring Data for Apache Geode 可以轻松定义和注册 CQ,以及用于处理和处理 CQ 的关联侦听器 活动,而无需 Apache Geode 管道的所有繁琐工作。SDG 新的基于注释的配置 for CQ 基于连续查询侦听器容器中的现有连续查询支持构建。
例如,假设银行应用程序对每个客户的支票账户都感兴趣,以检测透支 withdrawls 并通过应用透支保护或通知客户来处理此事件。然后, 应用程序可能会注册以下 CQ:
ClientCache
@SpringBootApplication
@ClientCacheApplication(subcriptionEnabled = true)
@EnableContinuousQueries
class PublisherPrintApplication {
@ContinuousQuery(name = "OverdraftProtection", query = "SELECT * FROM /CheckingAccount ca WHERE ca.balance < 0.0")
void handleOverdraft(CqEvent event) {
// Quick!!! Put more money into the checking account or notify the customer of the checking account!
}
}
要启用连续查询,请使用 .@EnableContinuousQueries
定义连续查询包括对任何 Spring 注释的 POJO 类方法进行注释
使用注释(类似于 SDG 的 Function 注释 POJO 方法)。
使用注释通过 CQ 定义的 POJO 方法将在数据匹配时调用
添加或更改查询谓词。@Component
@ContinuousQuery
@ContinuousQuery
此外,POJO 方法签名应符合 ContinuousQueryListener
和 ContinuousQueryListenerAdapter
部分中概述的要求。
请参阅 @EnableContinuousQueries
和 @ContinuousQuery
注释
Javadoc 了解有关可用属性和配置设置的更多详细信息。
有关 Spring Data for Apache Geode 的连续查询支持的更多详细信息,请参阅此处。
有关 Apache Geode 连续查询的更多详细信息,请参阅此处。
6.14. 配置 Spring 的缓存抽象
借助 Spring Data for Apache Geode,Apache Geode 可以用作 Spring 缓存抽象中的缓存提供程序。
在 Spring 的缓存抽象中,缓存注释(例如 )标识缓存查找的缓存
在调用可能昂贵的操作之前执行。缓存应用程序服务方法的结果
调用操作后。@Cacheable
在 Spring Data for Apache Geode 中,Spring 直接对应于 Apache Geode 区域。区域必须在
将调用任何缓存带批注的应用程序服务方法。对于 Spring 的任何缓存 Comments 都是如此
(即 , 和 ),用于标识要在服务操作中使用的缓存。Cache
@Cacheable
@CachePut
@CacheEvict
例如,我们发布者的销售点 (PoS) 应用程序可能具有在销售交易期间确定或查找 a 的功能,如下例所示:Price
Book
@Service
class PointOfSaleService
@Cacheable("BookPrices")
Price runPriceCheckFor(Book book) {
...
}
@Transactional
Receipt checkout(Order order) {
...
}
...
}
为了在将 Spring Data for Apache Geode 与 Spring 的缓存抽象结合使用时更轻松地工作,添加了两项新功能 添加到基于 Annotation 的配置模型。
考虑以下 Spring 缓存配置:
@EnableCaching
class CachingConfiguration {
@Bean
GemfireCacheManager cacheManager(GemFireCache gemfireCache) {
GemfireCacheManager cacheManager = new GemfireCacheManager();
cacheManager.setCache(gemfireCache);
return cacheManager;
}
@Bean("BookPricesCache")
ReplicatedRegionFactoryBean<Book, Price> bookPricesRegion(GemFireCache gemfireCache) {
ReplicatedRegionFactoryBean<Book, Price> bookPricesRegion =
new ReplicatedRegionFactoryBean<>();
bookPricesRegion.setCache(gemfireCache);
bookPricesRegion.setClose(false);
bookPricesRegion.setPersistent(false);
return bookPricesRegion;
}
@Bean("PointOfSaleService")
PointOfSaleService pointOfSaleService(..) {
return new PointOfSaleService(..);
}
}
使用 Spring Data for Apache Geode 的新功能,您可以将相同的缓存配置简化为以下内容:
@EnableGemfireCaching
@EnableCachingDefinedRegions
class CachingConfiguration {
@Bean("PointOfSaleService")
PointOfSaleService pointOfSaleService(..) {
return new PointOfSaleService(..);
}
}
首先,该 Comments 替换了 Spring Comments 和需求
在 Spring 配置中声明显式 bean 定义(名为 “cacheManager”)。@EnableGemfireCaching
@EnableCaching
CacheManager
第二种是注解,如
“Configuring Regions”,检查整个 Spring 应用程序,缓存
带注释的服务组件来识别应用程序在运行时需要的所有缓存,并创建
应用程序启动时这些缓存的 Apache Geode 中的区域。@EnableCachingDefinedRegions
@EnableEntityDefinedRegions
创建的区域是创建区域的应用程序进程的本地区域。如果应用程序是对等的 ,
区域仅存在于应用程序节点上。如果应用程序是 ,则 SDG 会创建
client Regions 的 Regions 中,并期望具有相同名称的 Region 已存在于集群中的服务器上。Cache
ClientCache
PROXY
SDG 无法确定使用 Spring 的服务方法所需的缓存,以在运行时解析操作中使用的缓存。CacheResolver |
SDG 还支持在应用程序服务组件上使用 JCache (JSR-107) 缓存注释。 有关用于代替 JCache 缓存注释的等效 Spring 缓存注释,请参阅核心 Spring 框架参考指南。 |
有关更多详细信息,请参阅“对 Spring Cache Abstraction 的支持”部分 在 Spring 的缓存抽象中使用 Apache Geode 作为缓存提供程序。
有关 Spring 的 Cache Abstraction 的更多详细信息,请参见此处。
6.15. 配置集群配置推送
这可能是 Spring Data for Apache Geode 中最令人兴奋的新功能。
当客户端应用程序类使用 、 定义的任何区域或索引进行批注时
并在 Spring 容器中声明为 bean 的 bean 被客户端应用程序“推送”到服务器集群
客户端连接到的。不仅如此,这个 “推送” 的执行方式是 Apache Geode
记住使用 HTTP 时客户端推送的配置。如果集群中的所有节点都宕机,则
使用与以前相同的配置恢复。如果将新服务器添加到集群中,它将获取
相同的配置。@EnableClusterConfiguration
从某种意义上说,此功能与使用 Gfsh 手动创建区域和索引没有太大区别 在集群中的所有服务器上。不同之处在于,现在使用 Spring Data for Apache Geode,您不再需要使用 Gfsh 来创建区域 和索引。您的 Spring Boot 应用程序启用了 Spring Data for Apache Geode 的强大功能,已包含所有配置 为您创建 Regions 和 Indexes 所需的元数据。
当您使用 Spring Data Repository 抽象时,我们知道所有区域(例如由带注释的实体类定义的区域)和索引(例如由带注释的实体字段和属性定义的区域)
您的应用程序将需要。@Region
@Indexed
当您使用 Spring 的 Cache Abstraction 时,我们还知道缓存中标识的所有缓存的所有区域 应用程序的服务组件所需的注释。
从本质上讲,您已经告诉我们我们需要了解的一切,只需使用 Spring Framework 只需使用其所有 API 和功能,无论是以 Comments 元数据、Java、XML 表示 或其他方式,无论是用于配置、映射还是任何目的。
关键是,您可以在使用框架的功能和支持 基础设施(例如 Spring 的缓存抽象、Spring 数据存储库、Spring 的事务管理、 等等),而 Spring Data for Apache Geode 负责这些框架功能所需的所有 Apache Geode 管道 代表您。
将配置从客户端推送到集群中的服务器并让集群记住它是可能的
部分通过使用 Apache Geode 的 Cluster Configuration 服务。Apache Geode 的集群配置服务也是 Gfsh 用来记录的相同服务
用户发出的与 schema 相关的更改(例如 )
从 shell 到集群。gfsh> create region --name=Example --type=PARTITION
当然,由于集群可能会 “记住” 客户端从上一次运行中推送的先前配置, Spring Data for Apache Geode 会小心翼翼地避免STOMP踏服务器中已定义的任何现有区域和索引。 这一点尤其重要,例如,当 Region 已经包含数据时!
目前,没有覆盖任何现有 Region 或 Index 定义的选项。重新创建区域 或 Index 时,您必须使用 Gfsh 首先销毁 Region 或 Index,然后重新启动客户端应用程序 ,以便该配置再次被推送到服务器。或者,您可以使用 Gfsh 来(重新)定义区域 和 Indexes manually. |
与 Gfsh 不同,Spring Data for Apache Geode 仅支持从客户端在服务器上创建区域和索引。 对于高级配置和使用案例,您应该使用 Gfsh 来管理(服务器端)集群。 |
要使用此功能,您必须显式声明对
Spring、Apache Geode 应用程序的 classpath 中。org.springframework:spring-web ClientCache |
考虑以下配置中表示的功率:
ClientCache
@SpringBootApplication
@ClientCacheApplication
@EnableCachingDefinedRegions
@EnableEntityDefinedRegions
@EnableIndexing
@EnableGemfireCaching
@EnableGemfireRepositories
@EnableClusterConfiguration
class ClientApplication { .. }
您可以立即获得带有 Apache Geode 实例、Spring Data Repositories、
Spring 的缓存抽象,将 Apache Geode 作为缓存提供程序(其中区域和索引
不仅在客户端上创建,而且推送到集群中的服务器)。ClientCache
从那里,您只需执行以下操作:
-
定义应用程序的域模型对象,并使用 mapping 和 index annotations 进行注释。
-
定义存储库接口以支持针对每种实体类型的基本数据访问操作和简单查询。
-
定义包含处理实体的业务逻辑的服务组件。
-
在需要缓存、事务行为等的服务方法上声明适当的注释。
在这种情况下,与应用程序后端服务所需的基础设施和管道无关 (例如 Apache Geode)。数据库用户具有类似的功能。现在 Spring 和 Apache Geode 开发人员也这样做了。
当与以下 Spring Data for Apache Geode 注释相结合时,此应用程序真正开始起飞, 只需很少的努力:
-
@EnableContinuousQueries
-
@EnableGemfireFunctionExecutions
-
@EnableGemfireCacheTransactions
请参阅 @EnableClusterConfiguration
注释
Javadoc 了解更多详情。
6.16. 配置 SSL
对于序列化要通过网络传输的数据,在传输过程中保护数据同样重要。 当然,在 Java 中实现此目的的常用方法是使用安全套接字扩展 (SSE) 和传输层安全性 (TLS)。
要启用 SSL,请使用 . 注释您的应用程序类,如下所示:@EnableSsl
ClientCache
@SpringBootApplication
@ClientCacheApplication
@EnableSsl
public class ClientApplication { .. }
然后,您需要设置必要的 SSL 配置属性或属性:密钥库、用户名/密码等。
您可以单独配置不同的 Apache Geode 组件(、 和 )
替换为 SSL,或者您可以使用枚举值将它们集中配置为使用 SSL。GATEWAY
HTTP
JMX
LOCATOR
SERVER
CLUSTER
您可以使用
嵌套注解 (property with enumerated values from enum,
如下:@EnableSsl
components
Component
ClientCache
@SpringBootApplication
@ClientCacheApplication
@EnableSsl(components = { GATEWAY, LOCATOR, SERVER })
public class ClientApplication { .. }
此外,您还可以使用相应的 annotation 属性或关联的配置属性来指定组件级 SSL 配置(和 / 信息)。ciphers
protocols
keystore
truststore
有关更多详细信息,请参见 @EnableSsl
注释 Javadoc。
有关 Apache Geode SSL 支持的更多详细信息,请参阅此处。
6.17. 配置安全性
毫无疑问,应用程序安全性非常重要,Spring Data for Apache Geode 提供了全面的支持 用于保护 Apache Geode 客户端和服务器。
最近,Apache Geode 引入了一个新的集成安全框架 (替换其旧的 authentication and authorization 安全模型)来处理 authentication 和 authorization。 这个新的安全框架的主要功能和优势之一是它与 Apache Shiro 集成,因此可以委托身份验证和授权请求 到 Apache Shiro 来增强安全性。
本节的其余部分演示了 Spring Data for Apache Geode 如何进一步简化 Apache Geode 的安全案例。
6.17.1. 配置 Server Security
您可以通过多种不同的方式为 Apache Geode 集群中的服务器配置安全性。
-
实现 Apache Geode 接口,并使用完全限定的 类名。或者,用户可以构造并初始化其实现的实例 并在创建 Apache Geode 对等节点时使用 CacheFactory.setSecurityManager(:SecurityManager) 方法进行设置。
org.apache.geode.security.SecurityManager
security-manager
SecurityManager
SecurityManager
Cache
-
shiro.ini
创建一个包含用户、角色、 和权限,然后设置 Apache Geode 属性 引用此文件,该文件必须在 .security-shiro-init
shiro.ini
CLASSPATH
-
仅使用Apache Shiro,使用Spring Data for Apache Geode的新注释注释你的Spring Boot应用程序类,并在Spring容器中定义一个或多个Apache Shiro
领域
作为bean,以访问你的应用程序的安全元数据(即授权用户、角色、 和权限)。@EnableSecurity
第一种方法的问题在于您必须实现自己的 ,这可能非常乏味
并且容易出错。实施自定义在访问安全元数据时提供了一定的灵活性
任何存储元数据的数据源(例如 LDAP 甚至专有的 internal
数据源。但是,这个问题已经通过配置和使用 Apache Shiro 解决了,
这更广为人知,并且不是特定于 Apache Geode 的。SecurityManager
SecurityManager
Realms
第二种方法,使用 Apache Shiro INI 文件,稍微好一些,但您仍然需要熟悉 首先是 INI 文件格式。此外,INI 文件是静态的,在运行时不容易更新。
第三种方法是最理想的,因为它遵循广为人知和行业接受的概念 (即Apache Shiro的安全框架)并且易于设置,如下例所示:
@SpringBootApplication
@CacheServerApplication
@EnableSecurity
class ServerApplication {
@Bean
PropertiesRealm shiroRealm() {
PropertiesRealm propertiesRealm = new PropertiesRealm();
propertiesRealm.setResourcePath("classpath:shiro.properties");
propertiesRealm.setPermissionResolver(new GemFirePermissionResolver());
return propertiesRealm;
}
}
前面例子中显示的配置很容易是 Apache Shiro 支持的任何配置:Realm Realms |
您甚至可以创建 Apache Shiro 的自定义实现。Realm
有关更多详细信息,请参阅 Apache Shiro 的 Realms 文档。
当 Apache Shiro 位于集群中的服务器上,并且一个或多个 Apache Shiro 已定义为 Spring 容器中的 bean 时,Spring Data for Apache Geode 会检测到此配置并使用 Apache Shiro
作为安全提供程序,以便在使用注释时保护 Apache Geode 服务器。CLASSPATH
Realms
@EnableSecurity
您可以找到有关 Spring Data for Apache Geode 对 Apache Geode 新集成安全性的支持的更多信息 框架 spring.io。 |
请参阅 @EnableSecurity
注释
Javadoc 了解有关可用属性和关联配置属性的更多详细信息。
有关 Apache Geode 安全性的更多详细信息,请参阅此处。
6.17.2. 配置 Client Security
如果不讨论如何保护基于 Spring 的 Apache Geode 缓存客户端,安全故事就不完整 应用程序也是如此。
老实说,Apache Geode 保护客户端应用程序的过程相当复杂。简而言之,您需要:
-
提供
org.apache.geode.security.AuthInitialize
接口的实现。 -
设置 Apache Geode (System) 属性以引用应用程序提供的自定义界面。
security-client-auth-init
AuthInitialize
-
在专有的 Apache Geode 文件中指定用户凭证。
gfsecurity.properties
Spring Data for Apache Geode 通过使用服务器中使用的相同注释来简化所有这些步骤
应用。换句话说,相同的 Comments 同时处理 Client 端和服务器的安全性
应用。当用户决定将应用程序从嵌入式
对等应用程序进行对等处理。只需更改 SDG 注释
from 或 to ,则您已完成。@EnableSecurity
@EnableSecurity
Cache
ClientCache
@PeerCacheApplication
@CacheServerApplication
@ClientCacheApplication
实际上,您需要在客户端上做的就是:
@EnableSecurity
@SpringBootApplication
@ClientCacheApplication
@EnableSecurity
class ClientApplication { .. }
然后,您可以定义熟悉的 Spring Boot 文件,其中包含所需的用户名和密码。
如以下示例所示,并且您已设置完毕:application.properties
application.properties
spring.data.gemfire.security.username=jackBlack
spring.data.gemfire.security.password=b@cK!nB1@cK
默认情况下,Spring Boot 可以在将文件放置在
应用程序的 .当然, Spring 支持许多通过使用其Resource抽象来定位资源的方法。application.properties CLASSPATH |
请参阅 @EnableSecurity
注释
Javadoc 了解有关可用属性和关联配置属性的更多详细信息。
有关 Apache Geode 安全性的更多详细信息,请参阅此处。
6.18. 配置提示
以下提示可以帮助您充分利用新的基于 annotation 的配置模型:
6.18.1. 配置组织
正如我们在 “配置集群配置推送” 一节中看到的,
当许多 Apache Geode 或 Spring Data for Apache Geode 功能通过使用注释启用时,我们开始堆叠大量
注解。在这种情况下,这是有道理的
开始对配置进行一些划分。@Configuration
@SpringBootApplication
例如,请考虑以下声明:
ClientCache
@SpringBootApplication
@ClientCacheApplication
@EnableContinuousQueries
@EnableCachingDefinedRegions
@EnableEntityDefinedRegions
@EnableIndexing
@EnableGemfireCacheTransactions
@EnableGemfireCaching
@EnableGemfireFunctionExecutions
@EnableGemfireRepositories
@EnableClusterConfiguration
class ClientApplication { .. }
我们可以按关注点分解此配置,如下所示:
ClientCache
@SpringBootApplication
@Import({ GemFireConfiguration.class, CachingConfiguration.class,
FunctionsConfiguration.class, QueriesConfiguration.class,
RepositoriesConfiguration.class })
class ClientApplication { .. }
@ClientCacheApplication
@EnableClusterConfiguration
@EnableGemfireCacheTransactions
class GemFireConfiguration { .. }
@EnableGemfireCaching
@EnableCachingDefinedRegions
class CachingConfiguration { .. }
@EnableGemfireFunctionExecutions
class FunctionsConfiguration { .. }
@EnableContinuousQueries
class QueriesConfiguration {
@ContinuousQuery(..)
void processCqEvent(CqEvent event) {
...
}
}
@EnableEntityDefinedRegions
@EnableGemfireRepositories
@EnableIndexing
class RepositoriesConfiguration { .. }
虽然这对 Spring 框架无关紧要,但我们通常建议以可读性为目标,以便 下一个必须维护代码的人(在未来的某个时候可能是你)。
6.18.2. 其他基于配置的注解
以下 SDG 注释未在本参考文档中讨论,因为 该注释支持 Apache Geode 的已弃用功能,或者因为有更好的替代方法 完成 Annotation 提供的功能:
-
@EnableAuth
:启用 Apache Geode 的旧身份验证和授权安全模型。(已弃用。 通过使用 SDG 的注释,可以在客户端和服务器上启用 Apache Geode 的新集成安全框架,如“配置安全性”中所述。@EnableSecurity
-
@EnableAutoRegionLookup
:不推荐。本质上,此注解支持查找在 external 中定义的区域 配置元数据(例如,应用于服务器时的 Cluster Configuration)并自动 将这些 Region 注册为 Spring 容器中的 bean。此注释对应于 SDG 的 XML 命名空间中的元素。更多详情可在此处找到。用户通常应 首选 Spring 配置,当使用 Spring 和 Spring Data for Apache Geode 时。请参见配置区域 和 “Configuring Cluster Configuration Push” 来代替。cache.xml
<gfe:auto-region-lookup>
-
@EnableBeanFactoryLocator
:启用 SDG 功能,该功能仅有用 使用外部配置元数据(例如 )时。例如,如果您定义 on 中定义的 Region,您仍然可以将其与 Spring 配置中定义的关系数据库 bean 自动连接。此 Comments 利用了此 SDG 功能,如果您有大量遗留配置元数据,则可能很有用。 例如文件。GemfireBeanFactoryLocator
cache.xml
CacheLoader
cache.xml
CacheLoader
DataSource
cache.xml
-
@EnableGemFireAsLastResource
:在全局 - 使用 Apache Geode 进行 JTA 事务管理中讨论。 -
@EnableMcast
:启用 Apache Geode 的旧对等发现机制,该机制使用基于 UDP 的多播网络。 (已弃用。请改用 Apache Geode 定位器。请参见配置嵌入式定位器。 -
@EnableRegionDataAccessTracing
:用于调试目的。此注释支持对所有数据访问进行跟踪 通过注册代理所有声明为 bean 的 Region 的 AOP Aspect 对 Region 执行的操作 在 Spring 容器中,拦截 Region 操作并记录事件。
6.19. 总结
正如我们在前面的部分中所学到的,Spring Data for Apache Geode 新的基于注释的配置模型提供了巨大的 的功率。希望它能实现其目标,让您在将 Apache Geode 与 Spring 结合使用时更容易、更快速、更轻松地入门。
请记住,当您使用新注释时,您仍然可以使用 Java 配置或 XML 配置。
你甚至可以通过在 Spring 或 class 上使用 Spring 的 @Import
和 @ImportResource
注解来组合所有三种方法。您明确提供
一个 bean 定义,否则将由 Spring Data for Apache Geode 使用其中一个 Comments(基于 Comments-Based
配置后退。@Configuration
@SpringBootApplication
在某些情况下,您甚至可能需要回退到 Java 配置,就像在这种情况下,要处理
更复杂或有条件的配置逻辑,不容易表达或无法通过
单独使用注释。不要惊慌。此行为是意料之中的。 例如,需要 Java 或 XML 配置的另一种情况是配置 Apache Geode WAN 组件时,
目前没有任何 annotation 配置支持。但是,定义和注册 WAN 组件
只需要在 Spring 的 Java 配置中使用 and API 类或类(推荐)。 |
注释并非旨在处理所有情况。这些注释旨在帮助您尽可能快速、轻松地启动和运行,尤其是在开发过程中。
我们希望您会喜欢这些新功能!
6.20. 基于 Comments 的配置快速入门
以下部分概述了 SDG 注释,以便快速入门。
所有注释都提供了额外的配置属性以及关联的属性,以便在运行时方便地自定义 Apache Geode 的配置和行为。但是,一般来说, 使用特定的 Apache Geode 功能不需要任何属性或关联属性。 只需声明注释以启用该功能,即可完成。请参阅 每个注释以获取更多详细信息。 |
6.20.1. 配置应用程序ClientCache
要配置和引导 Apache Geode 应用程序,请使用以下内容:ClientCache
@SpringBootApplication
@ClientCacheApplication
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
有关更多详细信息,请参阅使用 Spring 配置 Apache Geode 应用程序。
6.20.2. 配置 Peer 应用程序Cache
要配置和引导 Apache Geode 对等应用程序,请使用以下内容:Cache
@SpringBootApplication
@PeerCacheApplication
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
}
如果要启用允许应用程序连接到此服务器的 ,
然后只需将 Annotation 替换为 Annotation。这将
在 “localhost” 上启动一个运行,侦听 的默认端口 。CacheServer ClientCache @PeerCacheApplication @CacheServerApplication CacheServer CacheServer 40404 |
有关更多详细信息,请参阅使用 Spring 配置 Apache Geode 应用程序。
6.20.3. 配置嵌入式定位器
使用 为 Spring 或 class 添加注释以开始
绑定到侦听默认 Locator 端口的所有 NIC 的嵌入式 Locator,如下所示:@PeerCacheApplication
@CacheServerApplication
@EnableLocator
10334
@SpringBootApplication
@CacheServerApplication
@EnableLocator
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
}
@EnableLocator 只能与 Apache Geode 服务器应用程序一起使用。 |
有关更多详细信息,请参阅配置嵌入式定位器。
6.20.4. 配置嵌入式管理器
使用 为 Spring 或 class 添加注释以开始
绑定到侦听默认 Manager 端口的所有 NIC 的嵌入式 Manager,如下所示:@PeerCacheApplication
@CacheServerApplication
@EnableManager
1099
@SpringBootApplication
@CacheServerApplication
@EnableManager
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
}
@EnableManager 只能与 Apache Geode 服务器应用程序一起使用。 |
有关更多详细信息,请参阅配置 Embedded Manager。
6.20.5. 配置嵌入式 HTTP 服务器
使用 为 Spring 或 class 添加注释以开始
侦听 port 的嵌入式 HTTP 服务器 (Jetty),如下所示:@PeerCacheApplication
@CacheServerApplication
@EnableHttpService
7070
@SpringBootApplication
@CacheServerApplication
@EnableHttpService
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
}
@EnableHttpService 只能与 Apache Geode 服务器应用程序一起使用。 |
有关更多详细信息,请参阅配置嵌入式 HTTP 服务器。
6.20.6. 配置嵌入式 Memcached 服务器
使用 为 Spring 或 class 添加注释以开始
侦听 port 的嵌入式 Memcached 服务器 (Gemcached),如下所示:@PeerCacheApplication
@CacheServerApplication
@EnableMemcachedServer
11211
@SpringBootApplication
@CacheServerApplication
@EnableMemcachedServer
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
}
@EnableMemcachedServer 只能与 Apache Geode 服务器应用程序一起使用。 |
6.20.7. 配置嵌入式 Redis 服务器
使用 为 Spring 或 class 添加注释以开始
嵌入式 Redis 服务器监听 port ,如下所示:@PeerCacheApplication
@CacheServerApplication
@EnableRedisServer
6379
@SpringBootApplication
@CacheServerApplication
@EnableRedisServer
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
}
@EnableRedisServer 只能与 Apache Geode 服务器应用程序一起使用。 |
您必须在 Spring [Boot] 应用程序上显式声明该模块
classpath 的org.apache.geode:geode-redis |
有关更多详细信息,请参阅配置嵌入式 Redis 服务器。
6.20.8. 配置日志记录
要配置或调整 Apache Geode 日志记录,请注释您的 Spring、Apache Geode 客户端或服务器
Application 类替换为 ,如下所示:@EnableLogging
@SpringBootApplication
@ClientCacheApplication
@EnableLogging(logLevel="trace")
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
默认值为 “config”。此外,此注解不会调整应用程序中的日志级别。
仅适用于 Apache Geode。log-level |
有关更多详细信息,请参阅 配置 Logging 。
6.20.9. 配置统计信息
要在运行时收集 Apache Geode 统计信息,请对 Spring、Apache Geode 客户端或服务器进行批注
Application 类替换为 ,如下所示:@EnableStatistics
@SpringBootApplication
@ClientCacheApplication
@EnableStatistics
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
有关更多详细信息,请参阅配置统计信息。
6.20.10. 配置 PDX
要启用 Apache Geode PDX 序列化,请注释您的 Spring、Apache Geode 客户端或服务器
Application 类替换为 ,如下所示:@EnablePdx
@SpringBootApplication
@ClientCacheApplication
@EnablePdx
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
Apache Geode PDX 序列化是 Java 序列化的替代方案,具有许多附加优势。首先,
它使所有应用程序域模型类型都可序列化,而无需实现 。java.io.Serializable |
默认情况下,SDG 将 配置为序列化您的应用程序域模型类型,
它不需要任何开箱即用的特殊配置即可正确识别应用程序域对象
需要序列化,然后执行序列化,因为 中的 logic 基于
Spring Data 的映射基础设施。有关更多详细信息,请参阅 MappingPdxSerializer。MappingPdxSerializer MappingPdxSerializer |
请参见 @EnablePdx
Javadoc。
有关更多详细信息,请参阅配置 PDX。
6.20.11. 配置 SSL
要启用 Apache Geode SSL,请注释您的 Spring、Apache Geode 客户端或服务器应用程序类
其中,如下所示:@EnableSsl
@SpringBootApplication
@ClientCacheApplication
@EnableSsl(components = SERVER)
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
至少,Apache Geode要求您使用适当的配置指定密钥库和信任库
特性或属性。密钥库和信任库配置属性或属性可能引用同一个文件。此外,您需要指定用户名和密码才能访问该文件
如果文件已得到保护。KeyStore KeyStore |
Apache Geode SSL 允许您配置需要 TLS 的系统特定组件,例如 客户端/服务器、定位器、网关等。(可选)您可以指定 Apache Geode 的所有组件 将 SSL 与 “ALL” 一起使用。 |
请参见 @EnableSsl
Javadoc。
有关更多详细信息,请参阅配置 SSL。
6.20.12. 配置安全性
要启用 Apache Geode 安全性,请注释您的 Spring、Apache Geode 客户端或服务器应用程序类
其中,如下所示:@EnableSecurity
@SpringBootApplication
@ClientCacheApplication
@EnableSecurity
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
在服务器上,您必须配置对身份验证凭证的访问。您可以实现 Apache Geode SecurityManager 接口,也可以声明
1 个或多个 Apache Shiro。有关更多详细信息,请参阅配置 Server Security。Realms |
在客户端上,您必须配置用户名和密码。有关更多详细信息,请参阅配置 Client Security。 |
有关更多详细信息,请参阅配置安全性。
6.20.13. 配置 Apache Geode 属性
要配置面向特征的 SDG 未涵盖的其他低级 Apache Geode 属性
configuration annotations,为您的 Spring、Apache Geode 客户端或服务器应用程序类添加注释
其中,如下所示:@GemFireProperties
@SpringBootApplication
@PeerCacheApplication
@EnableGemFireProperties(
cacheXmlFile = "/path/to/cache.xml",
conserveSockets = true,
groups = "GroupOne",
remoteLocators = "lunchbox[11235],mailbox[10101],skullbox[12480]"
)
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
}
某些 Apache Geode 属性仅适用于客户端,而其他属性仅适用于服务器端。请查看 Apache Geode 文档 每个属性。 |
有关更多详细信息,请参阅配置 Apache Geode 属性。
6.20.14. 配置 Caching
要在 Spring 的缓存抽象中使用 Apache Geode 作为缓存提供程序,
并让 SDG 为您的应用程序所需的缓存自动创建 Apache Geode 区域
service 组件,然后注释 Spring、Apache Geode 客户端或服务器应用程序类
其中 和 ,如下所示:@EnableGemfireCaching
@EnableCachingDefinedRegions
@SpringBootApplication
@ClientCacheApplication
@EnableCachingDefinedRegions
@EnableGemfireCaching
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
然后,只需继续定义需要缓存的应用程序服务,如下所示:
@Service
public class BookService {
@Cacheable("Books")
public Book findBy(ISBN isbn) {
...
}
}
@EnableCachingDefinedRegions 是可选的。也就是说,如果您愿意,您可以手动定义您的区域。 |
有关更多详细信息,请参见配置 Spring 的缓存抽象。
6.20.15. 为持久性应用程序配置区域、索引、存储库和实体
要简短地创建 Spring、Apache Geode 持久客户端或服务器应用程序,请对
Application 类替换为 、 和 ,如下所示:@EnableEntityDefinedRegions
@EnableGemfireRepositories
@EnableIndexing
@SpringBootApplication
@ClientCacheApplication
@EnableEntityDefinedRegions(basePackageClasses = Book.class)
@EnableGemfireRepositories(basePackageClasses = BookRepository.class)
@EnableIndexing
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
使用注释时,注释是必需的。
有关更多详细信息,请参阅 配置索引 。@EnableEntityDefinedRegions @EnableIndexing |
接下来,定义您的实体类并使用 mapping 注释指定您的实体所在的区域
将被存储。使用注释定义应用程序查询中使用的实体字段的索引,
如下:@Region
@Indexed
package example.app.model;
@Region("Books")
public class Book {
@Id
private ISBN isbn;
@Indexed;
private Author author;
@Indexed
private LocalDate published;
@LuceneIndexed
private String title;
}
实体类注释由 用于确定
应用程序所需的区域。有关更多详细信息,请参阅配置特定于类型的区域和 POJO 映射。@Region("Books") @EnableEntityDefinedRegions |
最后,使用简单的查询定义您的 CRUD 存储库 以保留和访问 ,如下所示:Books
package example.app.repo;
public interface BookRepository extends CrudRepository {
List<Book> findByAuthorOrderByPublishedDesc(Author author);
}
有关更多详细信息,请参阅 Spring Data for Apache Geode 存储库。 |
请参阅 @Region
Javadoc。
请参见 @Indexed
Javadoc。
有关更多详细信息,请参阅配置区域。
有关更多详细信息,请参阅 Spring Data for Apache Geode 存储库。
6.20.16. 从集群定义的区域配置客户端区域
或者,您可以从集群中已定义的区域定义客户端 [*PROXY] 区域
使用 ,如下所示:@EnableClusterDefinedRegions
@SpringBootApplication
@ClientCacheApplication
@EnableClusterDefinedRegions
@EnableGemfireRepositories
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
...
}
有关更多详细信息,请参阅配置的集群定义的区域。
6.20.17. 配置函数
Apache Geode 函数在分布式计算方案中非常有用,其中计算成本可能很高 可以在集群中的节点之间并行执行 require data。在这种情况下,效率更高 将 logic 带到数据所在的位置(存储),而不是请求和获取要处理的数据 通过计算。
使用 和 注释 来启用 Apache Geode 函数
定义在 POJO 上实现为方法,如下所示:@EnableGemfireFunctions
@GemfireFunction
@PeerCacheApplication
@EnableGemfireFunctions
class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
@GemfireFunction
Integer computeLoyaltyPoints(Customer customer) {
...
}
}
将 与 Function 调用注释的 1 一起使用:、、 和 。@EnableGemfireFunctionExecutions
@OnMember
@OnMembers
@OnRegion
@OnServer
@OnServers
@ClientCacheApplication
@EnableGemfireFunctionExecutions(basePackageClasses = CustomerRewardsFunction.class)
class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
@OnRegion("Customers")
interface CustomerRewardsFunctions {
Integer computeLoyaltyPoints(Customer customer);
}
有关更多详细信息,请参阅 函数执行的注释支持。
6.20.18. 配置 Continuous Query
实时事件流处理正成为数据密集型应用程序越来越重要的任务。 主要是为了及时响应用户请求。Apache Geode Continuous Query (CQ) 将帮助您轻松完成这项相当复杂的任务。
通过注释您的应用程序类并定义您的 CQ 来启用 CQ
关联的事件处理程序,如下所示:@EnableContinuousQueries
@ClientCacheApplication
@EnableContinuousQueries
class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
然后,通过使用 注释关联的处理程序方法来定义 CQ,如下所示:@ContinousQuery
@Service
class CustomerService {
@ContinuousQuery(name = "CustomerQuery", query = "SELECT * FROM /Customers c WHERE ...")
public void process(CqEvent event) {
...
}
}
每当发生事件时,更改数据以匹配连续 OQL 查询 (CQ) 中的谓词,
该方法将被调用。Customer
process
Apache Geode CQ 仅是一项客户端功能。 |
有关更多详细信息,请参阅 Continuous Query (CQ) 和 Configuring Continuous Queries。
6.20.19. 配置集群配置
使用 Apache Geode 作为 Apache Geode 应用程序开发 Spring Data 应用程序时,它是
在开发过程中,配置服务器以匹配 Client/Server 拓扑中的 Client 端非常有用。事实上
Apache Geode 期望,当您在客户端上具有 “/Example” PROXY 时,按名称进行匹配
(即 “Example”)存在于服务器中。ClientCache
Region
Region
您可以使用 Gfsh 创建应用程序所需的每个区域和索引,或者,您可以直接推送 使用 Apache Geode 开发 Spring Data 应用程序时已表示的配置元数据 当你运行它时。
这就像用 Comments 你的主应用程序类一样简单:@EnableClusterConfiguration(..)
@EnableClusterConfiguration
@ClientCacheApplication
@EnableClusterConfiguration(useHttp = true)
class ClientApplication {
...
}
大多数情况下,当使用客户端/服务器拓扑时,尤其是在生产环境中,服务器 的集群将使用 Gfsh 启动。在这种情况下,通常使用 HTTP(S) 发送配置 元数据(例如区域和索引定义)添加到集群中。使用 HTTP 时,将发送配置元数据 分配给集群中的 Manager,并一致地分布在集群中的 Server 节点之间。 |
为了使用,您必须声明依赖项
在你的 Spring 应用程序 classpath 中。@EnableClusterConfiguration org.springframework:spring-web |
有关更多详细信息,请参阅配置集群配置推送。
6.20.20. 配置GatewayReceivers
在不同 Apache Geode 集群之间复制数据是一种越来越重要的容错能力 以及高可用性 (HA) 机制。Apache Geode WAN 复制是一种允许 Apache Geode 群集,用于将其数据以可靠且具有容错能力复制到另一个 Apache Geode 群集 方式。
Apache Geode WAN 复制需要配置两个组件:
-
GatewayReceiver
- 从远程 Apache Geode 集群接收数据的 WAN 复制组件。GatewaySender
-
GatewaySender
- 将数据发送到远程 Apache Geode 集群的 WAN 复制组件。GatewayReceiver
要启用 ,需要对 application 类进行如下注释:GatewayReceiver
@EnableGatewayReceiver
@CacheServerApplication
@EnableGatewayReceiver(manualStart = false, startPort = 10000, endPort = 11000, maximumTimeBetweenPings = 1000,
socketBufferSize = 16384, bindAddress = "localhost",transportFilters = {"transportBean1", "transportBean2"},
hostnameForSenders = "hostnameLocalhost"){
...
...
}
}
class MySpringApplication { .. }
Apache Geode 仅是一项服务器端功能,只能在对等节点上配置。GatewayReceiver CacheServer Cache |
6.20.21. 配置GatewaySenders
要启用 ,需要对 application 类进行注释,如下所示:GatewaySender
@EnableGatewaySenders
@EnableGatewaySender
@CacheServerApplication
@EnableGatewaySenders(gatewaySenders = {
@EnableGatewaySender(name = "GatewaySender", manualStart = true,
remoteDistributedSystemId = 2, diskSynchronous = true, batchConflationEnabled = true,
parallel = true, persistent = false,diskStoreReference = "someDiskStore",
orderPolicy = OrderPolicyType.PARTITION, alertThreshold = 1234, batchSize = 100,
eventFilters = "SomeEventFilter", batchTimeInterval = 2000, dispatcherThreads = 22,
maximumQueueMemory = 400,socketBufferSize = 16384,
socketReadTimeout = 4000, regions = { "Region1"}),
@EnableGatewaySender(name = "GatewaySender2", manualStart = true,
remoteDistributedSystemId = 2, diskSynchronous = true, batchConflationEnabled = true,
parallel = true, persistent = false, diskStoreReference = "someDiskStore",
orderPolicy = OrderPolicyType.PARTITION, alertThreshold = 1234, batchSize = 100,
eventFilters = "SomeEventFilter", batchTimeInterval = 2000, dispatcherThreads = 22,
maximumQueueMemory = 400, socketBufferSize = 16384,socketReadTimeout = 4000,
regions = { "Region2" })
}){
class MySpringApplication { .. }
}
Apache Geode 仅是一项服务器端功能,只能在对等节点或对等节点上配置。GatewaySender CacheServer Cache |
在上面的示例中,应用程序配置了 2 个区域和 .另外
2 个将配置为为这两个区域提供服务。 将配置为复制 将配置为复制“Region2”的数据。Region1
Region2
GatewaySenders
GatewaySender1
Region1’s data and `GatewaySender2
如演示所示,可以在每个 annotation 上配置每个属性。GatewaySender
EnableGatewaySender
也可以使用更通用的 “defaulted” properties 方法,其中所有属性都配置为
注释。这样,就可以在父注释上设置一组通用的默认值
然后根据需要在 child 上覆盖,如下所示:EnableGatewaySenders
@CacheServerApplication
@EnableGatewaySenders(gatewaySenders = {
@EnableGatewaySender(name = "GatewaySender", transportFilters = "transportBean1", regions = "Region2"),
@EnableGatewaySender(name = "GatewaySender2")},
manualStart = true, remoteDistributedSystemId = 2,
diskSynchronous = false, batchConflationEnabled = true, parallel = true, persistent = true,
diskStoreReference = "someDiskStore", orderPolicy = OrderPolicyType.PARTITION, alertThreshold = 1234, batchSize = 1002,
eventFilters = "SomeEventFilter", batchTimeInterval = 2000, dispatcherThreads = 22, maximumQueueMemory = 400,
socketBufferSize = 16384, socketReadTimeout = 4000, regions = { "Region1", "Region2" },
transportFilters = { "transportBean2", "transportBean1" })
class MySpringApplication { .. }
当属性留空或未填充时,将自动附加
本身到应用程序中的每个配置。regions GatewaySender Region |
7. 使用 Apache Geode API
配置 Apache Geode 缓存和区域后,可以注入它们在应用程序对象中并使用。 本章描述了与 Spring 的事务管理功能和 DAO 异常层次结构的集成。 本章还介绍了对 Apache Geode 托管对象的依赖关系注入的支持。
7.1. GemfireTemplate
与 Spring 提供的许多其他高级抽象一样, Spring Data for Apache Geode 提供了一个模板来简化 Apache Geode 数据访问操作。该类提供了多个包含常见 Region 操作的方法,
而且还提供了针对本机 Apache Geode API 执行代码的功能,而无需处理
Apache Geode 使用 .GemfireCallback
模板类需要 Apache Geode ,并且一旦配置,就是线程安全的,并且可以重用
跨多个应用程序类:Region
<bean id="gemfireTemplate" class="org.springframework.data.gemfire.GemfireTemplate" p:region-ref="SomeRegion"/>
配置模板后,开发人员可以将其与模板一起使用,以便直接使用
Apache Geode 无需处理检查异常、线程或资源管理问题:GemfireCallback
Region
template.execute(new GemfireCallback<Iterable<String>>() {
public Iterable<String> doInGemfire(Region region)
throws GemFireCheckedException, GemFireException {
Region<String, String> localRegion = (Region<String, String>) region;
localRegion.put("1", "one");
localRegion.put("3", "three");
return localRegion.query("length < 5");
}
});
为了访问 Apache Geode 查询语言的全部功能,开发人员可以使用 and 方法,与该方法相比,这些方法可以跨多个区域执行查询、执行投影、
等等。find
findUnique
query
当查询选择多个项目 (through ) 和后者时,应使用该方法,顾名思义,当仅返回一个对象时。find
SelectResults
findUnique
7.2. 异常转换
使用新的数据访问技术不仅需要适应新的 API,还需要处理异常 特定于该技术。
为了适应异常处理情况, Spring 框架提供了一个与技术无关且一致的异常层次结构,该层次结构将应用程序从专有的(通常是“检查的”)异常抽象为一组集中的运行时 异常。
正如 Spring Framework 的文档中提到的,通过使用 Comments 和 AOP,异常转换可以透明地应用于您的数据访问对象 (DAO)
通过定义 Bean 来获取。相同的异常转换功能
在使用 Apache Geode 时启用,只要声明了 the,例如使用 a 或 声明,它充当异常转换器,并被
Spring 基础结构并相应地使用。@Repository
PersistenceExceptionTranslationPostProcessor
CacheFactoryBean
<gfe:cache/>
<gfe:client-cache>
7.3. 本地,缓存事务管理
Spring Framework 最流行的功能之一是事务管理。
如果你不熟悉 Spring 的事务抽象,那么我们强烈建议你阅读 Spring 的事务管理基础设施,因为它提供了一个一致的编程模型 在多个 API 之间透明地进行配置,并且可以通过编程方式或声明方式进行配置 (最受欢迎的选择)。
对于 Apache Geode,Spring Data for Apache Geode 提供了一个专用的、每个缓存,一旦声明,
允许通过 Spring 以原子方式执行 Region 操作:PlatformTransactionManager
<gfe:transaction-manager id="txManager" cache-ref="myCache"/>
上面的示例可以通过删除 Apache Geode
cache 在默认名称 下定义。与其他 Spring Data for Apache Geode 命名空间元素一样,如果缓存
bean name 未配置,则将使用上述命名约定。此外,事务管理器
name 为 “gemfireTransactionManager” (如果未明确指定)。cache-ref gemfireCache |
目前,Apache Geode 支持具有读取提交隔离的乐观事务。此外,为了保证
这种隔离,开发人员应避免进行手动修改缓存中存在的值的就地更改。
为了防止这种情况发生,事务管理器将缓存配置为默认使用 copy on read 语义。
这意味着每次执行读取时都会创建实际值的克隆。如果需要,可以禁用此行为
通过财产。copyOnRead
由于在启用读取时复制给定键的值时会复制给定键的值,因此您必须随后调用 inorder 以事务方式更新该值。Region.put(key, value)
有关基础 Geode 事务管理器的语义和行为的更多信息,请参阅 Geode CacheTransactionManager Javadoc 以及文档。
7.4. 全局、JTA 事务管理
Apache Geode 还可以参与基于 JTA 的全局事务,例如事务 由 Java EE Application Server(例如 WebSphere Application Server (WAS))使用容器管理事务 (CMT) 以及其他 JTA 资源。
但是,与许多其他 JTA“兼容”资源(例如 ActiveMQ 等 JMS 消息代理)不同,Apache Geode 不是 XA 兼容资源。因此,Apache Geode 必须定位为 JTA 事务中的“最后一个资源” (准备阶段),因为它不实现两阶段提交协议,或者更确切地说不处理分布式 交易。
许多支持 CMT 的托管环境在基于 JTA 的环境中保持对“Last Resource”、非 XA 兼容资源的支持 transactions 的 API,尽管它在 JTA 规范中实际上并不是必需的。有关非 XA 合规性的更多信息, “Last Resource” 是指可以在 Red Hat 的文档中找到。 事实上,Red Hat 的 JBoss 项目 Narayana 就是这样一个 LGPL 开源实现。Narayana 将此称为 “Last Resource Commit Optimization” (LRCO)。更多详情可在此处找到。
但是,无论您是在具有开源 JTA 事务的独立环境中使用 Apache Geode 支持“Last Resource”的管理实现,或托管环境(例如 Java EE AS,如 WAS), Spring Data for Apache Geode 可以满足您的需求。
要正确使用 Apache Geode 作为 JTA 中的“最后一个资源”,您必须完成一系列步骤 涉及多个事务资源的事务。此外,只能有 1 个不符合 XA 标准的资源 (例如 Apache Geode)以这种方式进行。
1) 首先,您必须在此处完成 Apache Geode 文档中的步骤 1-4。
上面的 #1 独立于您的 Spring [Boot] 和/或 [Data for Apache Geode] 应用程序,并且必须是 成功完成。 |
2) 参考 Apache Geode 文档中的步骤 5,
Spring Data for Apache Geode 的 Annotation 支持将在使用 Comments 时尝试为您设置 , copyOnRead
属性。GemFireCache
@EnableGemFireAsLastResource
但是,如果 SDG 的自动配置在这方面不成功,则必须在 or XML 元素中显式设置属性或设置
将 JavaConfig 中的类设置为 true。例如:copy-on-read
<gfe:cache>
<gfe:client-cache>
copyOnRead
CacheFactoryBean
ClientCache
XML:
<gfe:client-cache ... copy-on-read="true"/>
ClientCache
JavaConfig 的
@Bean
ClientCacheFactoryBean gemfireCache() {
ClientCacheFactoryBean gemfireCache = new ClientCacheFactoryBean();
gemfireCache.setCopyOnRead(true);
return gemfireCache;
}
对等 XML:Cache
<gfe:cache ... copy-on-read="true"/>
对等 JavaConfig:Cache
@Bean
CacheFactoryBean gemfireCache() {
CacheFactoryBean gemfireCache = new CacheFactoryBean();
gemfireCache.setCopyOnRead(true);
return gemfireCache;
}
显式设置特性或属性确实没有必要。使
事务管理采用读取时复制的情况。copy-on-read copyOnRead |
3) 此时,您可以跳过 Apache Geode 文档中的步骤 6-8,让 Spring Data Geode 发挥其魔力。您需要做的就是对 Spring 类进行注释
使用 Spring Data for Apache Geode 的新注释以及 Spring 的事务管理基础结构和 Spring Data for Apache Geode 的注释配置的组合,可以解决问题。@Configuration
@EnableGemFireAsLastResource
@EnableGemFireAsLastResource
配置如下所示...
@Configuration
@EnableGemFireAsLastResource
@EnableTransactionManagement(order = 1)
class GeodeConfiguration {
...
}
唯一的要求是......
3.1) 注解必须在同一个 Spring 类上声明
其中还指定了 Spring 的 Comments。@EnableGemFireAsLastResource
@Configuration
@EnableTransactionManagement
3.2) 注解的属性必须显式设置为整数值
即不是 or(默认为 )。order
@EnableTransactionManagement
Integer.MAX_VALUE
Integer.MIN_VALUE
Integer.MAX_VALUE
当然,希望您知道在使用 JTA 事务时也需要配置 Spring,例如..JtaTransactionManager
@Bean
public JtaTransactionManager transactionManager(UserTransaction userTransaction) {
JtaTransactionManager transactionManager = new JtaTransactionManager();
transactionManager.setUserTransaction(userTransaction);
return transactionManager;
}
本地、缓存事务管理部分中的配置在此处不适用。
使用 Spring Data for Apache Geode 适用于“仅本地”的缓存事务,而不是“全局”的 JTA 事务。因此,在这种情况下,您不需要配置 SDG。
您可以按照上面所示配置 Spring。GemfireTransactionManager GemfireTransactionManager JtaTransactionManager |
有关将 Spring 的事务管理与 JTA 结合使用的更多详细信息, 请看这里。
实际上,Spring Data for Apache Geode 的注释导入包含 2 个 Aspect 的配置
在事务操作期间的适当点处理 Apache Geode 和操作的 bean 定义。@EnableGemFireAsLastResource
o.a.g.ra.GFConnectionFactory.getConnection()
o.a.g.ra.GFConnection.close()
具体而言,正确的事件顺序如下:
-
jtaTransation.begin()
-
GFConnectionFactory.getConnection()
-
调用应用程序的 service 方法
@Transactional
-
或
jtaTransaction.commit()
jtaTransaction.rollback()
-
最后
GFConnection.close()
这与作为应用程序开发人员的手动编码方式(如果您必须使用 JTA API)是一致的 + Apache Geode API,如 Apache Geode 示例。
值得庆幸的是, Spring 为您完成了繁重的工作,并且在应用适当的配置后您需要做的所有事情 (如上所示)是:
@Service
class MyTransactionalService {
@Transactional
public <Return-Type> someTransactionalServiceMethod() {
// perform business logic interacting with and accessing multiple JTA resources atomically
}
...
}
一旦你的应用程序输入了边界(即当 被调用时,Spring的JTA会为你适当地处理上述#1和#4。PlatformTransactionManager
@Transactional
MyTransactionService.someTransactionalServiceMethod()
#2 & #3由Spring Data for Apache Geode的新方面处理,并启用了注释。@EnableGemFireAsLastResource
#3 当然是您的应用程序的责任。
事实上,通过配置适当的日志记录,您将看到正确的事件序列......
2017-Jun-22 11:11:37 TRACE TransactionInterceptor - Getting transaction for [example.app.service.MessageService.send]
2017-Jun-22 11:11:37 TRACE GemFireAsLastResourceConnectionAcquiringAspect - Acquiring {data-store-name} Connection
from {data-store-name} JCA ResourceAdapter registered at [gfe/jca]
2017-Jun-22 11:11:37 TRACE MessageService - PRODUCER [ Message :
[{ @type = example.app.domain.Message, id= MSG0000000000, message = SENT }],
JSON : [{"id":"MSG0000000000","message":"SENT"}] ]
2017-Jun-22 11:11:37 TRACE TransactionInterceptor - Completing transaction for [example.app.service.MessageService.send]
2017-Jun-22 11:11:37 TRACE GemFireAsLastResourceConnectionClosingAspect - Closed {data-store-name} Connection @ [Reference [...]]
有关使用 Apache Geode 缓存级事务的更多详细信息,请参阅此处。
有关在 JTA 事务中使用 Apache Geode 的更多详细信息, 请看这里。
有关将 Apache Geode 配置为 “Last Resource” 的更多详细信息, 请看这里。
7.5. 使用 @TransactionalEventListener
使用事务时,可能需要注册一个侦听器以在 事务提交,或在发生回滚后。
Spring Data for Apache Geode 可以轻松创建侦听器,这些侦听器将在事务的特定阶段使用注释调用。注释 (如下所示) 的方法将是
在指定的 .@TransactionalEventListener
@TransactionalEventListener
phase
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handleAfterCommit(MyEvent event) {
// do something after transaction is committed
}
为了调用上述方法,您必须从事务中发布一个事件,如下所示:
@Service
class MyTransactionalService {
@Autowired
private final ApplicationEventPublisher applicationEventPublisher;
@Transactional
public <Return-Type> someTransactionalServiceMethod() {
// Perform business logic interacting with and accessing multiple transactional resources atomically, then...
applicationEventPublisher.publishEvent(new MyApplicationEvent(...));
}
...
}
该注解允许您指定事件处理程序
方法。选项包括: 、 、 和 。
如果未指定,则默认为 .如果你希望在没有事务的情况下也能调用 listener
存在,则可以设置为 。@TransactionalEventListener
phase
AFTER_COMMIT
AFTER_COMPLETION
AFTER_ROLLBACK
BEFORE_COMMIT
phase
AFTER_COMMIT
fallbackExecution
true
7.6. 自动交易事件发布
从 Spring Data for Apache Geode 开始,现在可以启用自动事务事件发布。Neumann/2.3
使用注解,设置属性
设置为 true。默认值为 false。@EnableGemfireCacheTransactions
enableAutoTransactionEventPublishing
@EnableGemfireCacheTransactions(enableAutoTransactionEventPublishing = true)
class GeodeConfiguration { ... }
然后,您可以创建带注释的 POJO 方法来处理
或 交易 阶段。@TransactionalEventListener
AFTER_COMMIT
AFTER_ROLLBACK
@Component
class TransactionEventListeners {
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handleAfterCommit(TransactionApplicationEvent event) {
...
}
@TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
public void handleAfterRollback(TransactionApplicationEvent event) {
...
}
}
仅限 和 受支持。 不受支持,因为 1) SDG 调整 Apache Geode 和接口以实现自动事务事件发布,以及 2) 调用 Apache Geode 时,在事务生命周期中调用带注释的 POJO 方法时,已经在调用之后调用了带注释的 POJO 方法。TransactionPhase.AFTER_COMMIT TransactionPhase.AFTER_ROLLBACK TransactionPhase.BEFORE_COMMIT TransactionListener TransactionWriter TransactionWriter.beforeCommit(:TransactionEvent) AbstractPlatformTransactionManager.triggerBeforeCommit(:TransactionStatus) @TranactionalEventListener |
使用自动事务事件发布,您无需在应用程序方法中显式调用该方法。applicationEventPublisher.publishEvent(..)
@Transactional
@Service
但是,如果您仍希望“在提交之前”接收事务事件,则仍必须在应用程序方法中调用该方法。
有关更多详细信息,请参阅上面的注释。applicationEventPublisher.publishEvent(..)
@Transactional
@Service
7.7. 连续查询 (CQ)
Apache Geode 提供的一项强大功能是 Continuous Query(或 CQ)。
简而言之,CQ 允许开发人员创建并注册 OQL 查询,然后在出现新数据时自动收到通知
)匹配查询谓词。Spring Data for Apache Geode 提供专用的
通过包及其侦听器容器支持 CQ;
在功能和命名上与 Spring Framework 中的 JMS 集成非常相似;事实上,熟悉
Spring 中的 JMS 支持应该让人感觉很舒服。org.springframework.data.gemfire.listener
基本上,Spring Data for Apache Geode 允许 POJO 上的方法成为 CQ 的端点。只需定义查询 并指示在匹配时应调用以通知的方法。Spring Data for Apache Geode 负责 其余的。这与 Java EE 的消息驱动 bean 样式非常相似,但对基类没有任何要求 或基于 Apache Geode 的接口实现。
目前,仅在 Apache Geode 的客户端/服务器拓扑中支持连续查询。此外,客户端池 used 是启用订阅所必需的。有关更多信息,请参阅 Apache Geode 文档。 |
7.7.1. Continuous Query Listener 容器
Spring Data for Apache Geode 通过处理 CQ 事件来简化 CQ 事件的创建、注册、生命周期和分派
使用 SDG 围绕 CQ 的基础设施,它完成了所有繁重的工作
代表用户。熟悉 EJB 和 JMS 的用户应该会发现这些概念在设计时很熟悉
尽可能接近 Spring Framework 及其消息驱动 POJO (MDP) 提供的支持。ContinuousQueryListenerContainer
SDG 充当事件(或消息)侦听器容器;它用于
从已注册的 CQ 接收事件,并调用注入其中的 POJO。侦听器容器
负责将消息接收和 dispatch 的所有线程处理到侦听器中进行处理。它的作用是
EDP(事件驱动型 POJO)和事件提供者之间的中介,负责创建和注册
CQ(接收事件)、资源获取和发布、异常转换等。这样,您就可以
作为应用程序开发人员,编写与接收事件相关的(可能很复杂的)业务逻辑
(并对此做出反应),并将样板 Apache Geode 基础架构问题委托给框架。ContinuousQueryListenerContainer
侦听器容器是完全可定制的。开发人员可以选择使用 CQ 线程执行调度
(同步交付)或新线程(来自现有池)通过定义合适的(或 Spring的)来异步方法。根据负载,侦听器的数量
或运行时环境,开发人员应该更改或调整 executor 以更好地满足她的需求。特别
在托管环境(例如应用程序服务器)中,强烈建议选择合适的环境以利用其运行时。java.util.concurrent.Executor
TaskExecutor
TaskExecutor
7.7.2. 和ContinuousQueryListener
ContinuousQueryListenerAdapter
该类是 Spring Data for Apache Geode CQ 支持中的最后一个组件。简而言之
class 允许您将几乎任何实现类公开为 EDP,并且约束最小。 实现接口,一个简单的侦听器接口
类似于 Apache Geode 的 CqListener。ContinuousQueryListenerAdapter
ContinuousQueryListenerAdapter
ContinuousQueryListener
请考虑以下接口定义。请注意各种事件处理方法及其参数:
public interface EventDelegate {
void handleEvent(CqEvent event);
void handleEvent(Operation baseOp);
void handleEvent(Object key);
void handleEvent(Object key, Object newValue);
void handleEvent(Throwable throwable);
void handleQuery(CqQuery cq);
void handleEvent(CqEvent event, Operation baseOp, byte[] deltaValue);
void handleEvent(CqEvent event, Operation baseOp, Operation queryOp, Object key, Object newValue);
}
package example;
class DefaultEventDelegate implements EventDelegate {
// implementation elided for clarity...
}
特别是,请注意上述接口的实现根本没有 Apache Geode 依赖项。
它确实是一个 POJO,我们可以并且将通过以下配置将其制作成 EDP。EventDelegate
该类不必实现接口;接口仅用于更好地展示解耦 在 Contract 和 implementation 之间。 |
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:gfe="https://www.springframework.org/schema/geode"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/geode https://www.springframework.org/schema/geode/spring-geode.xsd
">
<gfe:client-cache/>
<gfe:pool subscription-enabled="true">
<gfe:server host="localhost" port="40404"/>
</gfe:pool>
<gfe:cq-listener-container>
<!-- default handle method -->
<gfe:listener ref="listener" query="SELECT * FROM /SomeRegion"/>
<gfe:listener ref="another-listener" query="SELECT * FROM /AnotherRegion" name="myQuery" method="handleQuery"/>
</gfe:cq-listener-container>
<bean id="listener" class="example.DefaultMessageDelegate"/>
<bean id="another-listener" class="example.DefaultMessageDelegate"/>
...
<beans>
上面的示例显示了侦听器可以具有的各种形式中的一些;至少会是侦听器
reference 和 actual query definition 是必需的。但是,可以指定
生成的 Continuous Query(用于监视),以及方法的名称(默认值为 )。
指定方法可以具有各种参数类型,接口列出了允许的类型。handleEvent EventDelegate |
上面的示例使用 Spring Data for Apache Geode 命名空间来声明事件侦听器容器 并自动注册侦听器。完整的 bean 定义如下所示:
<!-- this is the Event Driven POJO (MDP) -->
<bean id="eventListener" class="org.springframework.data.gemfire.listener.adapter.ContinuousQueryListenerAdapter">
<constructor-arg>
<bean class="gemfireexample.DefaultEventDelegate"/>
</constructor-arg>
</bean>
<!-- and this is the event listener container... -->
<bean id="gemfireListenerContainer" class="org.springframework.data.gemfire.listener.ContinuousQueryListenerContainer">
<property name="cache" ref="gemfireCache"/>
<property name="queryListeners">
<!-- set of CQ listeners -->
<set>
<bean class="org.springframework.data.gemfire.listener.ContinuousQueryDefinition" >
<constructor-arg value="SELECT * FROM /SomeRegion" />
<constructor-arg ref="eventListener"/>
</bean>
</set>
</property>
</bean>
每次收到事件时,适配器都会在 Apache Geode 事件之间自动执行类型转换 和所需的方法参数。捕获由方法调用引起的任何异常 并由容器处理(默认情况下,被记录)。
7.8. 接线组件Declarable
Apache Geode XML 配置(通常称为 )允许声明用户对象
作为配置的一部分。通常这些对象是或其他可插拔的回调组件
由 Apache Geode 支持。使用本机 Apache Geode 配置,通过 XML 声明的每个用户类型都必须实现
接口,它允许将任意参数传递给声明的类
通过实例。cache.xml
CacheLoaders
Declarable
Properties
在本节中,我们将介绍如何配置这些在 using Spring 中定义的可插拔组件,同时保持 中定义的 Cache/Region 配置。这允许您的
可插拔组件,以专注于应用程序逻辑,而不是 或其他协作者的位置或创建。cache.xml
cache.xml
DataSources
但是,如果要启动一个 green field 项目,建议您配置 Cache、Region、
和其他可插拔的 Apache Geode 组件。这避免了从接口继承
或本节中介绍的基类。Declarable
有关此方法的更多信息,请参阅以下侧栏。
作为使用 Spring 配置组件的示例,请考虑以下声明
(摘自 Javadoc):Declarable
Declarable
<cache-loader>
<class-name>com.company.app.DBLoader</class-name>
<parameter name="URL">
<string>jdbc://12.34.56.78/mydb</string>
</parameter>
</cache-loader>
为了简化解析、转换参数和初始化对象的任务,Spring Data for Apache Geode 提供了
一个基类 (),它允许通过模板 Bean 定义连接 Apache Geode 用户对象
或者,如果缺少它,请通过 Spring IoC 容器执行自动连接。要利用此功能,
用户对象需要扩展 ,它会自动定位声明并在初始化过程中执行连接。WiringDeclarableSupport
WiringDeclarableSupport
BeanFactory
7.8.1. 使用模板 bean 定义进行配置
使用时,尝试首先找到现有的 bean 定义并使用它
作为布线模板。除非指定,否则组件类名将用作隐式 bean 定义名。WiringDeclarableSupport
让我们看看我们的声明在这种情况下会是什么样子:DBLoader
class DBLoader extends WiringDeclarableSupport implements CacheLoader {
private DataSource dataSource;
public void setDataSource(DataSource dataSource){
this.dataSource = dataSource;
}
public Object load(LoaderHelper helper) { ... }
}
<cache-loader>
<class-name>com.company.app.DBLoader</class-name>
<!-- no parameter is passed (use the bean's implicit name, which is the class name) -->
</cache-loader>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
">
<bean id="dataSource" ... />
<!-- template bean definition -->
<bean id="com.company.app.DBLoader" abstract="true" p:dataSource-ref="dataSource"/>
</beans>
在上面的场景中,由于没有指定参数,因此使用了 id/name 为
作为连接 Apache Geode 创建的实例的模板。对于 Bean 名称使用不同约定的情况,
可以在 Apache Geode 配置中传入参数:com.company.app.DBLoader
bean-name
<cache-loader>
<class-name>com.company.app.DBLoader</class-name>
<!-- pass the bean definition template name as parameter -->
<parameter name="bean-name">
<string>template-bean</string>
</parameter>
</cache-loader>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
">
<bean id="dataSource" ... />
<!-- template bean definition -->
<bean id="template-bean" abstract="true" p:dataSource-ref="dataSource"/>
</beans>
模板 Bean 定义不必在 XML 中声明。 允许任何格式(Groovy、注释等)。 |
7.8.2. 使用自动装配和注解进行配置
默认情况下,如果未找到 bean 定义,则将自动装配声明的实例。这意味着,除非实例提供了任何依赖项注入元数据,否则
容器将找到 Object Setter 并尝试自动满足这些依赖项。
但是,开发人员也可以使用 JDK 5 注释为自动装配过程提供其他信息。WiringDeclarableSupport
我们强烈建议您阅读 Spring 文档中的专门章节,以了解有关支持的 Comments 和启用因素的更多信息。 |
例如,可以通过以下方式注入 Spring 配置的上述假设声明:DBLoader
DataSource
class DBLoader extends WiringDeclarableSupport implements CacheLoader {
// use annotations to 'mark' the needed dependencies
@javax.inject.Inject
private DataSource dataSource;
public Object load(LoaderHelper helper) { ... }
}
<cache-loader>
<class-name>com.company.app.DBLoader</class-name>
<!-- no need to declare any parameters since the class is auto-wired -->
</cache-loader>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
">
<!-- enable annotation processing -->
<context:annotation-config/>
</beans>
通过使用 JSR-330 注释,自定位和创建以来,代码已得到简化
的已外部化,用户代码仅与加载过程有关。
可能是事务性的、延迟创建的、在多个对象之间共享的或从 JNDI 检索的。
这些方面可以通过 Spring 容器轻松配置和更改,而无需接触
代码。CacheLoader
DataSource
DataSource
DBLoader
7.9. 支持 Spring 缓存抽象
Spring Data for Apache Geode 提供了 Spring 缓存抽象的实现,以将 Apache Geode 定位为 Spring 缓存基础架构中的缓存提供程序。
要使用 Apache Geode 作为后备实现,即 Spring 缓存抽象中的“缓存提供程序”,
只需添加到您的配置中:GemfireCacheManager
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:gfe="https://www.springframework.org/schema/geode"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache https://www.springframework.org/schema/cache/spring-cache.xsd
https://www.springframework.org/schema/geode https://www.springframework.org/schema/geode/spring-geode.xsd
">
<!-- enable declarative caching -->
<cache:annotation-driven/>
<gfe:cache id="gemfire-cache"/>
<!-- declare GemfireCacheManager; must have a bean ID of 'cacheManager' -->
<bean id="cacheManager" class="org.springframework.data.gemfire.cache.GemfireCacheManager"
p:cache-ref="gemfire-cache">
</beans>
如果默认缓存 Bean 名称
(即 “gemfireCache”),即 没有显式 ID。cache-ref CacheManager <gfe:cache> |
当声明 (Singleton) bean 实例并启用声明式缓存时
(在带有 Spring 注解的 XML 中或在 JavaConfig 中),
Spring 缓存注释(例如)标识将在内存中缓存数据的“缓存”
使用 Apache Geode 区域。GemfireCacheManager
<cache:annotation-driven/>
@EnableCaching
@Cacheable
这些缓存(即 Region)必须存在于使用它们的缓存注释之前,否则将发生错误。
举例来说,假设您有一个 Customer Service 应用程序,其中包含一个应用程序组件
执行缓存...CustomerService
@Service
class CustomerService {
@Cacheable(cacheNames="Accounts", key="#customer.id")
Account createAccount(Customer customer) {
...
}
然后,您将需要以下配置。
XML:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:gfe="https://www.springframework.org/schema/geode"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache https://www.springframework.org/schema/cache/spring-cache.xsd
https://www.springframework.org/schema/geode https://www.springframework.org/schema/geode/spring-geode.xsd
">
<!-- enable declarative caching -->
<cache:annotation-driven/>
<bean id="cacheManager" class="org.springframework.data.gemfire.cache.GemfireCacheManager">
<gfe:cache/>
<gfe:partitioned-region id="accountsRegion" name="Accounts" persistent="true" ...>
...
</gfe:partitioned-region>
</beans>
JavaConfig 的
@Configuration
@EnableCaching
class ApplicationConfiguration {
@Bean
CacheFactoryBean gemfireCache() {
return new CacheFactoryBean();
}
@Bean
GemfireCacheManager cacheManager() {
GemfireCacheManager cacheManager = GemfireCacheManager();
cacheManager.setCache(gemfireCache());
return cacheManager;
}
@Bean("Accounts")
PartitionedRegionFactoryBean accountsRegion() {
PartitionedRegionFactoryBean accounts = new PartitionedRegionFactoryBean();
accounts.setCache(gemfireCache());
accounts.setClose(false);
accounts.setPersistent(true);
return accounts;
}
}
当然,您可以自由选择您喜欢的任何区域类型(例如 REPLICATE、PARTITION、LOCAL 等)。
有关 Spring 的 Cache Abstraction 的更多详细信息,请参阅文档。
8. 使用 Apache Geode 序列化
为了提高 Apache Geode 内存数据网格的整体性能,Apache Geode 支持专用的 序列化协议,称为 PDX,与标准 Java 序列化相比,它更快,提供更紧凑的结果 除了跨各种语言平台(Java、C++ 和 .NET)透明地工作之外。
有关更多详细信息,请参阅 PDX 序列化功能和 PDX 序列化内部。
本章讨论 Spring Data for Apache Geode 简化和改进 Apache Geode 的 Java 中的自定义序列化。
8.1. 连接反序列化实例
序列化对象具有瞬态数据是相当常见的。瞬态数据通常取决于系统
或它在某个时间点生活的环境。例如,a 特定于环境。
序列化此类信息毫无用处,甚至可能很危险,因为它是某个 VM 或计算机的本地信息。
对于这种情况, Spring Data for Apache Geode 提供了一个特殊的实例化器
,该实例化器在反序列化期间为 Apache Geode 创建的每个新实例执行连接。DataSource
通过这样的机制,你可以依靠 Spring 容器来注入和管理某些依赖项,这很容易 将 transient 与持久化数据分开,并以透明的方式拥有丰富的 domain 对象。
Spring 用户可能会发现这种方法类似于 @Configurable
)。
其工作方式类似于 ,尝试首先找到 bean 定义
作为配线模板,否则回退到自动配线。WiringInstantiator
WiringDeclarableSupport
有关连接功能的更多详细信息,请参阅上一节 (连接可声明
组件) 。
要使用 SDG ,请将其声明为 bean,如下例所示:Instantiator
<bean id="instantiator" class="org.springframework.data.gemfire.serialization.WiringInstantiator">
<!-- DataSerializable type -->
<constructor-arg>org.pkg.SomeDataSerializableClass</constructor-arg>
<!-- type id -->
<constructor-arg>95</constructor-arg>
</bean>
在 Spring 容器启动期间,一旦初始化,默认情况下,它会将自身注册到
Apache Geode 序列化系统,并在创建的所有实例上执行连接
由 Apache Geode 在反序列化期间提供。Instantiator
SomeDataSerializableClass
8.2. 自动生成自定义Instantiators
对于数据密集型应用程序,随着数据流入,可能会在每台计算机上创建大量实例。
Apache Geode 使用反射来创建新类型,但在某些情况下,这可能会证明成本很高。
与往常一样,最好执行分析来量化是否是这种情况。对于此类情况,Spring Data for Apache Geode
允许自动生成类,这些类实例化新类型(使用默认构造函数)
不使用反射。下面的示例演示如何创建实例化器:Instatiator
<bean id="instantiatorFactory" class="org.springframework.data.gemfire.serialization.InstantiatorFactoryBean">
<property name="customTypes">
<map>
<entry key="org.pkg.CustomTypeA" value="1025"/>
<entry key="org.pkg.CustomTypeB" value="1026"/>
</map>
</property>
</bean>
前面的定义会自动为两个类 ( 和 ) 生成 2 个
并在用户 ID 和 下向 Apache Geode 注册它们。两者避免使用
反射并直接通过 Java 代码创建实例。Instantiators
CustomTypeA
CustomTypeB
1025
1026
Instantiators
9. POJO 映射
本节涵盖:
9.1. 对象映射基础知识
本节介绍了 Spring Data 对象映射、对象创建、字段和属性访问、可变性和不可变性的基础知识。 请注意,本节仅适用于不使用底层数据存储(如 JPA)的对象映射的 Spring Data 模块。 此外,请务必查阅特定于 store 的部分,了解特定于 store 的对象映射,例如索引、自定义列或字段名称等。
Spring Data 对象映射的核心职责是创建域对象的实例并将存储原生数据结构映射到这些实例上。 这意味着我们需要两个基本步骤:
-
使用公开的构造函数之一创建实例。
-
实例填充 实现所有公开的属性。
9.1.1. 对象创建
Spring Data 会自动尝试检测用于具体化该类型对象的持久实体的构造函数。 解析算法的工作原理如下:
-
如果有一个 Comments 的 static factory 方法,则使用它。
@PersistenceCreator
-
如果只有一个构造函数,则使用它。
-
如果有多个构造函数,并且只有一个构造函数被注释为 ,则使用它。
@PersistenceCreator
-
如果存在无参数构造函数,则使用它。 其他构造函数将被忽略。
值解析假定构造函数/工厂方法参数名称与实体的属性名称匹配,即解析将像要填充属性一样执行,包括映射中的所有自定义(不同的数据存储列或字段名称等)。
这还需要类文件中可用的参数名称信息或构造函数上存在的 Comments。@ConstructorProperties
可以通过使用特定于存储的 SPEL 表达式使用 Spring Framework 的值注释来自定义值解析。
有关更多详细信息,请参阅特定于 store 的映射部分。@Value
9.1.2. 属性人口
创建实体的实例后, Spring Data 将填充该类的所有剩余持久属性。 除非已由实体的构造函数填充(即通过其构造函数参数列表使用),否则将首先填充 identifier 属性以允许解析循环对象引用。 之后,将在实体实例上设置尚未由构造函数填充的所有非临时属性。 为此,我们使用以下算法:
-
如果属性是不可变的,但公开了一个方法(见下文),我们使用该方法创建具有新属性值的新实体实例。
with…
with…
-
如果定义了属性访问(即通过 getter 和 setter 进行访问),我们将调用 setter 方法。
-
如果属性是可变的,我们直接设置字段。
-
如果属性是不可变的,我们将使用持久性操作(请参阅对象创建)使用的构造函数来创建实例的副本。
-
默认情况下,我们直接设置 field 值。
让我们看看以下实体:
class Person {
private final @Id Long id; (1)
private final String firstname, lastname; (2)
private final LocalDate birthday;
private final int age; (3)
private String comment; (4)
private @AccessType(Type.PROPERTY) String remarks; (5)
static Person of(String firstname, String lastname, LocalDate birthday) { (6)
return new Person(null, firstname, lastname, birthday,
Period.between(birthday, LocalDate.now()).getYears());
}
Person(Long id, String firstname, String lastname, LocalDate birthday, int age) { (6)
this.id = id;
this.firstname = firstname;
this.lastname = lastname;
this.birthday = birthday;
this.age = age;
}
Person withId(Long id) { (1)
return new Person(id, this.firstname, this.lastname, this.birthday, this.age);
}
void setRemarks(String remarks) { (5)
this.remarks = remarks;
}
}
1 | identifier 属性是 final,但在构造函数中设置为 to。
该类公开了一个用于设置标识符的方法,例如,当实例插入数据存储并生成标识符时。
创建新实例时,原始实例保持不变。
相同的模式通常适用于存储管理的其他属性,但对于持久性操作,可能需要更改这些属性。
wither 方法是可选的,因为持久化构造函数(参见 6)实际上是一个复制构造函数,并且设置该属性将被转换为创建一个应用了新标识符值的新实例。null withId(…) Person |
2 | 和 属性是可能通过 getter 公开的普通不可变属性。firstname lastname |
3 | 该属性是不可变的,但派生自该属性。
显示设计后,数据库值将胜过默认值,因为 Spring Data 使用唯一声明的构造函数。
即使意图是应该首选计算,此构造函数也必须将 as 参数 (可能会忽略它) ,否则属性 population 步骤将尝试设置 age 字段并失败,因为它是不可变的并且不存在方法。age birthday age with… |
4 | 该属性是可变的,并通过直接设置其字段来填充。comment |
5 | 该属性是可变的,并通过调用 setter 方法进行填充。remarks |
6 | 该类公开了用于创建对象的工厂方法和构造函数。
这里的核心思想是使用工厂方法而不是额外的构造函数,以避免通过 .
相反,属性的默认值是在工厂方法中处理的。
如果希望 Spring Data 使用工厂方法进行对象实例化,请使用 .@PersistenceCreator @PersistenceCreator |
9.1.3. 一般建议
-
尽量坚持使用不可变对象 — 不可变对象很容易创建,因为具体化对象只需调用其构造函数即可。 此外,这还可以避免您的域对象充斥着允许客户端代码操作对象状态的 setter 方法。 如果需要这些,最好将它们设为包保护,以便它们只能由有限数量的共存类型调用。 仅构造函数具体化比属性填充快 30%。
-
提供全参数构造函数 — 即使您不能或不想将实体建模为不可变值,提供将实体的所有属性(包括可变属性)作为参数的构造函数仍然具有价值,因为这允许对象映射跳过属性填充以获得最佳性能。
-
使用工厂方法而不是重载的构造函数以避免
@PersistenceCreator
— 由于需要全参数构造函数才能获得最佳性能,我们通常希望公开更多特定于应用程序用例的构造函数,这些构造函数省略了自动生成的标识符等内容。 使用静态工厂方法来公开 all-args 构造函数的这些变体是一种既定模式。 -
请确保遵守允许使用生成的 instantiator 和 property 访问器类的约束 —
-
对于要生成的标识符,仍将 final 字段与全参数持久化构造函数(首选)或
with...
方法结合使用 — -
使用 Lombok 避免样板代码 — 由于持久性操作通常需要一个采用所有参数的构造函数,因此它们的声明会变成将样板参数繁琐地重复到字段分配中,最好通过使用 Lombok 的 .
@AllArgsConstructor
覆盖属性
Java 允许灵活地设计域类,其中子类可以定义一个属性,该属性已经在其超类中以相同的名称声明。 请考虑以下示例:
public class SuperType {
private CharSequence field;
public SuperType(CharSequence field) {
this.field = field;
}
public CharSequence getField() {
return this.field;
}
public void setField(CharSequence field) {
this.field = field;
}
}
public class SubType extends SuperType {
private String field;
public SubType(String field) {
super(field);
this.field = field;
}
@Override
public String getField() {
return this.field;
}
public void setField(String field) {
this.field = field;
// optional
super.setField(field);
}
}
这两个类都定义了 using 可赋值类型。 然而 shadows .
根据类设计,使用构造函数可能是设置 .
或者,调用 setter 可以将 in .
所有这些机制在某种程度上都会产生冲突,因为属性共享相同的名称,但可能表示两个不同的值。
如果类型不可分配,则 Spring Data 会跳过超类型属性。
也就是说,被覆盖属性的类型必须可分配给其超类型属性类型才能注册为 override,否则超类型属性被视为临时属性。
我们通常建议使用不同的属性名称。field
SubType
SuperType.field
SuperType.field
super.setField(…)
field
SuperType
Spring Data 模块通常支持持有不同值的覆盖属性。 从编程模型的角度来看,需要考虑以下几点:
-
应该保留哪个属性(默认为所有声明的属性)? 您可以通过使用 .
@Transient
-
如何在数据存储中表示属性? 对不同的值使用相同的字段/列名称通常会导致数据损坏,因此您应该使用显式字段/列名称至少注释一个属性。
-
不能使用 use,因为如果不对 setter 实现进行任何进一步的假设,通常无法设置 superproperty 。
@AccessType(PROPERTY)
9.1.4. Kotlin 支持
Spring Data 调整了 Kotlin 的细节以允许对象创建和更改。
Kotlin 对象创建
支持实例化 Kotlin 类,默认情况下所有类都是不可变的,并且需要显式属性声明来定义可变属性。
请考虑以下类:data
Person
data class Person(val id: String, val name: String)
上面的类编译为具有显式构造函数的典型类。我们可以通过添加另一个构造函数来自定义这个类,并对其进行注释以指示构造函数首选项:@PersistenceCreator
data class Person(var id: String, val name: String) {
@PersistenceCreator
constructor(id: String) : this(id, "unknown")
}
Kotlin 允许在未提供参数时使用默认值,从而支持参数可选性。
当Spring Data检测到具有参数 defaulting 的构造函数时,如果数据存储不提供值(或只是返回),则它不会保留这些参数,以便 Kotlin 可以应用参数 defaulting。请考虑以下类,该类为null
name
data class Person(var id: String, val name: String = "unknown")
每次参数不是结果的一部分或其值为 时,则默认为 。name
null
name
unknown
Kotlin 数据类的属性填充
在 Kotlin 中,默认情况下,所有类都是不可变的,并且需要显式属性声明来定义可变属性。
请考虑以下类:data
Person
data class Person(val id: String, val name: String)
这个类实际上是不可变的。
它允许创建新实例,因为 Kotlin 会生成一个方法来创建新的对象实例,从现有对象复制所有属性值,并将作为参数提供的属性值应用于该方法。copy(…)
Kotlin 覆盖属性
Kotlin 允许声明属性覆盖来更改子类中的属性。
open class SuperType(open var field: Int)
class SubType(override var field: Int = 1) :
SuperType(field) {
}
这样的排列会呈现两个名为 的属性。
Kotlin 会为每个类中的每个属性生成属性访问器(getter 和 setter)。
实际上,代码如下所示:field
public class SuperType {
private int field;
public SuperType(int field) {
this.field = field;
}
public int getField() {
return this.field;
}
public void setField(int field) {
this.field = field;
}
}
public final class SubType extends SuperType {
private int field;
public SubType(int field) {
super(field);
this.field = field;
}
public int getField() {
return this.field;
}
public void setField(int field) {
this.field = field;
}
}
仅 getter 和 setters on set 而不是 .
在这样的安排中,使用构造函数是设置 .
可以添加 method to set via,但不符合支持的约定。
属性覆盖在某种程度上会产生冲突,因为属性共享相同的名称,但可能表示两个不同的值。
我们通常建议使用不同的属性名称。SubType
SubType.field
SuperType.field
SuperType.field
SubType
SuperType.field
this.SuperType.field = …
Spring Data 模块通常支持持有不同值的覆盖属性。 从编程模型的角度来看,需要考虑以下几点:
-
应该保留哪个属性(默认为所有声明的属性)? 您可以通过使用 .
@Transient
-
如何在数据存储中表示属性? 对不同的值使用相同的字段/列名称通常会导致数据损坏,因此您应该使用显式字段/列名称至少注释一个属性。
-
不能使用 using,因为无法设置 super-property。
@AccessType(PROPERTY)
9.2. 实体映射
Spring Data for Apache Geode 支持映射存储在区域中的实体。映射元数据由 在 Application Domain 类上使用 Comments,如下例所示:
@Region("People")
public class Person {
@Id Long id;
String firstname;
String lastname;
@PersistenceConstructor
public Person(String firstname, String lastname) {
// …
}
…
}
该注释可用于自定义存储类实例的 Region。
该注释可用于注释应用作缓存 Region 键的属性,标识
Region 条目。该注释有助于消除多个可能可用的
构造函数,获取参数并显式标记注释为要使用的构造函数的构造函数
构造实体。在没有构造函数或只有一个构造函数的应用程序域类中,可以省略注释。@Region
Person
@Id
@PersistenceConstructor
除了将实体存储在顶级区域中外,实体还可以存储在子区域中。 如下例所示:
@Region("/Users/Admin")
public class Admin extends User {
…
}
@Region("/Users/Guest")
public class Guest extends User {
…
}
请务必使用 Apache Geode 区域的完整路径,如 Spring Data for Apache Geode XML 命名空间所定义
通过使用元素的 or 属性。id
name
<*-region>
9.2.1. 按区域类型划分的实体映射
除了注释之外, Spring Data for Apache Geode 还可以识别特定于类型的区域映射注释:、、 、 和 。@Region
@ClientRegion
@LocalRegion
@PartitionRegion
@ReplicateRegion
从功能上讲,这些注释的处理方式与 SDG 中的通用注释完全相同
测绘基础设施。但是,这些额外的映射注释在 Spring Data for Apache Geode 的
注释配置模型。与配置注释结合使用时
在 Spring 注解的类上,可以在本地缓存中生成 Region,无论
应用程序是客户端或对等方。@Region
@EnableEntityDefinedRegions
@Configuration
通过这些注释,您可以更具体地了解应用程序实体类应映射到的 Region 类型 并且还会对区域的数据管理策略产生影响(例如,分区(也称为分片)与复制数据)。
将这些特定于类型的区域映射注释与 SDG 注释配置模型结合使用可以节省您 不必在 configuration 中显式定义这些 Region。
9.3. 存储库映射
作为使用注释指定存储实体的区域的替代方法
在 Entity 类上,您还可以在实体的界面上指定 Annotation。
有关更多详细信息,请参阅 Spring Data for Apache Geode 存储库。@Region
@Region
Repository
但是,假设您要将记录存储在多个 Apache Geode 区域(例如 和 )中。然后,您可以定义相应的接口扩展,如下所示:Person
People
Customers
Repository
@Region("People")
public interface PersonRepository extends GemfireRepository<Person, String> {
…
}
@Region("Customers")
public interface CustomerRepository extends GemfireRepository<Person, String> {
...
}
然后,单独使用每个存储库,您可以将实体存储在多个 Apache Geode 区域中。 如下例所示:
@Service
class CustomerService {
CustomerRepository customerRepo;
PersonRepository personRepo;
Customer update(Customer customer) {
customerRepo.save(customer);
personRepo.save(customer);
return customer;
}
您甚至可以将 service 方法包装在 Spring 托管事务中,作为本地缓存事务
或全局事务。update
9.4. MappingPdxSerializer 映射
Spring Data for Apache Geode 提供了一个名为 的自定义 PdxSerializer
实现,它使用 Spring Data 映射元数据来自定义实体序列化。MappingPdxSerializer
序列化程序还允许您使用 Spring Data 抽象自定义实体实例化。
默认情况下,序列化程序使用 ,它使用
映射的实体。持久化构造函数是默认构造函数、单独声明的构造函数、
或显式注释有 .EntityInstantiator
ReflectionEntityInstantiator
@PersistenceConstructor
为了为构造函数参数提供参数,序列化程序读取具有命名构造函数参数
通过使用 Spring 的 Comments 从提供的 PdxReader
显式标识,
如以下示例所示:@Value
@Value
public class Person {
public Person(@Value("#root.thing") String firstName, @Value("bean") String lastName) {
…
}
}
以这种方式注释的实体类具有从 中读取的 “thing” 字段,并将其作为参数值传递
对于 constructor 参数,为 .的值是名为 “bean” 的 Spring Bean。PdxReader
firstname
lastName
除了
它还提供的功能远远超出了 Apache Geode 自己的 ReflectionBasedAutoSerializer
。EntityInstantiators
MappingPdxSerializer
虽然 Apache Geode 方便地使用 Java 反射来填充实体
并使用正则表达式来标识应由序列化器处理(序列化和反序列化)的类型,
与 不同,它不能执行以下操作:ReflectionBasedAutoSerializer
MappingPdxSerializer
-
按实体字段或属性名称和类型注册自定义对象。
PdxSerializer
-
方便地识别 ID 属性。
-
自动处理只读属性。
-
自动处理瞬态属性。
-
允许以类型安全的方式进行更健壮的类型过滤(例如,不限于 仅使用正则表达式表示类型)。
null
现在,我们更详细地探讨 的每个功能。MappingPdxSerializer
9.4.1. 自定义 PdxSerializer 注册
使您能够根据实体的字段注册自定义
或属性名称和类型。MappingPdxSerializer
PdxSerializers
例如,假设您定义了一个对 a 进行建模的实体类型,如下所示:User
package example.app.security.auth.model;
public class User {
private String name;
private Password password;
...
}
虽然用户名可能不需要任何特殊逻辑来序列化值,但序列化密码 另一方面,可能需要额外的 logic 来处理字段或属性的敏感性质。
也许你想在通过网络在客户端和服务器之间发送值时保护密码。
除了 TLS 之外,您只想存储加盐哈希值。使用 时,您可以注册
用于处理用户密码的自定义,如下所示:MappingPdxSerializer
PdxSerializer
PdxSerializers
Map<?, PdxSerializer> customPdxSerializers = new HashMap<>();
customPdxSerializers.put(Password.class, new SaltedHashPasswordPdxSerializer());
mappingPdxSerializer.setCustomPdxSerializers(customPdxSerializers);
在将应用程序定义的实例注册到应用程序域模型类型后,将查阅自定义以序列化和反序列化所有对象,而不管包含对象如何(例如,)。SaltedHashPasswordPdxSerializer
Password
MappingPdxSerializer
PdxSerializer
Password
User
但是,假设您只想自定义 对象的序列化。
为此,您可以通过指定完全限定名称来注册类型的自定义
,如下例所示:Passwords
User
PdxSerializer
User
Class’s
PdxSerializers
Map<?, PdxSerializer> customPdxSerializers = new HashMap<>();
customPdxSerializers.put("example.app.security.auth.model.User.password", new SaltedHashPasswordPdxSerializer());
mappingPdxSerializer.setCustomPdxSerializers(customPdxSerializers);
请注意使用完全限定的字段或属性名称(即 )
作为自定义注册码。example.app.security.auth.model.User.password
PdxSerializer
您可以使用更合乎逻辑的代码片段来构造注册密钥,如下所示:。我们推荐了这个方法,而不是前面显示的示例。
前面的示例尝试尽可能明确地说明注册的语义。User.class.getName().concat(".password"); |
9.4.2. 映射 ID 属性
与 Apache Geode 一样,SDG 也能够
确定实体的标识符。但是,通过使用 Spring Data 的 Map 元数据
特别是通过使用 Spring Data 的 @Id
注释查找指定为标识符的实体属性。
或者,任何名为 “id” 的字段或属性(未显式注释为 )也被指定为
实体的标识符。ReflectionBasedAutoSerializer
MappingPdxSerializer
MappingPdxSerializer
@Id
例如:
class Customer {
@Id
Long id;
...
}
在这种情况下,在序列化过程中调用该方法时,将使用 PdxWriter.markIdentifierField(:String)
将字段标记为 PDX 类型元数据中的标识符字段。Customer
id
PdxSerializer.toData(..)
9.4.3. 映射只读属性
当您的实体定义只读属性时会发生什么情况?
首先,了解什么是 “只读” 属性很重要。如果您按照 JavaBeans 规范定义 POJO(就像 Spring 一样), 您可以定义具有只读属性的 POJO,如下所示:
package example;
class ApplicationDomainType {
private AnotherType readOnly;
public AnotherType getReadOnly() [
this.readOnly;
}
...
}
该属性是只读的,因为它不提供 setter 方法。它只有一个 getter 方法。
在这种情况下,属性(不要与字段混淆)
被视为只读。readOnly
readOnly
readOnly
DomainType
因此,在方法中填充 的实例时,不会尝试为此属性设置值
在反序列化期间,特别是当 PDX 序列化字节中存在值时。MappingPdxSerializer
ApplicationDomainType
PdxSerializer.fromData(:Class<ApplicationDomainType>, :PdxReader)
当您可能要返回某种实体类型的视图或投影,并且您只希望 以设置可写状态。也许实体的视图或投影基于授权或其他一些 标准。关键是,您可以根据应用程序的使用案例来利用此功能 和要求。如果您希望始终写入字段或属性,只需定义一个 setter 方法。
9.4.4. 映射瞬态属性
同样,当您的实体定义属性时会发生什么情况?transient
在序列化时,您可能希望实体的字段或属性不会序列化为 PDX
实体。这正是发生的事情,与 Apache Geode 自己的 不同,
它通过 Java Reflection 序列化可从对象访问的所有内容。transient
ReflectionBasedAutoSerializer
也不会序列化任何被限定为瞬态的字段或属性
通过使用 Java 自己的关键字(在类实例字段的情况下)或通过在字段或属性上使用 @Transient
Spring Data 注释。MappingPdxSerializer
transient
例如,您可以定义具有临时字段和属性的实体,如下所示:
package example;
class Process {
private transient int id;
private File workingDirectory;
private String name;
private Type type;
@Transient
public String getHostname() {
...
}
...
}
字段和 readable 属性都不会写入 PDX。Process
id
hostname
9.4.5. 按类类型过滤
与 Apache Geode 类似,SDG 允许您进行筛选
序列化和反序列化的对象类型。ReflectionBasedAutoSerializer
MappingPdxSerializer
但是,与 Apache Geode 的 不同,Apache Geode 使用复杂的正则表达式来表示
序列化器处理哪些类型,SDG 使用更健壮的 java.util.function.Predicate
接口
和 API 来表示类型匹配标准。ReflectionBasedAutoSerializer
MappingPdxSerializer
如果您想使用正则表达式,则可以使用 Java 的正则表达式支持来实现一个。Predicate |
Java 界面的优点在于,您可以使用方便的
以及适当的 API 方法,包括:and(:P redicate)
或 (:P redicate)
,
和 negate()
的 URL 中。Predicate
Predicates
以下示例显示了 API 的运行情况:Predicate
Predicate<Class<?>> customerTypes =
type -> Customer.class.getPackage().getName().startsWith(type.getName()); // Include all types in the same package as `Customer`
Predicate includedTypes = customerTypes
.or(type -> User.class.isAssignble(type)); // Additionally, include User sub-types (e.g. Admin, Guest, etc)
mappingPdxSerializer.setIncludeTypeFilters(includedTypes);
mappingPdxSerializer.setExcludeTypeFilters(
type -> !Reference.class.getPackage(type.getPackage()); // Exclude Reference types
传递给 your 的任何对象都保证不是 .Class Predicate null |
SDG 包括对 include 和 exclude 类类型过滤器的支持。MappingPdxSerializer
排除类型筛选
默认情况下,SDG 的 registers 预定义了过滤或排除类型
从以下软件包中:MappingPdxSerializer
Predicates
-
java.*
-
com.gemstone.gemfire.*
-
org.apache.geode.*
-
org.springframework.*
此外,在调用时筛选对象,在调用方法时筛选类类型。MappingPdxSerializer
null
PdxSerializer.toData(:Object, :PdxWriter)
null
PdxSerializer.fromData(:Class<?>, :PdxReader)
为其他类类型或整个类型包添加排除项非常容易,只需定义 a 并将其添加到 中,如前所述。Predicate
MappingPdxSerializer
该方法是加法的,这意味着它由
应用程序定义的类型过滤器与上面所示的现有预定义类型过滤器
using the method.MappingPdxSerializer.setExcludeTypeFilters(:Predicate<Class<?>>)
Predicates
Predicate.and(:Predicate<Class<?>>)
但是,如果要包含由
排除类型过滤器?请参阅包括类型过滤。java.security Principal
包括类型筛选
如果要显式包含类类型,或重写隐式排除类类型的类类型筛选器
需要(例如,默认情况下,在包排除类型过滤器打开时排除了它),然后只需定义适当的 并将其添加到
序列化器 using 方法,如下所示:java.security.Principal
java.*
MappingPdxSerializer
Predicate
MappingPdxSerializer.setIncludeTypeFilters(:Predicate<Class<?>>)
Predicate<Class<?>> principalTypeFilter =
type -> java.security.Principal.class.isAssignableFrom(type);
mappingPdxSerializer.setIncludeTypeFilters(principalTypeFilters);
同样,方法
like ,是 additive 的,因此组成任何传递的类型过滤器
用。这意味着您可以根据需要多次调用。MappingPdxSerializer.setIncludeTypeFilters(:Predicate<Class<?>>)
setExcludeTypeFilters(:Predicate<Class<?>>)
Predicate.or(:Predicate<Class<?>>)
setIncludeTypeFilters(:Predicate<Class<?>>)
当存在包含类型过滤器时,则 会决定是否取消/序列化
类类型的实例(当类类型未被隐式排除时,或者当类类型
显式包含,以返回 true 者为准。然后,类类型的实例将被序列化
或适当地反序列化。MappingPdxSerializer
例如,当 type filter of 如前所述显式注册时,
它会取消包类型的隐式 Exclude Type 筛选器。Predicate<Class<Principal>>
java.*
10. 适用于 Apache Geode 存储库的 Spring Data
Spring Data for Apache Geode 支持使用 Spring Data Repository 抽象轻松地将实体持久化到 Apache Geode 以及执行查询。存储库编程模型的一般介绍 在此处提供。
10.1. Spring XML 配置
要引导 Spring Data Repositories,请使用 Spring Data for Apache Geode Data 命名空间中的元素。
如下例所示:<repositories/>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:gfe-data="https://www.springframework.org/schema/data/geode"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/data/geode https://www.springframework.org/schema/data/geode/spring-data-geode.xsd
">
<gfe-data:repositories base-package="com.example.acme.repository"/>
</beans>
前面的配置代码段在配置的基础包下查找接口,并创建 Repository 实例
对于由 SimpleGemFireRepository
支持的接口。
除非您正确映射了应用程序域类,否则引导过程将失败 添加到已配置的区域。 |
10.2. Spring 基于 Java 的配置
或者,许多开发人员更喜欢使用 Spring 的基于 Java 的容器配置。
使用这种方法,您可以使用 SDG 注释引导 Spring Data Repositories,如下例所示:@EnableGemfireRepositories
@EnableGemfireRepositories
@SpringBootApplication
@EnableGemfireRepositories(basePackages = "com.example.acme.repository")
class SpringDataApplication {
...
}
您可能更喜欢使用 type-safe 属性,而不是使用 attribute。
允许您通过以下方式指定包含所有应用程序 Repository 类的包
仅指定您的应用程序 Repository 接口类型之一。考虑创建一个特殊的无操作标记类
或接口,该接口仅用于标识应用程序存储库的位置
引用。basePackages
basePackageClasses
basePackageClasses
除了 attributes 之外,比如 Spring 的 @ComponentScan
注解,
该注释根据 Spring 的ComponentScan.Filter
类型提供包含和排除过滤器。
您可以使用该属性按不同方面进行筛选,例如应用程序存储库类型
使用特定 Comments 进行注释或扩展特定类类型,依此类推。有关更多详细信息,请参阅 FilterType
Javadoc。basePackages and basePackageClasses
@EnableGemfireRepositories
filterType
该注释还允许您指定命名 OQL 查询的位置,该查询位于
Java 文件。属性名称必须与名称匹配
的 Repository 查询方法,属性值是您希望在 Repository 查询方法时执行的 OQL 查询
被调用。@EnableGemfireRepositories
Properties
namedQueriesLocation
如果您的
application 需要一个或多个自定义存储库实现。
此功能通常用于扩展 Spring Data Repository 基础结构,以实现
数据存储(例如 SDG)。repositoryImplementationPostfix
Impl
Apache Geode 需要自定义存储库实现的一个示例是执行联接时。
SDG 存储库不支持联接。对于 Apache Geode 区域,联接必须为
在并置区域上执行,因为 Apache Geode 不支持“分布式”联接。
此外,Equi-Join OQL 查询必须在 Apache Geode 函数中执行。
有关 Apache Geode 等值联接查询的更多详细信息,请参阅此处。PARTITION
PARTITION
SDG 的 Repository 基础设施扩展的许多其他方面也可以进行自定义。有关所有配置设置的更多详细信息,请参阅 @EnableGemfireRepositories
Javadoc。
10.3. 执行 OQL 查询
Spring Data for Apache Geode 存储库支持定义查询方法,以轻松执行 Apache Geode OQL 查询 针对托管实体映射到的区域,如下例所示:
@Region("People")
public class Person { … }
public interface PersonRepository extends CrudRepository<Person, Long> {
Person findByEmailAddress(String emailAddress);
Collection<Person> findByFirstname(String firstname);
@Query("SELECT * FROM /People p WHERE p.firstname = $1")
Collection<Person> findByFirstnameAnnotated(String firstname);
@Query("SELECT * FROM /People p WHERE p.firstname IN SET $1")
Collection<Person> findByFirstnamesAnnotated(Collection<String> firstnames);
}
前面示例中列出的第一个查询方法会导致派生以下 OQL 查询:。第二种 query 方法的工作方式相同,但
它返回找到的所有实体,而第一个 Query 方法期望找到单个结果。SELECT x FROM /People x WHERE x.emailAddress = $1
如果支持的关键字不足以声明和表达您的 OQL 查询,或者方法名称也
verbose,则您可以使用第三个和第四个方法所示对查询方法进行注释。@Query
下表提供了可在查询方法中使用的受支持关键字的简要示例:
关键词 | 样本 | 逻辑结果 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(无关键词) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10.4. 使用注解的 OQL 查询扩展
许多查询语言,例如 Apache Geode 的 OQL(对象查询语言),具有不直接的扩展 由 Spring Data Commons 的 Repository 基础架构提供支持。
Spring Data Commons 的 Repository 基础设施目标之一是作为维护的最低公分母 支持和移植最广泛的可用数据存储,并用于应用程序开发 今天。从技术上讲,这意味着开发人员可以访问 Spring Data Commons 支持的多个不同的数据存储 通过重用现有的特定于应用程序的 Repository 接口 — 一种方便的 和强大的抽象。
为了支持 Apache Geode 的 OQL 查询语言扩展并保持跨不同数据存储的可移植性, Spring Data for Apache Geode 通过使用 Java 注释增加了对 OQL 查询扩展的支持。这些注释会被其他 没有类似 查询语言功能。
例如,许多数据存储很可能不实现 Apache Geode 的 OQL 关键字。作为 Annotation (即 ) 实现,而不是作为查询方法签名(具体而言,方法 'name')的一部分实现
在评估查询方法名称以构建另一个数据存储时,不会干扰解析基础设施
language appropriate 查询。IMPORT
IMPORT
@Import
目前,Spring Data for Apache Geode 支持的 Apache Geode OQL 查询语言扩展集包括:
关键词 | 注解 | 描述 | 参数 |
---|---|---|---|
|
OQL 查询索引提示 |
|
|
|
限定特定于应用程序的类型。 |
|
|
|
限制返回的查询结果集。 |
|
|
|
启用 OQL 查询特定的调试。 |
那 |
例如,假设您有一个应用程序域类和相应的 Apache Geode Region
以及 a 和 a query 方法按姓氏查找,如下所示:Customers
CustomerRepository
Customers
package ...;
...
@Region("Customers")
public class Customer ... {
@Id
private Long id;
...
}
package ...;
public interface CustomerRepository extends GemfireRepository<Customer, Long> {
@Trace
@Limit(10)
@Hint("LastNameIdx")
@Import("org.example.app.domain.Customer")
List<Customer> findByLastName(String lastName);
...
}
前面的示例生成以下 OQL 查询:
<TRACE> <HINT 'LastNameIdx'> IMPORT org.example.app.domain.Customer; SELECT * FROM /Customers x WHERE x.lastName = $1 LIMIT 10
Spring Data for Apache Geode 的存储库扩展会小心翼翼地避免在 OQL 注释扩展时创建冲突的声明
与 Comments 结合使用。@Query
再举一个例子,假设您在 ,
如下:@Query
CustomerRepository
public interface CustomerRepository extends GemfireRepository<Customer, Long> {
@Trace
@Limit(10)
@Hint("CustomerIdx")
@Import("org.example.app.domain.Customer")
@Query("<TRACE> <HINT 'ReputationIdx'> SELECT DISTINCT * FROM /Customers c WHERE c.reputation > $1 ORDER BY c.reputation DESC LIMIT 5")
List<Customer> findDistinctCustomersByReputationGreaterThanOrderByReputationDesc(Integer reputation);
}
上述查询方法将生成以下 OQL 查询:
IMPORT org.example.app.domain.Customer; <TRACE> <HINT 'ReputationIdx'> SELECT DISTINCT * FROM /Customers x
WHERE x.reputation > $1 ORDER BY c.reputation DESC LIMIT 5
注释不会覆盖原始查询中显式定义的注释。
此外,注释不会覆盖原始查询中显式定义的注释。
最后,注释是多余的,没有额外的影响。@Limit(10)
LIMIT
@Hint("CustomerIdx")
HINT
@Trace
考虑到可能拥有的客户数量,该指数可能不是最明智的指数
他们的声誉值相同,这会降低指数的有效性。请选择索引和其他
明智地进行优化,因为不正确或选择不当的索引可能会对您的性能产生相反的影响,因为
维护索引的开销。该仅用于实现示例的目的。 |
10.5. 查询后处理
由于使用了 Spring Data Repository 抽象,用于定义数据存储特定的 查询(例如 OQL)既简单又方便。然而,有时仍然希望进行检查甚至可能进行检查 修改从 Repository 查询方法生成的查询。
从 2.0.x 开始,Spring Data for Apache Geode 包括功能接口。
该接口的定义大致如下:o.s.d.gemfire.repository.query.QueryPostProcessor
package org.springframework.data.gemfire.repository.query;
@FunctionalInterface
interface QueryPostProcessor<T extends Repository, QUERY> extends Ordered {
QUERY postProcess(QueryMethod queryMethod, QUERY query, Object... arguments);
}
还提供了其他默认方法,允许您编写类似于 java.util.function.Function.andThen(:Function) 和 java.util.function.Function.compose(:Function) 工作方式的实例。QueryPostProcessor
此外,该接口还实现了 org.springframework.core.Ordered
接口
这在 Spring 容器中声明和注册多个并用于
为一组生成的 Query Method 查询创建处理管道。QueryPostProcessor
QueryPostProcessors
最后,接受与类型参数对应的类型参数,以及
分别。类型扩展了 Spring Data Commons 标记接口org.springframework.data.repository.Repository
。
我们将在本节后面进一步讨论这一点。Spring Data for Apache Geode 案例中的所有类型参数参数都是 type 。QueryPostProcessor
T
QUERY
T
QUERY
java.lang.String
将查询定义为 type 很有用,因为此接口可以移植到
Spring Data Commons,因此必须处理不同数据存储(例如 JPA、MongoDB、
或 Redis)。QUERY QueryPostProcessor |
您可以实现此接口,以便在调用该方法时接收从应用程序接口方法生成的查询的回调。Repository
例如,您可能希望记录来自所有应用程序存储库接口定义的所有查询。你可以这样做
使用以下实现:QueryPostProcessor
package example;
class LoggingQueryPostProcessor implements QueryPostProcessor<Repository, String> {
private Logger logger = Logger.getLogger("someLoggerName");
@Override
public String postProcess(QueryMethod queryMethod, String query, Object... arguments) {
String message = String.format("Executing query [%s] with arguments [%s]", query, Arrays.toString(arguments));
this.logger.info(message);
}
}
该 被键入到 Spring Data 标记器接口,因此,记录所有应用程序 Repository 接口查询方法生成的查询。LoggingQueryPostProcessor
org.springframework.data.repository.Repository
您可以将此日志记录的范围限制为仅来自某些类型的应用程序存储库接口的查询。
例如,例如,A ,如下例所示:CustomerRepository
interface CustomerRepository extends CrudRepository<Customer, Long> {
Customer findByAccountNumber(String accountNumber);
List<Customer> findByLastNameLike(String lastName);
}
然后,您可以专门键入 ,如下所示:LoggingQueryPostProcessor
CustomerRepository
class LoggingQueryPostProcessor implements QueryPostProcessor<CustomerRepository, String> { .. }
因此,仅记录接口中定义的查询,例如 。CustomerRepository
findByAccountNumber
您可能希望为 Repository 查询方法定义的特定查询创建。例如
假设您要限制从查询方法生成的 OQL 查询
仅返回五个结果以及按升序排序 by 。为此,
您可以定义 自定义 ,如下例所示:QueryPostProcessor
CustomerRepository.findByLastNameLike(:String)
Customers
firstName
QueryPostProcessor
class OrderedLimitedCustomerByLastNameQueryPostProcessor implements QueryPostProcessor<CustomerRepository, String> {
private final int limit;
public OrderedLimitedCustomerByLastNameQueryPostProcessor(int limit) {
this.limit = limit;
}
@Override
public String postProcess(QueryMethod queryMethod, String query, Object... arguments) {
return "findByLastNameLike".equals(queryMethod.getName())
? query.trim()
.replace("SELECT", "SELECT DISTINCT")
.concat(" ORDER BY firstName ASC")
.concat(String.format(" LIMIT %d", this.limit))
: query;
}
}
虽然前面的示例有效,但您可以使用 Spring Data Repository 约定实现相同的效果 由 Spring Data for Apache Geode 提供。例如,可以按如下方式定义相同的查询:
interface CustomerRepository extends CrudRepository<Customer, Long> {
@Limit(5)
List<Customer> findDistinctByLastNameLikeOrderByFirstNameDesc(String lastName);
}
但是,如果您无法控制应用程序接口定义,则
那么 (即 ) 很方便。CustomerRepository
QueryPostProcessor
OrderedLimitedCustomerByLastNameQueryPostProcessor
如果要确保 总是在另一个应用程序定义的之后,该应用程序定义可能在Spring中声明并注册了bean,则可以设置。
该属性,如下例所示:LoggingQueryPostProcessor
QueryPostProcessors
ApplicationContext
order
o.s.core.Ordered.getOrder()
order
class LoggingQueryPostProcessor implements QueryPostProcessor<Repository, String> {
@Override
int getOrder() {
return 1;
}
}
class CustomerQueryPostProcessor implements QueryPostProcessor<CustomerRepository, String> {
@Override
int getOrder() {
return 0;
}
}
这可确保您始终在记录查询之前看到其他人应用的后处理的效果。QueryPostProcessors
LoggingQueryPostProcessor
您可以在 Spring 中定义任意数量的 Spring 并按任意顺序应用它们。
添加到所有或特定的应用程序存储库接口,并使用提供的参数根据需要进行精细化
添加到方法回调中。QueryPostProcessors
ApplicationContext
postProcess(..)
11. 函数执行的 Annotation 支持
Spring Data for Apache Geode 包括注释支持,以简化 Apache Geode 函数的执行。
在后台,Apache Geode API 提供了用于实现和注册部署在 Apache Geode 上的 Apache Geode 函数的类 服务器,然后可以由其他对等成员应用程序调用或从缓存客户端远程调用。
函数可以并行执行,分布在集群中的多个 Apache Geode 服务器之间,聚合 结果,并发送回给调用者。函数也可以针对在单个 server 或 Region。Apache Geode API 支持使用各种预定义的 范围:区域、成员(组)、服务器等。远程函数的实现和执行, 与任何 RPC 协议一样,需要一些样板代码。
Spring Data for Apache Geode 忠实于 Spring 的核心价值主张,旨在隐藏远程函数执行的机制,让您 专注于核心 POJO 编程和业务逻辑。为此,Spring Data for Apache Geode 引入了 annotation to declarively 将 POJO 类的公共方法注册为 Apache Geode 函数,并能够调用已注册的 使用带注释的接口执行函数 (包括远程) 。
11.1. 实现与执行
有两个单独的问题需要解决:实现和执行。
第一个是 Function 实现(服务器端),它必须与 FunctionContext
交互以访问调用参数,ResultsSender
以发送结果,
和其他执行上下文信息。Function 实现通常访问缓存和 Region
并在 FunctionService
中以唯一 ID 注册。
调用 Function 的缓存客户端应用程序不依赖于实现。要调用 Function,
应用程序实例化一个 Execution
,提供 Function ID、调用参数和 Function 目标,用于定义其范围:
区域、服务器、服务器、成员或成员。如果 Function 产生结果,则调用者使用 ResultCollector
聚合并获取执行结果。在某些情况下,自定义实现
是必需的,并且可以在 .ResultCollector
Execution
此处在函数执行的上下文中使用“Client”和“Server”,可能具有不同的含义
比 Apache Geode 的客户端-服务器拓扑中的客户端和服务器。虽然使用
一个实例,用于在集群中的一个或多个 Apache Geode 服务器上调用函数,则它也是
可以在点对点 (P2P) 配置中执行 Functions,其中应用程序是集群的成员
托管对等实例。请记住,对等成员缓存应用程序受所有约束的约束
成为集群的对等成员。ClientCache Cache |
11.2. 实现函数
使用 Apache Geode API,它提供了一个运行时调用上下文,其中包括客户端的
调用参数和实现以将结果发送回客户端。此外,如果函数
在 Region 上执行,则实际上是 的实例,它提供
其他信息,例如调用函数的目标区域、任何筛选条件(一组特定键)
与 关联 ,依此类推。如果 Region 是 Region,则 Function 应使用
提取本地数据集。FunctionContext
ResultSender
FunctionContext
RegionFunctionContext
Execution
PARTITION
PartitionRegionHelper
通过使用 Spring,您可以编写一个简单的 POJO 并使用 Spring 容器来绑定一个或多个 POJO
public 方法传递给 Function。旨在用作 Function 的 POJO 方法的签名通常必须符合
添加到客户端的执行参数中。但是,在执行 Region 的情况下,也可以提供 Region 数据
(如果 Region 是 Region,则数据可能保存在本地分区中)。PARTITION
此外,函数可能需要应用的筛选器(如果有)。这表明 Client 端和 Server
共享调用参数的 Contract,但方法签名可以包含额外的参数来传递值
由 提供。一种可能性是客户端和服务器共享一个公共接口,但是这个
并非严格要求。唯一的约束是方法签名包含相同的调用参数序列
在解析其他参数后调用函数。FunctionContext
例如,假设客户端提供 a 和 an 作为调用参数。这些是提供的
在 AS 数组中,如下例所示:String
int
FunctionContext
Object[] args = new Object[] { "test", 123 };
Spring 容器应该能够绑定到类似于以下内容的任何方法签名(忽略返回类型 目前):
public Object method1(String s1, int i2) { ... }
public Object method2(Map<?, ?> data, String s1, int i2) { ... }
public Object method3(String s1, Map<?, ?> data, int i2) { ... }
public Object method4(String s1, Map<?, ?> data, Set<?> filter, int i2) { ... }
public void method4(String s1, Set<?> filter, int i2, Region<?,?> data) { ... }
public void method5(String s1, ResultSender rs, int i2) { ... }
public void method6(FunctionContest context) { ... }
一般规则是,一旦解析了任何其他参数(即 Region data 和 filter),则
其余参数必须在 order 和 type 上与预期的 Function 方法参数完全对应。
该方法的返回类型必须是 void 或可以序列化(作为 、 、
或 )。后者也是调用参数的要求。java.io.Serializable
DataSerializable
PdxSerializable
Region 数据通常应定义为 ,以便于单元测试,但也可以是 Region 类型,
如有必要。如前面的示例所示,将 self 本身传递给
或者,如果您需要控制将结果返回到客户端的方式。Map
FunctionContext
ResultSender
11.2.1. 函数实现的注解
以下示例显示了如何使用 SDG 的 Function 注解来公开 POJO 方法 作为 Apache Geode Functions:
@Component
public class ApplicationFunctions {
@GemfireFunction
public String function1(String value, @RegionData Map<?, ?> data, int i2) { ... }
@GemfireFunction(id = "myFunction", batchSize=100, HA=true, optimizedForWrite=true)
public List<String> function2(String value, @RegionData Map<?, ?> data, int i2, @Filter Set<?> keys) { ... }
@GemfireFunction(hasResult=true)
public void functionWithContext(FunctionContext functionContext) { ... }
}
请注意,类本身必须注册为 Spring bean,并且每个 Apache Geode 函数都用 .在前面的示例中,使用了 Spring 的 Comments,但你可以注册 Bean
通过使用 Spring 支持的任何方法(例如 XML 配置,或者在使用
Spring Boot 的 Boot)。这允许 Spring 容器创建此类的实例并将其包装在 PojoFunctionWrapper
中。
Spring 为每个方法创建一个包装器实例,并用 .每个包装器实例共享
相同的 Target Object 实例来调用相应的方法。@GemfireFunction
@Component
@GemfireFunction
POJO Function 类是 Spring bean 这一事实可能会提供其他好处。由于它共享
使用 Apache Geode 组件(例如缓存和区域),这些组件可以注入到
类(如有必要)。ApplicationContext |
Spring 创建包装器类,并使用 Apache Geode 的 .函数 ID
用于注册的每个 Function 必须是唯一的。通过使用约定,它默认为简单(非限定)方法名称。
可以使用 Comments 的属性显式定义名称。FunctionService
id
@GemfireFunction
该 Comments 还提供其他配置属性:和 ,
对应于 Apache Geode 的 Function
接口定义的属性。@GemfireFunction
HA
optimizedForWrite
如果 POJO Function 方法的返回类型为 ,则属性会自动设置为 。
否则,如果方法返回值,则 attributes 将设置为 。Even for method return
types,则可以将注解的属性设置为 to 来覆盖此约定,
如前面显示的方法所示。据推测,其目的是您将使用
直接将结果发送给调用方。void
hasResult
false
hasResult
true
void
GemfireFunction
hasResult
true
functionWithContext
ResultSender
最后,注释支持 attribute (属性),该属性指定权限
执行函数所需的。默认情况下,所有 Function 都需要该权限。属性
接受一个 String 数组,允许您根据应用程序和/或 Function UC 的要求修改权限。
每个资源权限应采用以下格式:。GemfireFunction
requiredPermissions
DATA:WRITE
<RESOURCE>:<OPERATION>:[Target]:[Key]
RESOURCE
可以是 {data-store-javadoc]/org/apache/geode/security/ResourcePermission.Resource.html 中的 1 个
枚举值。 可以是 {data-store-javadoc}/org/apache/geode/security/ResourcePermission.Operation.html 中的 1 个
枚举值。(可选)可以是 Region 的名称或 1 个
{数据存储-javadoc}/org/apache/geode/security/ResourcePermission.Target.html[]
枚举值。最后,(可选)是区域中的有效 Key(如果指定)。ResourcePermission.Resource
OPERATION
ResourcePermission.Operation
Target
ResourcePermission.Target
Key
Target
实现 Apache Geode 的接口,绑定方法参数,并调用
目标方法在其方法中。它还将方法的返回值发送回调用方
通过使用 .PojoFunctionWrapper
Function
execute()
ResultSender
11.2.2. 批处理结果
如果返回类型是数组 或 ,则必须考虑如何返回结果。
默认情况下,the 返回整个数组或一次返回。如果元素数
或非常大,则可能会导致性能损失。要将 payload 划分为更小的
更易于管理的块,您可以设置该属性,如前面所示。Collection
PojoFunctionWrapper
Collection
Collection
batchSize
function2
如果您需要对 进行更多控制,特别是如果方法本身会占用太多内存
要创建 ,您可以传入 或通过 访问它,并直接在方法中使用它,将结果发送回调用方。ResultSender Collection ResultSender FunctionContext |
11.3. 执行函数
调用远程 Function 的进程需要提供 Function 的 ID,调用参数、执行目标
(、、、 或 ) 和(可选)过滤器集。通过使用 Spring Data for Apache Geode,
您需要做的就是定义一个 Annotations 支持的接口。Spring 为接口创建一个动态代理,
它使用 来创建 、 调用 和 (如有必要) 强制
结果转换为定义的返回类型。此技术类似于 Spring Data for Apache Geode 的存储库扩展的工作方式。
因此,应该熟悉一些配置和概念。onRegion
onServers
onServer
onMember
onMembers
FunctionService
Execution
Execution
通常,单个接口定义映射到多个 Function 执行,每个 Function 对应一个方法 在接口中定义。
11.3.1. 函数执行的注解
为了支持客户端函数执行,提供了以下 SDG 函数注释:、、、 和 .这些注释对应于 Apache Geode 的 FunctionService
类提供的实现。@OnRegion
@OnServer
@OnServers
@OnMember
@OnMembers
Execution
每个注释都公开了相应的属性。这些 Comments 还提供了一个 optional 属性
其值是实现ResultCollector
接口的 Spring bean 的名称
用于执行。resultCollector
代理接口将所有声明的方法绑定到相同的执行配置。虽然这是意料之中的 单个方法接口是通用的,则接口中的所有方法都由相同的代理实例提供支持 ,因此它们都共享相同的配置。 |
下面的清单显示了几个示例:
@OnRegion(region="SomeRegion", resultCollector="myCollector")
public interface FunctionExecution {
@FunctionId("function1")
String doIt(String s1, int i2);
String getString(Object arg1, @Filter Set<Object> keys);
}
默认情况下,Function ID (函数 ID) 是简单(非限定)方法名称。可以使用 Annotation
将此调用绑定到其他函数 ID。@FunctionId
11.3.2. 启用 Comments 处理
客户端使用 Spring 的 Classpath 组件扫描功能来发现带 Comments 的接口。要启用 XML 中的函数执行注释处理,请在 XML 配置中插入以下元素:
<gfe-data:function-executions base-package="org.example.myapp.gemfire.functions"/>
该元素在 XML 命名空间中提供。该属性是必需的
以避免扫描整个 Classpath。可以按照 Spring 参考文档中的描述提供其他过滤器。function-executions
gfe-data
base-package
或者,您可以按如下方式注释 Java 配置类:
@EnableGemfireFunctionExecutions(basePackages = "org.example.myapp.gemfire.functions")
11.4. 编程函数执行
使用上一节中定义的 Function execution annotated interface,只需自动连接您的接口 导入到将调用 Function 的应用程序 Bean 中:
@Component
public class MyApplication {
@Autowired
FunctionExecution functionExecution;
public void doSomething() {
functionExecution.doIt("hello", 123);
}
}
或者,您可以直接使用 Function 执行模板。在以下示例中,
将创建一个 Function :GemfireOnRegionFunctionTemplate
onRegion
Execution
GemfireOnRegionFunctionTemplate
Set<?, ?> myFilter = getFilter();
Region<?, ?> myRegion = getRegion();
GemfireOnRegionOperations template = new GemfireOnRegionFunctionTemplate(myRegion);
String result = template.executeAndExtract("someFunction", myFilter, "hello", "world", 1234);
在内部,Function 总是返回一个 . 假定一个包含结果的 singleton,并尝试将该值强制转换为请求的类型。还有一种方法
这将返回 As Is。第一个参数是函数 ID。filter 参数是可选的。剩余的
arguments 是 variable argument 。Executions
List
executeAndExtract
List
execute
List
List
11.5. 使用 PDX 执行函数
将 Spring Data for Apache Geode 的 Function 注释支持与 Apache Geode 的 PDX 序列化结合使用时, 有一些后勤事项需要牢记。
如本节前面所述,举例来说,您通常应该定义 Apache Geode 函数 通过使用带有 Spring Data for Apache Geode 函数注释的 POJO 类, 如下:
public class OrderFunctions {
@GemfireFunction(...)
Order process(@RegionData data, Order order, OrderSource orderSourceEnum, Integer count) { ... }
}
typed 参数是任意的,类的分隔也是任意的
和 enum ,它们的组合可能是合乎逻辑的。但是,参数是这样设置的
演示 PDX 上下文中的 Function 执行问题。Integer count Order OrderSource |
您的 class 和 enum 可以定义如下:Order
OrderSource
public class Order ... {
private Long orderNumber;
private LocalDateTime orderDateTime;
private Customer customer;
private List<Item> items
...
}
public enum OrderSource {
ONLINE,
PHONE,
POINT_OF_SALE
...
}
当然,您可以定义一个 Function 接口来调用 'process' Apache Geode 服务器 Function,
如下:Execution
@OnServer
public interface OrderProcessingFunctions {
Order process(Order order, OrderSource orderSourceEnum, Integer count);
}
显然,此 Function 是使用实例从客户端调用
(即 )。这意味着 Function 参数也必须是可序列化的。同样的情况
在集群中的 Peer 节点之间调用 Peer-to-Peer 成员函数(如 )时。任何形式的 of 都需要对 Client 端和服务器(或 Peer 节点)之间传输的数据进行序列化。process(..)
Order
ClientCache
<gfe:client-cache/>
@OnMember(s)
distribution
现在,如果您已将 Apache Geode 配置为使用 PDX 进行序列化(而不是 Java 序列化,例如)
您还可以在 Apache Geode 服务器的配置中将属性设置为
如下:pdx-read-serialized
true
<gfe:cache pdx-read-serialized="true"/>
或者,您可以将 Apache Geode 缓存客户端应用程序的属性设置为
如下:pdx-read-serialized
true
<gfe:client-cache pdx-read-serialized="true"/>
这样做会导致从缓存中读取所有值(即 Region)以及在客户端和服务器之间传递的信息 (或 peers)保持序列化形式,包括但不限于 Function 参数。
Apache Geode 仅序列化您专门配置(注册)的应用程序域对象类型
通过使用 Apache Geode 的 ReflectionBasedAutoSerializer
,
或者专门 (和推荐) 使用“自定义”Apache Geode PdxSerializer
。
如果您使用 Spring Data for Apache Geode 的存储库扩展,您甚至可能需要考虑使用 Spring Data for Apache Geode 的 MappingPdxSerializer
。
它使用实体的映射元数据来确定来自序列化的应用程序域对象的数据
添加到 PDX 实例。
但是,不太明显的是,Apache Geode 会自动处理 Java 类型,而不管
它们是否被显式配置(即,向 、
使用正则表达式模式和参数 or 由“自定义”Apache Geode 处理)、
尽管 Java 枚举实现 .Enum
ReflectionBasedAutoSerializer
classes
PdxSerializer
java.io.Serializable
因此,当您在 Apache Geode 函数
(包括 Spring Data for Apache Geode 函数注释的 POJO 类)已注册,那么您可能会遇到令人惊讶的行为
调用 Function .pdx-read-serialized
true
Execution
调用 Function 时,您可以传递以下参数:
orderProcessingFunctions.process(new Order(123, customer, LocalDateTime.now(), items), OrderSource.ONLINE, 400);
但是,服务器上的 Apache Geode 函数将获得以下内容:
process(regionData, order:PdxInstance, :PdxInstanceEnum, 400);
和 已作为 PDX 实例传递给函数。
同样,这一切都是因为 设置为 ,这在
Apache Geode 服务器与多个不同的客户端(例如,Java 客户端的组合)进行交互
和本机客户端,例如 C/C++、C# 等)。Order
OrderSource
pdx-read-serialized
true
这与 Spring Data for Apache Geode 的强类型函数注释的 POJO 类方法签名背道而驰,在那里你会 合理地期望应用程序域对象类型,而不是 PDX 序列化实例。
因此, Spring Data for Apache Geode 包括增强的函数支持,以自动转换 PDX 类型的方法参数 添加到由 Function 方法的签名(参数类型)定义的所需应用程序域对象类型。
但是,这也要求您在 Apache Geode 服务器上显式注册 Apache Geode
其中注册并使用 Spring Data for Apache Geode 函数注释的 POJO,如下例所示:PdxSerializer
<bean id="customPdxSerializer" class="x.y.z.gemfire.serialization.pdx.MyCustomPdxSerializer"/>
<gfe:cache pdx-serializer-ref="customPdxSerializeer" pdx-read-serialized="true"/>
或者,为方便起见,您可以使用 Apache Geode 的 ReflectionBasedAutoSerializer
。当然,我们建议您尽可能使用 custom 来维护
对序列化策略进行更精细的控制。PdxSerializer
最后,如果您一般地处理 Function 参数,Spring Data for Apache Geode 会小心避免转换 Function 参数 或作为 Apache Geode 的 PDX 类型之一,如下所示:
@GemfireFunction
public Object genericFunction(String value, Object domainObject, PdxInstanceEnum pdxEnum) {
// ...
}
Spring Data for Apache Geode 当且仅当相应的 application domain types 位于 Classpath 上,并且 Function 注释的 POJO 方法需要它。
有关自定义、组合特定于应用程序的 Apache Geode 以及适当的
基于方法签名的 POJO 函数参数类型处理,请参阅 Spring Data for Apache Geode 的 ClientCacheFunctionExecutionWithPdxIntegrationTest
类。PdxSerializers
12. Apache Lucene 集成
Apache Geode 与 Apache Lucene 集成,让您 使用 Lucene 查询对存储在 Apache Geode 中的数据进行索引和搜索。基于搜索的查询还包括 分页查询结果的能力。
此外,Spring Data for Apache Geode 还增加了对基于 Spring Data Commons 投影基础结构的查询投影的支持。 此功能允许根据应用程序的需要将查询结果投影到一流的应用程序域类型中。
必须先创建 Lucene,然后才能运行任何基于 Lucene 搜索的查询。可以在 Spring (Data for Apache Geode) XML 配置中创建 A,如下所示:Index
LuceneIndex
<gfe:lucene-index id="IndexOne" fields="fieldOne, fieldTwo" region-path="/Example"/>
此外,Apache Lucene 允许为每个字段指定分析器,并且可以按以下示例所示进行配置:
<gfe:lucene-index id="IndexTwo" lucene-service-ref="luceneService" region-path="/AnotherExample">
<gfe:field-analyzers>
<map>
<entry key="fieldOne">
<bean class="example.AnalyzerOne"/>
</entry>
<entry key="fieldTwo">
<bean class="example.AnalyzerTwo"/>
</entry>
</map>
</gfe:field-analyzers>
</gfe:lucene-index>
可以指定为顶级 bean 定义,并使用属性
,如下所示: .Map
ref
<gfe:field-analyzers>
<gfe-field-analyzers ref="refToTopLevelMapBeanDefinition"/>
Spring Data for Apache Geode 的 API 和 SDG 的 XML 命名空间还允许在创建 .
用于配置对象的转换方式
到 Lucene 文档以获取索引。LuceneIndexFactoryBean
LuceneIndex
LuceneSerializer
以下示例演示如何将 an 添加到 :LuceneSerializer
LuceneIndex
<bean id="MyLuceneSerializer" class="example.CustomLuceneSerializer"/>
<gfe:lucene-index id="IndexThree" lucene-service-ref="luceneService" region-path="/YetAnotherExample">
<gfe:lucene-serializer ref="MyLuceneSerializer">
</gfe:lucene-index>
您也可以将 指定为匿名的嵌套 bean 定义,如下所示:LuceneSerializer
<gfe:lucene-index id="IndexThree" lucene-service-ref="luceneService" region-path="/YetAnotherExample">
<gfe:lucene-serializer>
<bean class="example.CustomLuceneSerializer"/>
</gfe:lucene-serializer>
</gfe:lucene-index>
或者,你可以在 Spring Java 配置中声明或定义一个 类,
如下例所示:LuceneIndex
@Configuration
@Bean(name = "Books")
@DependsOn("bookTitleIndex")
PartitionedRegionFactoryBean<Long, Book> booksRegion(GemFireCache gemfireCache) {
PartitionedRegionFactoryBean<Long, Book> peopleRegion =
new PartitionedRegionFactoryBean<>();
peopleRegion.setCache(gemfireCache);
peopleRegion.setClose(false);
peopleRegion.setPersistent(false);
return peopleRegion;
}
@Bean
LuceneIndexFactoryBean bookTitleIndex(GemFireCache gemFireCache,
LuceneSerializer luceneSerializer) {
LuceneIndexFactoryBean luceneIndex = new LuceneIndexFactoryBean();
luceneIndex.setCache(gemFireCache);
luceneIndex.setFields("title");
luceneIndex.setLuceneSerializer(luceneSerializer);
luceneIndex.setRegionPath("/Books");
return luceneIndex;
}
@Bean
CustomLuceneSerializer myLuceneSerialier() {
return new CustomeLuceneSerializer();
}
Apache Geode 的 Apache Lucene 集成和支持存在一些限制。
首先,只能在 Apache Geode 区域上创建 a。LuceneIndex
PARTITION
其次,必须在 Region 之前创建 all。LuceneIndexes
LuceneIndex
为了帮助确保在 Spring 容器中定义的所有声明都是在 Region 之前创建的
SDG 包括 .
你可以使用 XML 配置来注册这个 Spring BeanFactoryPostProcessor 。
只能在使用 SDG XML 配置时使用。
有关 Spring 的更多详细信息,请点击此处。LuceneIndexes org.springframework.data.gemfire.config.support.LuceneIndexRegionBeanFactoryPostProcessor <bean class="org.springframework.data.gemfire.config.support.LuceneIndexRegionBeanFactoryPostProcessor"/> o.s.d.g.config.support.LuceneIndexRegionBeanFactoryPostProcessor BeanFactoryPostProcessors |
这些 Apache Geode 限制可能不适用于未来的版本,这就是原因
SDG API 也直接引用了该地区,
而不仅仅是 Region 路径。LuceneIndexFactoryBean
当您想在稍后使用数据在现有区域上定义 时,这更理想
在应用程序的生命周期内并根据需求。在可能的情况下,SDG 努力遵守
强类型对象。但是,目前必须使用该属性来指定 Region
应用到的。LuceneIndex
regionPath
LuceneIndex
此外,在前面的示例中,请注意 Spring 的注释的存在
在 Region bean 定义上。这将创建从 Region Bean 到 Bean 定义的依赖关系,从而确保在应用它的 Region 之前创建。@DependsOn Books Books bookTitleIndex LuceneIndex LuceneIndex |
现在,一旦我们有了 ,我们就可以执行基于 Lucene 的数据访问操作,例如查询。LuceneIndex
12.1. Lucene 模板数据访问器
Spring Data for Apache Geode 为 Lucene 数据访问操作提供了两个主要模板,具体取决于级别 您的应用程序已准备好处理。
该接口使用 Apache Geode Lucene 类型定义查询操作,
在以下接口定义中定义:LuceneOperations
public interface LuceneOperations {
<K, V> List<LuceneResultStruct<K, V>> query(String query, String defaultField [, int resultLimit]
, String... projectionFields);
<K, V> PageableLuceneQueryResults<K, V> query(String query, String defaultField,
int resultLimit, int pageSize, String... projectionFields);
<K, V> List<LuceneResultStruct<K, V>> query(LuceneQueryProvider queryProvider [, int resultLimit]
, String... projectionFields);
<K, V> PageableLuceneQueryResults<K, V> query(LuceneQueryProvider queryProvider,
int resultLimit, int pageSize, String... projectionFields);
<K> Collection<K> queryForKeys(String query, String defaultField [, int resultLimit]);
<K> Collection<K> queryForKeys(LuceneQueryProvider queryProvider [, int resultLimit]);
<V> Collection<V> queryForValues(String query, String defaultField [, int resultLimit]);
<V> Collection<V> queryForValues(LuceneQueryProvider queryProvider [, int resultLimit]);
}
这表示该参数是可选的。[, int resultLimit] resultLimit |
该接口中的操作与 Apache Geode 的 LuceneQuery 接口提供的操作匹配。
然而,SDG 具有将专有的 Apache Geode 或 Apache Lucene 转化为 Spring 高度一致且富有表现力的 DAO 异常层次结构的附加价值。
特别是因为许多现代数据访问操作涉及多个存储或存储库。LuceneOperations
Exceptions
此外,SDG 的接口可以保护您的应用程序免受接口中断性更改的影响
由基础 Apache Geode 或 Apache Lucene API 引入。LuceneOperations
但是,如果提供仅使用 Apache Geode 和 Apache Lucene 的 Lucene 数据访问对象 (DAO) 会很遗憾
数据类型(如 Apache Geode 的 )。因此,SDG 为您提供了解决这些重要应用程序问题的接口。以下清单显示了
接口定义:LuceneResultStruct
ProjectingLuceneOperations
ProjectingLuceneOperations
public interface ProjectingLuceneOperations {
<T> List<T> query(String query, String defaultField [, int resultLimit], Class<T> projectionType);
<T> Page<T> query(String query, String defaultField, int resultLimit, int pageSize, Class<T> projectionType);
<T> List<T> query(LuceneQueryProvider queryProvider [, int resultLimit], Class<T> projectionType);
<T> Page<T> query(LuceneQueryProvider queryProvider, int resultLimit, int pageSize, Class<T> projectionType);
}
该界面主要使用允许您使用
您的应用程序数据。方法变体接受投影类型,模板应用查询结果
到给定投影类型的实例中。ProjectingLuceneOperations
query
此外,该模板将分页的 Lucene 查询结果包装在 Spring Data Commons 抽象的实例中。相同的投影逻辑仍可应用于页面中的结果,并进行延迟投影
,因为访问集合中的每个页面。Page
举例来说,假设您有一个表示 的类,如下所示:Person
class Person {
Gender gender;
LocalDate birthDate;
String firstName;
String lastName;
...
String getName() {
return String.format("%1$s %2$s", getFirstName(), getLastName());
}
}
此外,您可能有一个接口来表示 人员 ,具体取决于您的应用程序视图
如下:Customers
interface Customer {
String getName()
}
如果我定义以下内容 ...LuceneIndex
@Bean
LuceneIndexFactoryBean personLastNameIndex(GemFireCache gemfireCache) {
LuceneIndexFactoryBean personLastNameIndex =
new LuceneIndexFactoryBean();
personLastNameIndex.setCache(gemfireCache);
personLastNameIndex.setFields("lastName");
personLastNameIndex.setRegionPath("/People");
return personLastNameIndex;
}
然后,您可以将 people 作为对象进行查询,如下所示:Person
List<Person> people = luceneTemplate.query("lastName: D*", "lastName", Person.class);
或者,您可以查询 type 为 的 a ,如下所示:Page
Customer
Page<Customer> customers = luceneTemplate.query("lastName: D*", "lastName", 100, 20, Customer.class);
然后,可以使用 this 来获取结果的各个页面,如下所示:Page
List<Customer> firstPage = customers.getContent();
方便的是,Spring Data Commons 接口还实现了 ,使其变得简单
以迭代内容。Page
java.lang.Iterable<T>
Spring Data Commons Projection 基础结构的唯一限制是投影类型必须是
一个接口。但是,可以扩展提供的 SDC Projection 基础设施,并提供使用 CGLIB 生成代理类作为投影实体的自定义 ProjectionFactory
。
可用于在 Lucene 模板上设置自定义。setProjectionFactory(:ProjectionFactory)
ProjectionFactory
12.2. 注解配置支持
最后,Spring Data for Apache Geode 为 .LuceneIndexes
最终,SDG Lucene 支持将进入 Repository 基础设施扩展
Apache Geode,以便 Lucene 查询可以表示为应用程序接口上的方法,
与今天的 OQL 支持的工作方式大致相同。Repository
不过,同时,如果您想 方便表达 ,您可以直接在
您的 Application Domain 对象,如下例所示:LuceneIndexes
@PartitionRegion("People")
class Person {
Gender gender;
@Index
LocalDate birthDate;
String firstName;
@LuceneIndex;
String lastName;
...
}
要启用此功能,您必须专门将 SDG 的注释配置支持与 和 注释一起使用,如下所示:@EnableEntityDefineRegions
@EnableIndexing
@PeerCacheApplication
@EnableEntityDefinedRegions
@EnableIndexing
class ApplicationConfiguration {
...
}
LuceneIndexes 只能在 Apache Geode 服务器上创建,因为仅适用于
到 Region.LuceneIndexes PARTITION |
鉴于我们之前对类的定义,SDG 注释配置支持会找到
实体类定义,并确定人员存储在名为 “People” 的 Region 中
并且 具有 OQL on 和 on 。Person
Person
PARTITION
Person
Index
birthDate
LuceneIndex
lastName
13. 在 Apache Geode 中引导 Spring ApplicationContext
通常,基于 Spring 的应用程序使用 Spring Data for Apache Geode 的功能来引导 Apache Geode。
通过指定使用 Spring Data for Apache Geode XML 命名空间的元素,单个嵌入式 Apache Geode
peer 实例在与应用程序相同的 JVM 进程中使用默认设置进行创建和初始化。<gfe:cache/>
Cache
但是,有时有必要(可能是您的 IT 组织施加的要求)Apache Geode
完全由提供的 Apache Geode 工具套件管理和操作,可能使用 Gfsh。通过使用 Gfsh,Apache Geode 引导
你的Spring,而不是相反。而不是应用程序服务器或 Java 主类
,Apache Geode 执行引导并托管您的应用程序。ApplicationContext
Apache Geode 不是应用程序服务器。此外,使用此方法也存在限制 其中涉及 Apache Geode 缓存配置。 |
13.1. 使用 Apache Geode 引导从 gfsh 开始的 Spring 上下文
为了在启动 Apache Geode 服务器时在 Apache Geode 中引导 Spring
使用 Gfsh 时,您必须使用 Apache Geode 的 initalizer 功能。
初始化器块可以声明在初始化缓存后启动的应用程序回调
由 Apache Geode 提供。ApplicationContext
初始值设定项在 initializer 元素中声明
通过使用 Apache Geode 的本机的最小片段。要引导 Spring ,
需要一个文件,就像引导需要 Spring XML 配置的最小片段一样
配置了组件扫描的 Spring
(例如 )。cache.xml
ApplicationContext
cache.xml
ApplicationContext
<context:component-scan base-packages="…"/>
幸运的是,框架已经方便地提供了这样的初始化器:SpringContextBootstrappingInitializer
。
以下示例显示了 Apache Geode 文件中此类的典型但最小的配置: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.data.gemfire.support.SpringContextBootstrappingInitializer</class-name>
<parameter name="contextConfigLocations">
<string>classpath:application-context.xml</string>
</parameter>
</initializer>
</cache>
该类遵循类似于 Spring 类的约定,该类用于在 Web 应用程序中引导 Spring,其中配置文件是使用 Servlet 上下文参数指定的。SpringContextBootstrappingInitializer
ContextLoaderListener
ApplicationContext
ApplicationContext
contextConfigLocations
此外,该类还可以与参数
以指定包含适当注释的应用程序组件的基本包的逗号分隔列表。
Spring 容器搜索这些组件以查找和创建 Spring bean 和其他应用程序组件
在 Classpath 中,如下例所示:SpringContextBootstrappingInitializer
basePackages
<?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.data.gemfire.support.SpringContextBootstrappingInitializer</class-name>
<parameter name="basePackages">
<string>org.mycompany.myapp.services,org.mycompany.myapp.dao,...</string>
</parameter>
</initializer>
</cache>
然后,使用正确配置和构造的文件(如前所示)指定为
在 Gfsh 中启动 Apache Geode 服务器时的命令行选项,命令行如下所示:CLASSPATH
cache.xml
gfsh>start server --name=ExampleServer --log-level=config ...
--classpath="/path/to/application/classes.jar:/path/to/spring-data-geode-<major>.<minor>.<maint>.RELEASE.jar"
--cache-xml-file="/path/to/geode/cache.xml"
可以是任何有效的 Spring 配置元数据,包括所有 SDG
XML 命名空间元素。此方法的唯一限制是无法配置 Apache Geode 缓存
通过使用 SDG XML 命名空间。换句话说,没有任何 element 属性
(如 、 、 、 、
和其他)的如果使用,则忽略这些属性。application-context.xml
<gfe:cache/>
cache-xml-location
properties-ref
critical-heap-percentage
pdx-serializer-ref
lock-lease
这样做的原因是 Apache Geode 本身已经在初始化器之前创建并初始化了缓存 被调用。因此,缓存已经存在,并且由于它是 “单例” ,因此无法重新初始化 或扩充其任何配置。
13.2. 懒惰布线 Apache Geode 组件
Spring Data for Apache Geode 已经支持自动装配 Apache Geode 组件(例如 、 等),这些组件由 Apache Geode 使用
SDG 的类,如使用自动连接和注释的配置中所述。但是,这有效
仅当 Spring 是执行引导的一方(即,当 Spring Boot Apache Geode 时)。CacheListeners
CacheLoaders
CacheWriters
cache.xml
WiringDeclarableSupport
当您的 Spring 由 Apache Geode 引导时,这些 Apache Geode 应用程序组件
而被忽视,因为 Spring 还不存在。Spring 没有得到
在 Apache Geode 调用初始值设定项块之前创建,这只发生在所有其他 Apache Geode 之后
组件(缓存、区域等)已创建并初始化。ApplicationContext
ApplicationContext
ApplicationContext
为了解决这个问题,引入了一个新类。这个新类知道
Spring。这个抽象基类背后的意图是,任何实现类都会注册
本身由最终由 Apache Geode 创建的 Spring 容器进行配置,一旦初始化器
被调用。从本质上讲,这为您的 Apache Geode 应用程序组件提供了配置和自动连接的机会
替换为 Spring 容器中定义的 Spring bean。LazyWiringDeclarableSupport
ApplicationContext
为了使 Apache Geode 应用程序组件由 Spring 容器自动连接,您应该创建
一个 Application 类,用于扩展 并注释任何需要
作为 Spring bean 依赖项提供,类似于以下示例:LazyWiringDeclarableSupport
public class UserDataSourceCacheLoader extends LazyWiringDeclarableSupport
implements CacheLoader<String, User> {
@Autowired
private DataSource userDataSource;
...
}
如上面的示例所示,您可能必须(尽管很少)同时定义了一个 Region
和 Apache Geode 中的组件。可能需要访问应用程序
Repository (或者可能是 Spring 中定义的 JDBC )加载到
启动时的 Apache Geode Region。CacheLoader
CacheListener
cache.xml
CacheLoader
DataSource
ApplicationContext
Users
REPLICATE
谨慎
以这种方式将 Apache Geode 和 Spring 容器的不同生命周期混合在一起时要小心。
并非所有用例和场景都受支持。Apache Geode 配置类似于
以下内容(来自 SDG 的测试套件):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">
<region name="Users" refid="REPLICATE">
<region-attributes initial-capacity="101" load-factor="0.85">
<key-constraint>java.lang.String</key-constraint>
<value-constraint>org.springframework.data.gemfire.repository.sample.User</value-constraint>
<cache-loader>
<class-name>
org.springframework.data.gemfire.support.SpringContextBootstrappingInitializerIntegrationTests$UserDataStoreCacheLoader
</class-name>
</cache-loader>
</region-attributes>
</region>
<initializer>
<class-name>org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer</class-name>
<parameter name="basePackages">
<string>org.springframework.data.gemfire.support.sample</string>
</parameter>
</initializer>
</cache>
14. 示例应用程序
示例应用程序现在保存在 Spring Apache Geode 示例存储库中。 |
Spring Data for Apache Geode 项目还包括一个示例应用程序。名为 “Hello World” 的示例应用程序 演示如何在 Spring 应用程序中配置和使用 Apache Geode。在运行时,示例提供 一个 shell,允许您对数据网格运行各种命令。它提供了一个极好的 对于不熟悉基本组件或不熟悉 Spring 和 Apache Geode 概念的开发人员,可以从起点开始。
该示例与发行版捆绑在一起,并且基于 Maven。您可以将其导入到任何 Maven 感知 IDE(例如 Spring Tool Suite)或从命令行运行它们。
14.1. Hello World
“Hello World” 示例应用程序演示了 Spring Data for Apache Geode 项目的核心功能。 它引导 Apache Geode,对其进行配置,对缓存执行任意命令,然后将其关闭 当应用程序退出时。可以同时启动应用程序的多个实例 协同工作,无需任何用户干预即可共享数据。
在 Linux 下运行 如果在启动 Apache Geode 或示例时遇到网络问题,请尝试添加以下内容
system 属性设置为命令行(例如 )。
有关替代(全局)修复(尤其是在 Ubuntu 上),请参阅 SGF-28。java.net.preferIPv4Stack=true -Djava.net.preferIPv4Stack=true |
14.1.1. 启动和停止采样
“Hello World” 示例应用程序设计为独立的 Java 应用程序。它具有一个可以启动的类
从 IDE (在 Eclipse 或 STS 中,通过 ) 或从命令行
通过 Maven 和 .如果 Classpath 设置正确,则还可以直接在生成的工件上使用。main
Run As/Java Application
mvn exec:java
java
要停止示例,请在命令行中键入或按 以停止 JVM 并关闭
Spring 容器。exit
Ctrl+C
14.1.2. 使用示例
启动后,该示例将创建一个共享数据网格,并允许您对其发出命令。 输出应类似于以下内容:
INFO: Created {data-store-name} Cache [Spring {data-store-name} World] v. X.Y.Z
INFO: Created new cache region [myWorld]
INFO: Member xxxxxx:50694/51611 connecting to region [myWorld]
Hello World!
Want to interact with the world ? ...
Supported commands are:
get <key> - retrieves an entry (by key) from the grid
put <key> <value> - puts a new entry into the grid
remove <key> - removes an entry (by key) from the grid
...
例如,要向网格添加新项,可以使用以下命令:
-> Bold Section qName:emphasis level:5, chunks:[put 1 unu] attrs:[role:bold]
INFO: Added [1=unu] to the cache
null
-> Bold Section qName:emphasis level:5, chunks:[put 1 one] attrs:[role:bold]
INFO: Updated [1] from [unu] to [one]
unu
-> Bold Section qName:emphasis level:5, chunks:[size] attrs:[role:bold]
1
-> Bold Section qName:emphasis level:5, chunks:[put 2 two] attrs:[role:bold]
INFO: Added [2=two] to the cache
null
-> Bold Section qName:emphasis level:5, chunks:[size] attrs:[role:bold]
2
可以同时运行多个实例。启动后,新 VM 会自动看到现有区域 及其信息,如下例所示:
INFO: Connected to Distributed System ['Spring {data-store-name} World'=xxxx:56218/49320@yyyyy]
Hello World!
...
-> Bold Section qName:emphasis level:5, chunks:[size] attrs:[role:bold]
2
-> Bold Section qName:emphasis level:5, chunks:[map] attrs:[role:bold]
[2=two] [1=one]
-> Bold Section qName:emphasis level:5, chunks:[query length = 3] attrs:[role:bold]
[one, two]
我们鼓励您尝试该示例,根据需要启动(和停止)任意数量的实例,并在一个实例中运行各种命令 看看其他人的反应。要保留数据,至少需要一个实例始终处于活动状态。如果所有实例 关闭,则网格数据将被完全销毁。
14.1.3. Hello World 示例解释
“Hello World” 示例使用 Spring XML 和注解进行配置。初始引导配置为 ,其中包括文件中定义的高速缓存配置
并对 Spring 组件执行 Classpath 组件扫描。app-context.xml
cache-context.xml
缓存配置定义 Apache Geode 缓存、一个区域,为了便于说明,还定义了一个充当记录器的 a。CacheListener
主要的 bean 是 和 ,它们依赖于 与 交互
分布式结构。这两个类都使用 Comments 来定义它们的依赖关系和生命周期回调。HelloWorld
CommandProcessor
GemfireTemplate