gemfire - 是否可以在一个 JVM 中启动 Pivotal GemFire 服务器、定位器和客户端?
问题描述
我想使用Spring Boot在单个 JVM 中启动 Pivotal GemFire 服务器、定位器和客户端。
服务器和定位器启动正常(我在服务器中使用了“start-locator” gemfire.properties
)。
但是,当我尝试启动连接到定位器的客户端时,出现异常:
java.lang.IllegalStateException: A connection to a distributed system already exists in this VM.
at com.gemstone.gemfire.distributed.internal.InternalDistributedSystem.validateSameProperties(InternalDistributedSystem.java:3054)
at com.gemstone.gemfire.distributed.DistributedSystem.connect(DistributedSystem.java:1642)
并且,在异常中,服务器用于连接定位器的现有属性被打印出来。
这是客户端的代码:
@Bean(name = "GemfireClientProperties")
Properties gemfireClientProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("mcast-port", "0");
gemfireProperties.setProperty("log-level", "config");
return gemfireProperties;
}
@Bean(name = "GemfireClientPool")
PoolFactoryBean gemfireClientPool() {
PoolFactoryBean gemfirePool = new PoolFactoryBean();
gemfirePool.setRetryAttempts(1);
gemfirePool.setLocators(Collections.singletonList(new ConnectionEndpoint("localhost", 17202)));
return gemfirePool;
}
@Bean(name = "clientCache")
ClientCache clientCache(@Qualifier("GemfireClientProperties") Properties gemfireClientProperties) {
ClientCacheFactory clientCacheFactory = new ClientCacheFactory(gemfireClientProperties);
return clientCacheFactory.create();
}
Pivotal GemFire 版本是 8.2.5。
我在debug模式下跟踪,在clientCacheFactory.create()行抛出异常,在方法中,传入的properties文件是正确的,只有2个entry。
Pivotal GemFire 是否有一些限制,以至于我无法以这种方式连接?
解决方案
简而言之,不,您不能在同一个 JVM(或 Java 应用程序进程)中拥有对等Cache
实例(带有嵌入式定位器)和实例。ClientCache
在 Apache Geode/Pivotal GemFire 中,缓存实例,无论是对等Cache
点(分布式系统或集群的对等成员)还是ClientCache
实例,都是Singleton。因此,每个 JVM 只能有 1 个 GemFire 缓存实例(或者从技术上讲ClassLoader
,,但我们不会走那条丑陋的道路)。
无论如何,当缓存实例已经存在时,任何后续的缓存创建尝试都会说,ClientCache
使用 GemFire 的实例创建o.a.g.cache.client.ClientCacheFactory
(当Cache
由 . 创建的对等实例o.a.g.cache.CacheFactory
已经存在时)将导致检查 GemFire 几乎期望缓存实例在相同(即Cache
存在对等点,因此最好尝试创建相同的(无论如何通过配置)“对等点”Cache
实例)。显然,一个ClientCache
实例不会具有与对等Cache
实例相同的(分布式系统)配置,因此会失败。
你可以看到从这里开始的逻辑。创建缓存实例的第一件事是检查和查找现有的缓存实例。ClientCache
实例不能设置locators
andmcast-port
属性(此处);如果是,则会导致错误(通常是客户端和对等缓存实例之间的另一个差异,特别是对于locators
属性)。
如果现有实例没有关闭或关闭,那么它将验证配置。几乎创建另一个缓存实例的唯一方法是当它是同一个实例时。配置验证非常广泛。
在 Apache Geode 开发列表中已经讨论过改变 GemFire 缓存实例的“ Singletone ”性质,但在这方面还没有实现,因为它是一项重大任务,部分原因是静态 (Client)CacheFactory.getAnyInstance()
(或更糟糕的是,GemFireCacheImpl.getInstance()
对等和客户端缓存实例共享相同的基类... org.apache.geode.cache.internal.GemFireCacheImpl
)在整个代码库中被广泛使用,而不是将缓存实例传递给依赖的 GemFire 对象/组件,例如Regions。
无论如何,对不起,这个答案并没有给你任何安慰。
但是,我经常创建 2 个单独的Spring Boot应用程序(类)来分别配置和引导一个客户端和 1 个或多个服务器。
在服务器上,我什至使用Spring 配置文件在单个服务器实例中激活 Locator/Manager ,这样我就可以形成一个小型集群(带有嵌入式 Locator)和Manager,这样我也可以使用Gfsh连接到这个集群。
因此,您可以使用同一个类来启动一个小型集群。第一台服务器将声明为:
$java -cp ... -Dspring.profiles.active=locator-manager example.app.geode.cache.server. GeodeServerApplication
加入第一台服务器的子序列服务器将使用以下命令启动:
$java -cp ... -Dspring.data.gemfire.name=ServerTwo -Dspring.data.gemfire.cache.server.port=42424 example.app.geode.cache.server. GeodeServerApplication
注意,您必须非常注意成员名称(使用该spring.data.gemfire.name
属性,因为 GemFire 要求对等成员名称是唯一的)并且您必须更改CacheServer
端口(缓存客户端用于连接;因此该spring.data.gemfire.cache.server.port
属性)否则您将点击 a java.net.BindException
,因为默认情况下CacheServer
监听端口40404
。
众所周知的 SDG(系统)属性是改变配置和运行小型集群的最简单方法(甚至没有Gfsh;太酷了!)。
推荐阅读
- django - Docker-compose up with conda 无法正常工作
- python-3.x - python中的谷歌地图距离矩阵例程
- javascript - 简单滚动到 ID 不适用于移动设备
- angular - JqxGrid在Angular中显示未调用的数据
- vim - 从gvim中的行首删除前2个空格
- asp.net - 如何在Gridview中将行合并到行中
- ios - SKPaymentQueue.defaultQueue.storefront.countryCode 不返回正确的国家代码
- mips - MIPS:什么指令从内存中获取数据?
- sql-server - DOMAIN\MACHINENAME$ 登录失败
- php - mysql查询需要1分钟以上才能完成