是否可以在一个 JVM 中启动 PIvotal GemFire 服务器、定位器和客户端?
Is it possible to start a PIvotal GemFire Server, Locator and Client in one JVM?
我想使用 Spring Boot.
在单个 JVM 中启动 Pivotal GemFire 服务器、定位器和客户端
服务器和定位器启动正常(我在服务器gemfire.properties
中使用了"start-locator")。
但是,当我尝试启动连接到定位器的客户端时,出现异常:
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 是否有一些限制,以至于我无法通过这种方式连接?
是的,这是已知的限制,每个 JVM 的缓存不能超过一个(具有嵌入式定位器的服务器除外)。
干杯。
简而言之,不,您不能在同一个 JVM(或 Java 应用程序进程)中拥有对等 Cache
实例(带有嵌入式定位器)和 ClientCache
实例。
在 Apache Geode/Pivotal GemFire 中,缓存实例,无论是对等 Cache
(分布式系统或集群的对等成员)还是 ClientCache
实例,都是一个单例。
因此,每个 JVM 只能有 1 个 GemFire 缓存实例(或者更专业地说,ClassLoader
,但我们不会走那条丑陋的路)。
无论如何,当缓存实例已经存在时,任何后续的缓存创建尝试都会说,使用 GemFire 的 o.a.g.cache.client.ClientCacheFactory
(when a peer Cache
instance, created by the o.a.g.cache.CacheFactory
创建的 ClientCache
实例已经存在)将导致检查 GemFire 几乎在哪里期望缓存实例相同(即存在对等 Cache
,因此最好尝试创建相同的(通过配置,无论如何)"peer" Cache
实例)。显然,ClientCache
实例将不会具有与对等 Cache
实例相同的(分布式系统)配置,因此失败。
你可以看到开始的逻辑here. The first thing that a cache instance creation does is check and lookup an existing cache instance. A ClientCache
instance cannot have the locators
and mcast-port
properties set (here);如果是,则会导致错误(通常是客户端和对等缓存实例之间的另一个差异,特别是 locators
属性)。
如果现有实例没有关闭或正在关闭,那么它将validate the configuration。创建另一个缓存实例的唯一方法几乎是当它是同一个实例时。配置验证非常广泛。
在 Apache Geode 开发列表中讨论过更改 GemFire 缓存实例的“Singletone”性质,但没有讨论在这方面已经实现,但因为它是一项重大任务,部分原因是 static (Client)CacheFactory.getAnyInstance()
(或更糟,GemFireCacheImpl.getInstance()
;对等和客户端缓存实例共享相同的基础 class... org.apache.geode.cache.internal.GemFireCacheImpl
) 在整个代码库中被广泛使用,而不是将缓存实例传递给依赖的 GemFire objects/components,例如像 地区.
无论如何,很抱歉这个回答不能给您任何安慰。
但是,我经常创建 2 个单独的 Spring Boot 应用程序(classes)来配置和 bootstrap 两者都是 client and 1 or more servers, 个人.
在服务器上,我什至使用 Spring profile to active a Locator/Manager in a single server instance so that I can form a small cluster (with the embedded Locator) and Manager 这样我也可以使用 Gfsh.
连接到这个集群
因此,您可以使用相同的 class 来启动一个小型集群。第一个服务器将声明为:
$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;酷!) .
我想使用 Spring Boot.
在单个 JVM 中启动 Pivotal GemFire 服务器、定位器和客户端服务器和定位器启动正常(我在服务器gemfire.properties
中使用了"start-locator")。
但是,当我尝试启动连接到定位器的客户端时,出现异常:
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 是否有一些限制,以至于我无法通过这种方式连接?
是的,这是已知的限制,每个 JVM 的缓存不能超过一个(具有嵌入式定位器的服务器除外)。 干杯。
简而言之,不,您不能在同一个 JVM(或 Java 应用程序进程)中拥有对等 Cache
实例(带有嵌入式定位器)和 ClientCache
实例。
在 Apache Geode/Pivotal GemFire 中,缓存实例,无论是对等 Cache
(分布式系统或集群的对等成员)还是 ClientCache
实例,都是一个单例。
因此,每个 JVM 只能有 1 个 GemFire 缓存实例(或者更专业地说,ClassLoader
,但我们不会走那条丑陋的路)。
无论如何,当缓存实例已经存在时,任何后续的缓存创建尝试都会说,使用 GemFire 的 o.a.g.cache.client.ClientCacheFactory
(when a peer Cache
instance, created by the o.a.g.cache.CacheFactory
创建的 ClientCache
实例已经存在)将导致检查 GemFire 几乎在哪里期望缓存实例相同(即存在对等 Cache
,因此最好尝试创建相同的(通过配置,无论如何)"peer" Cache
实例)。显然,ClientCache
实例将不会具有与对等 Cache
实例相同的(分布式系统)配置,因此失败。
你可以看到开始的逻辑here. The first thing that a cache instance creation does is check and lookup an existing cache instance. A ClientCache
instance cannot have the locators
and mcast-port
properties set (here);如果是,则会导致错误(通常是客户端和对等缓存实例之间的另一个差异,特别是 locators
属性)。
如果现有实例没有关闭或正在关闭,那么它将validate the configuration。创建另一个缓存实例的唯一方法几乎是当它是同一个实例时。配置验证非常广泛。
在 Apache Geode 开发列表中讨论过更改 GemFire 缓存实例的“Singletone”性质,但没有讨论在这方面已经实现,但因为它是一项重大任务,部分原因是 static (Client)CacheFactory.getAnyInstance()
(或更糟,GemFireCacheImpl.getInstance()
;对等和客户端缓存实例共享相同的基础 class... org.apache.geode.cache.internal.GemFireCacheImpl
) 在整个代码库中被广泛使用,而不是将缓存实例传递给依赖的 GemFire objects/components,例如像 地区.
无论如何,很抱歉这个回答不能给您任何安慰。
但是,我经常创建 2 个单独的 Spring Boot 应用程序(classes)来配置和 bootstrap 两者都是 client and 1 or more servers, 个人.
在服务器上,我什至使用 Spring profile to active a Locator/Manager in a single server instance so that I can form a small cluster (with the embedded Locator) and Manager 这样我也可以使用 Gfsh.
连接到这个集群因此,您可以使用相同的 class 来启动一个小型集群。第一个服务器将声明为:
$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;酷!) .