我想在带有Spring Boot的单个JVM中启动一个Pivotal GemFire服务器,定位器和客户端。
服务器和定位器启动正常(我在服务器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。
我在调试模式下跟踪,异常在 clientCacheFactory.create(( 行抛出,并且在方法中,传入的属性文件是正确的,只有 2 个条目。
Pivotal GemFire 是否有一些限制,以至于我无法以这种方式连接?
简而言之,NO,您不能在同一 JVM(或 Java 应用程序进程(中拥有对等Cache
实例(带有嵌入式定位器(和ClientCache
实例。
在Apache Geode/Pivotal GemFire中,缓存实例,无论是对等Cache
(分布式系统或集群的对等成员(还是ClientCache
实例,都是单例。 因此,每个 JVM 只能有 1 个 GemFire 缓存实例(或者更技术地说,ClassLoader
,但我们不会走那条丑陋的道路(。
无论如何,当缓存实例已经存在时,任何后续的缓存创建尝试都说,使用 GemFire 的o.a.g.cache.client.ClientCacheFactory
创建ClientCache
实例(当由o.a.g.cache.CacheFactory
创建的对等Cache
实例已经存在时(将导致检查 GemFire 几乎期望缓存实例相同(即存在对等Cache
, 因此,最好尝试创建相同的(无论如何通过配置("对等"Cache
实例(。 显然,ClientCache
实例不会具有与对等Cache
实例相同的(分布式系统(配置,并且会失败。
您可以看到从这里开始的逻辑。 创建缓存实例要做的第一件事是检查和查找现有缓存实例。ClientCache
实例不能设置locators
和mcast-port
属性(此处(;如果是,则会导致错误(通常是客户端和对等缓存实例之间的另一个差异,特别是对于locators
属性(。
如果现有实例未关闭或关闭,则它将验证配置。 创建另一个缓存实例的唯一方法是当它是同一个实例时。 配置验证非常广泛。
关于更改 Apache Geode 开发列表中 GemFire 缓存实例的">单调"性质的讨论已经存在,但在这方面还没有实现,因为它是一项重大任务,部分原因是静态(Client)CacheFactory.getAnyInstance()
(或者更糟的是,GemFireCacheImpl.getInstance()
;对等和客户端缓存实例共享相同的基类......org.apache.geode.cache.internal.GemFireCacheImpl
(在整个代码库中被广泛使用,而不是将缓存实例传递给依赖的 GemFire 对象/组件,例如区域。
无论如何,对不起,这个答案并没有给你任何缓解。
但是,我经常创建 2 个单独的Spring 引导应用程序(类(来分别配置和引导客户端和 1 台或多台服务器。
在服务器上,我甚至使用 Spring 配置文件在单个服务器实例中激活定位器/管理器,以便我可以形成一个小集群(带有嵌入式定位器(和管理器,以便我也可以使用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
属性(,否则您将遇到java.net.BindException
,因为默认情况下CacheServer
侦听端口40404
。
众所周知的 SDG(系统(属性是改变配置和运行小型集群的最简单方法(甚至没有Gfsh;很酷!
是的,这是已知的限制,每个 JVM 不能有多个缓存(具有嵌入式定位器的服务器除外(。 干杯。