Spring Data Geode Region 具有本地作用域,无法监听远程 Region 事件

Spring Data Geode Region has local scope and cannot listen to remote Region events

我正在为使用远程 Apache Geode 服务器的 Spring 启动应用程序使用 Apache Geode 的 Spring 数据。要设置本地区域,我正在使用 @Configuration class,例如:

@Configuration
public class GeodeConfig {

  public static Region<String, String> myRegion;

  @Bean("setupMyRegion")
  public Region<String, String> setupMyRegion(GemFireCache cache) {

    Region<String, String> r = cache.getRegion("myRegion");
    myRegion = r;

    return r;
  }
}

这使我能够在区域中放置和获取数据。

当我注册订阅密钥时,订阅设置为 scope=LOCAL,如下所示:

org.apach.geode.inter.cache.LocalRegion 4439 logKeys: org.apache.geode.internal.cache.LocalRegion[path='/myRegion';scope=LOCAL';dataPolicy=NORMAL; concurrencyChecksEnabled] refreshEntriesFromServerKeys count=1 policy=KEYS_VALUES

我想我想将其设置为 CACHING_PROXY 以便稍后在订阅该区域中的事件时,本地订阅将看到服务器区域事件。

我已经为 @ClientCacheApplication 设置了 subscriptionEnabled=TRUE,我正在尝试设置

clientRegionShortcut = ClientRegionShortcut.CACHING_PROXY 

我不知道在哪里做这个。我试过 @EnableClusterDefinedRegions 注释,但区域仍设置为本地。

如果我尝试从 GemFireCache 创建区域工厂,它会给我一个错误,即方法 createClientRegionFactory(ClientRegionShortcut) 是类型 GemFireCache 的 "undefined"。

谢谢

通常,直接使用 Apache Geode API 在 Spring 上下文中配置 beans 是一种不好的做法。例如...

  @Bean("MyRegion")
  public Region<String, Object> myRegion(GemFireCache cache) {
    return cache.getRegion("myRegion");
  }

或使用:

  @Bean("MyRegion")
  public Region<String, Object> myRegion(ClientCache clientCache) {
    return clientCache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY)
      .create("MyRegion");
  }

以上两种方法推荐!

Spring Apache Geode (SDG) 的数据包含特定的 Spring FactoryBeans to do the same thing. For instance, the SDG ClientRegionFactoryBean

您将在 Spring 应用程序配置中使用 ClientRegionFactoryBean,如下所示:

@Bean("MyRegion")
ClientRegionFactoryBean<String, Object> myRegion(ClientCache clientCache) {

  ClientRegionFactoryBean<String, Object> myRegion = 
    new ClientRegionFactoryBean<>();

  myRegion.setCache(clientCache);
  myRegion.setShortcut(ClientRegionShortcut.CACHING_PROXY);

  return myRegion;
}

不同类型的 Geode 对象有 SDG FactoryBeans,例如 [client] RegionsIndexesDiskStoresGatewayReceiversGatewaySenders,等等

这些 FactoryBeans 对于确保 Geode 对象(例如 Region(s))的 "lifecycle" 正确同步到 [=124] 的生命周期至关重要=]容器。通过放弃使用 SDG 的 FactoryBeans,您实际上忽略了 Spring 容器和自定义(框架)FactoryBeans 提供的生命周期协调,并且因此,在 Spring 配置中直接使用 Geode 的 API 时,负责 Geode 对象本身的生命周期。这是 SDG 存在的主要原因之一。

A "client" Region 必须是 *PROXY(例如 PROXYCACHING_PROXY)才能启用订阅并从服务器接收有趣的事件那个地区。这是因为 Geode 集群(服务器)在连接时为客户端维护一个订阅队列,其中包含客户端表示有兴趣接收的事件。

对于 *PROXY 客户端 Regions,这也意味着客户端 Region 必须有一个相应的服务器端,同名的对等缓存 Region

您可以通过使用 SDG 的基于注释的配置模型,特别是 @EnableEntityDefinedRegions@EnableCachingDefinedRegions.

来简化一般区域的创建,特别是客户端区域的创建

例如:

@ClientCacheApplication(subscriptionsEnabled = true)
@EnableEntityDefinedRegions(basePackageClasses = SomeEntity.class, 
  clientRegionShortcut = ClientRegionShortcut.CACHING_PROXY)
class GeodeConfiguration {
  ...
}

当然,这里假设你已经定义了应用领域模型实体类,比如:

package example.app.model;

import ...;

@Region("MyRegion")
class SomeEntity {

  @Id
  private Long id;

  ...
}

ClientRegionFactoryBean 将相应地键入:ClientRegionFactoryBean<Long, SomeEntity>

查看基于 SDG 注释的配置模型 documentation for more details, and specifically Annotation configuration covering Region definitions

@EnableClusterDefinedRegions 注释为客户端连接的所有现有服务器端(集群)Regions 定义客户端Regions

比如在Gfsh中启动集群如下:

gfsh>start locator --name=MyLocator ...

gfsh>start server --name=MyServer ...

gfsh>create region --name=Example --type=PARTITION

gfsh>create region --name=AnotherExample --type=REPLICATE

然后使用以下 Geode 配置将 Spring Boot、Apache Geode ClientCache 应用程序连接到此集群:

@ClientCacheApplication
@EnableClusterDefinedRegions(clientRegionShortcut = 
  ClientRegionShortcut.CACHING_PROXY)
class GeodeConfiguration {
  ...
}

然后 Spring Boot,Apache Geode ClientCache 应用程序将有 2 Spring配置了名称为 "Example" 和 "AnotherExample" 的客户端区域 bean,类型均为 CACHING_PROXY.

如果集群中目前没有服务器端区域,则 @EnableClusterDefinedRegions 不会定义任何客户端区域。

无论如何,我希望这是有道理的并且有所帮助!

干杯!

这里的主要问题是我想在其中使用 Geode 区域的 class 没有在 Spring 容器中注册,因为我使用 new 来使用 class 而不是对 Spring 使用 @Autowired 注释。这意味着当我使用 @Resource(name = "Example") private Region<Object, Object> example 根据@JohnBlum 的回答设置 Geode 区域时,自动装配仍在生成空对象。

此外,我想使用这些区域的 class 在我的 @ComponentScan 之外的另一个包中,因此我不得不修改 @ComponentScan 以找到该包。

事情是,一旦我完成了这些配置并正确设置了 @EnableClusterDefinedRegions(一旦你知道如何操作就真的很容易!!)我可以放置和获取区域,

register interests 的问题是我的 application.properties

spring.data.gemfire.cache.client.durable-client-id=myListener

当我删除 属性 时,CacheListenerAdapter 开始从服务器接收事件!