首页 > 解决方案 > Spring Data Geode Region 有本地作用域,无法监听远程 Region 事件

问题描述

我正在将 Spring Data for Apache Geode 用于使用远程 Apache Geode 服务器的 Spring Boot 应用程序。要设置本地区域,我使用的@Configuration类如下:

@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这样,以便稍后在订阅区域中的事件时,本地订阅将看到服务器区域事件。

我已经设置subscriptionEnabled=TRUE并且@ClientCacheApplication我正在尝试设置

clientRegionShortcut = ClientRegionShortcut.CACHING_PROXY 

我不知道在哪里做这个。我已经尝试了@EnableClusterDefinedRegions注释,但该区域仍被设置为本地。

如果我尝试从它创建一个区域工厂,GemFireCache它会给我一个错误,即该方法createClientRegionFactory(ClientRegionShortcut)对于 type 是“未定义的” GemFireCache

谢谢

标签: geodespring-data-gemfirespring-boot-data-geode

解决方案


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

  @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 Data for Apache Geode (SDG) 包含特定的Spring FactoryBeans来做同样的事情。例如,可持续发展目标ClientRegionFactoryBean

您将ClientRegionFactoryBeanSpring应用程序配置中使用如下:

@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] Regions, Indexes, DiskStores, GatewayReceivers,GatewaySenders等。

这些FactoryBeans对于确保 Geode 对象(例如)的“生命周期”与Spring容器Region(s)的生命周期正确同步是必不可少的。通过放弃使用 SDG,您实际上忽略了Spring容器和自定义(框架)提供的生命周期协调,因此在Spring配置中直接使用 Geode 的 API 时负责 Geode 对象本身的生命周期。这是 SDG 存在的主要原因之一。FactoryBeansFactoryBeans

“客户端”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 注释的配置模型文档

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

例如,如果您在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 GeodeClientCache应用程序将有 2 个Spring配置的客户端区域 bean,其名称均为“Example”和“AnotherExample”,类型均为CACHING_PROXY.

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

无论如何,我希望这有意义并有所帮助!

干杯!


推荐阅读