Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot Spring数据GemFire和GemFire缓存与启动时的Spring引导之间的松耦合_Spring Boot_Gemfire_Spring Data Gemfire - Fatal编程技术网

Spring boot Spring数据GemFire和GemFire缓存与启动时的Spring引导之间的松耦合

Spring boot Spring数据GemFire和GemFire缓存与启动时的Spring引导之间的松耦合,spring-boot,gemfire,spring-data-gemfire,Spring Boot,Gemfire,Spring Data Gemfire,我们有一个GemFire集群,它有两个定位器和两个缓存节点 我们的Spring Boot服务将作为客户端连接到GemFire群集,并具有客户端区域。我们正在使用SpringDataGemFire引导具有GemFireXMLConfig和属性的客户端区域 当GemFire群集关闭时,Spring引导服务无法启动,因为它无法满足GemFire区域依赖关系(unsatifiedDependecyException) 有没有一种方法可以将Spring Boot启动和GemFire松散耦合 本质上,我们希

我们有一个GemFire集群,它有两个定位器和两个缓存节点

我们的Spring Boot服务将作为客户端连接到GemFire群集,并具有客户端区域。我们正在使用SpringDataGemFire引导具有GemFireXMLConfig和属性的客户端区域

当GemFire群集关闭时,Spring引导服务无法启动,因为它无法满足GemFire区域依赖关系(
unsatifiedDependecyException

有没有一种方法可以将Spring Boot启动和GemFire松散耦合

本质上,我们希望Spring引导服务即使在GemFire集群关闭时也能启动

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:gfe="http://www.springframework.org/schema/gemfire"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
                http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

   <util:properties id="gemfireProperties" location="classpath:gemfire.properties"/>

     <bean id="autoSerializer" class="org.apache.geode.pdx.ReflectionBasedAutoSerializer">
        </bean>

    <gfe:client-cache pdx-serializer-ref="autoSerializer" pdx-read-serialized="true" pool-name="POOL" properties-ref="gemfireProperties"/>

<gfe:pool id="POOL" subscription-enabled="true" >
     <gfe:locator host="${gf.cache.locator1}" port="${gf.cache.locator1.port}"/>
     <gfe:locator host="${gf.cache.locator2}" port="${gf.cache.locator2.port}"/>
 </gfe:pool>

<gfe:client-region id="xyz" shortcut="CACHING_PROXY" pool-name="POOL">
    <gfe:regex-interest pattern=".*" result-policy="KEYS_VALUES"/>
    </gfe:client-region>


</beans>


@ImportResource({"classpath:gemfire-config.xml"})

@ImportResource({“classpath:gemfire config.xml})

您所要求的是可以做到的,但没有一些自定义代码是不行的

而且,与一起使用要比使用或(我读对了吗?您(可能)正在使用…)容易得多

不过,首先,我想知道您使用GemFire的能力是什么,您的Spring Boot应用程序(或服务)不严格要求GemFire运行(服务器端)才能正常工作,这样您的Spring Boot应用程序/服务仍然可以启动并满足您客户的需要

显然,在本例中,Pivotal GemFire没有被用作Spring引导服务的记录系统(SOR)。然而,如果您只是简单地将Pivotal GemFire用于“缓存”,那么这是有意义的,也许是作为Spring缓存抽象中的(或)一个?这就是你在做的吗

无论如何

我认为最好的方法是用一个,;-)的例子来证明这一点

我编写了一个简单的集成测试,
ResilientClientServerIntegrationTests
,其中的功能是作为一个应用程序(将
put
/
get
数据发送到一个
区域,即“示例”),并演示它可以“有条件地”在客户机/服务器和仅本地模式之间切换

测试(或基于Spring的应用程序)在客户机/服务器和仅本地模式之间切换的关键是实现一个,然后在应用程序(客户机)配置类上使用
@Conditional
Spring注释,如图所示

但是,在服务器集群不可用时,我没有完全禁用GemFire客户端,而是简单地将应用程序(也称为测试)切换到仅在本地模式下运行的客户端

我专门通过客户端区域执行此操作,以使用
ClientRegionShortcut.LOCAL
设置。然后在配置客户端GemFire对象时使用此设置,例如在“示例”客户端区域上,请参阅,然后

现在,如果我运行这个测试,它将通过我是否有GemFire集群(服务器)运行,因为如果没有可用的GemFire集群,那么它将只在仅本地模式下运行

如果GemFire集群已提供给应用程序,那么它也将按预期工作,并且在不更改任何客户端应用程序代码或配置的情况下使用集群,呵呵

作为示例,假设我使用Gfsh启动一个集群,如下所示

$ echo $GEMFIRE
/Users/jblum/pivdev/apache-geode-1.6.0

$ gfsh
    _________________________     __
   / _____/ ______/ ______/ /____/ /
  / /  __/ /___  /_____  / _____  / 
 / /__/ / ____/  _____/ / /    / /  
/______/_/      /______/_/    /_/    1.6.0

Monitor and Manage Apache Geode
gfsh>


gfsh>start locator --name=LocatorOne --log-level=config
Starting a Geode Locator in /Users/jblum/pivdev/lab/LocatorOne...
.....
Locator in /Users/jblum/pivdev/lab/LocatorOne on 10.99.199.24[10334] as LocatorOne is currently online.
Process ID: 9737
Uptime: 3 seconds
Geode Version: 1.6.0
Java Version: 1.8.0_192
Log File: /Users/jblum/pivdev/lab/LocatorOne/LocatorOne.log
JVM Arguments: -Dgemfire.enable-cluster-configuration=true -Dgemfire.load-cluster-configuration-from-dir=false -Dgemfire.log-level=config -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806
Class-Path: /Users/jblum/pivdev/apache-geode-1.6.0/lib/geode-core-1.6.0.jar:/Users/jblum/pivdev/apache-geode-1.6.0/lib/geode-dependencies.jar

Successfully connected to: JMX Manager [host=10.99.199.24, port=1099]

Cluster configuration service is up and running.


gfsh>start server --name=ServerOne --log-level=config
Starting a Geode Server in /Users/jblum/pivdev/lab/ServerOne...
....
Server in /Users/jblum/pivdev/lab/ServerOne on 10.99.199.24[40404] as ServerOne is currently online.
Process ID: 9780
Uptime: 3 seconds
Geode Version: 1.6.0
Java Version: 1.8.0_192
Log File: /Users/jblum/pivdev/lab/ServerOne/ServerOne.log
JVM Arguments: -Dgemfire.default.locators=10.99.199.24[10334] -Dgemfire.start-dev-rest-api=false -Dgemfire.use-cluster-configuration=true -Dgemfire.log-level=config -XX:OnOutOfMemoryError=kill -KILL %p -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806
Class-Path: /Users/jblum/pivdev/apache-geode-1.6.0/lib/geode-core-1.6.0.jar:/Users/jblum/pivdev/apache-geode-1.6.0/lib/geode-dependencies.jar


gfsh>list members
   Name    | Id
---------- | ----------------------------------------------------------------
LocatorOne | 10.99.199.24(LocatorOne:9737:locator)<ec><v0>:1024 [Coordinator]
ServerOne  | 10.99.199.24(ServerOne:9780)<v1>:1025


gfsh>create region --name=Example --type=PARTITION
 Member   | Status
--------- | ----------------------------------------
ServerOne | Region "/Example" created on "ServerOne"


gfsh>list regions
List of regions
---------------
Example


gfsh>describe region --name=/Example
..........................................................
Name            : Example
Data Policy     : partition
Hosting Members : ServerOne

Non-Default Attributes Shared By Hosting Members  

 Type  |    Name     | Value
------ | ----------- | ---------
Region | size        | 0
       | data-policy | PARTITION

酷!成功了!我们的“示例”区域包含由测试/应用程序放置的条目

当然,如果我停止集群并重新运行测试,它仍然会通过,因为代码/配置会智能地切换回仅本地模式,而无需执行任何操作

如果您不清楚/不确定测试正在执行我所说的操作,那么只需注释出负责A)确定GemFire群集是否可用以及B)决定如何处理群集不可用时的情况的选项,在本例中,我们只需简单地说明

但是,通过注释该条件,您将看到类似于以下内容的异常:

org.apache.geode.cache.client.NoAvailableLocatorsException: Unable to connect to any locators in the list [LocatorAddress [socketInetAddress=localhost/127.0.0.1:10334, hostname=localhost, isIpString=false]]

    at org.apache.geode.cache.client.internal.AutoConnectionSourceImpl.findServer(AutoConnectionSourceImpl.java:158)
    at org.apache.geode.cache.client.internal.ConnectionFactoryImpl.createClientToServerConnection(ConnectionFactoryImpl.java:234)
    at org.apache.geode.cache.client.internal.pooling.ConnectionManagerImpl.borrowConnection(ConnectionManagerImpl.java:242)
    at org.apache.geode.cache.client.internal.OpExecutorImpl.execute(OpExecutorImpl.java:148)
    at org.apache.geode.cache.client.internal.OpExecutorImpl.execute(OpExecutorImpl.java:127)
    at org.apache.geode.cache.client.internal.PoolImpl.execute(PoolImpl.java:782)
    at org.apache.geode.cache.client.internal.PutOp.execute(PutOp.java:91)
    at org.apache.geode.cache.client.internal.ServerRegionProxy.put(ServerRegionProxy.java:159)
    at org.apache.geode.internal.cache.LocalRegion.serverPut(LocalRegion.java:3010)
    at org.apache.geode.internal.cache.LocalRegion.cacheWriteBeforePut(LocalRegion.java:3121)
    at org.apache.geode.internal.cache.ProxyRegionMap.basicPut(ProxyRegionMap.java:239)
    at org.apache.geode.internal.cache.LocalRegion.virtualPut(LocalRegion.java:5631)
    at org.apache.geode.internal.cache.LocalRegionDataView.putEntry(LocalRegionDataView.java:152)
    at org.apache.geode.internal.cache.LocalRegion.basicPut(LocalRegion.java:5059)
    at org.apache.geode.internal.cache.LocalRegion.validatedPut(LocalRegion.java:1597)
    at org.apache.geode.internal.cache.LocalRegion.put(LocalRegion.java:1584)
    at org.apache.geode.internal.cache.AbstractRegion.put(AbstractRegion.java:413)
    at example.tests.spring.data.geode.clientserver.ResilientClientServerIntegrationTests.exampleRegionDataAccessOperationsAreSuccessful(ResilientClientServerIntegrationTests.java:86)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

这就是
NoAvailableLocatorsException
,因为“默认”是
代理(同样是),它期望服务器集群中存在具有相应客户端区域(即“示例”)的集群

当然,如果您绝对且严格地不希望在集群不可用时任何GemFire客户端对象正常工作,那么您可以完全禁用[Spring[Boot]]应用程序/服务中的任何GemFire客户端配置。您只需返回false。在这种情况下,您只需注意应用程序没有自动连接任何GemFire对象

同样,您也可以使用SpringXMLConfig实现类似的效果,但是使用基于Java的Spring配置更容易演示,我将其作为一个练习留给您去理解

此外,测试集群可用性的方法虽然有效(并且硬编码为:p),但很粗糙,我让您添加更“健壮”的逻辑

但是,我相信这充分解决了你的问题

希望这有帮助


干杯

谢谢你的解释。我们现在正在通过Spring boot主类中的Gemfire-config.xml@ImportResource引导Gemfire客户端缓存。有没有办法实现此设置?。使用gemfire-config.xml和spring boot classYes更新了我的代码,正如我前面提到的,使用xml可以实现同样的效果,尤其是在
@Configuration
类上使用
@ImportResource
时。简而言之,这正是
@Conditonal
注释将与您的自定义
条件一起声明的地方。感谢您的测试。我复制了它,它在远程Geode服务器定位时运行,但在其他情况下,它会失败,出现
org.apache.Geode.cache.client.NoAvailableLocatorsException:无法连接到列表中的任何定位器[LocatorAddress[socketInetAddress=localhost/127.0.0.1:10334,hostname=localhost,isIpString=false]]
删除远程服务器配置时。我怎么能跑同样的车
org.apache.geode.cache.client.NoAvailableLocatorsException: Unable to connect to any locators in the list [LocatorAddress [socketInetAddress=localhost/127.0.0.1:10334, hostname=localhost, isIpString=false]]

    at org.apache.geode.cache.client.internal.AutoConnectionSourceImpl.findServer(AutoConnectionSourceImpl.java:158)
    at org.apache.geode.cache.client.internal.ConnectionFactoryImpl.createClientToServerConnection(ConnectionFactoryImpl.java:234)
    at org.apache.geode.cache.client.internal.pooling.ConnectionManagerImpl.borrowConnection(ConnectionManagerImpl.java:242)
    at org.apache.geode.cache.client.internal.OpExecutorImpl.execute(OpExecutorImpl.java:148)
    at org.apache.geode.cache.client.internal.OpExecutorImpl.execute(OpExecutorImpl.java:127)
    at org.apache.geode.cache.client.internal.PoolImpl.execute(PoolImpl.java:782)
    at org.apache.geode.cache.client.internal.PutOp.execute(PutOp.java:91)
    at org.apache.geode.cache.client.internal.ServerRegionProxy.put(ServerRegionProxy.java:159)
    at org.apache.geode.internal.cache.LocalRegion.serverPut(LocalRegion.java:3010)
    at org.apache.geode.internal.cache.LocalRegion.cacheWriteBeforePut(LocalRegion.java:3121)
    at org.apache.geode.internal.cache.ProxyRegionMap.basicPut(ProxyRegionMap.java:239)
    at org.apache.geode.internal.cache.LocalRegion.virtualPut(LocalRegion.java:5631)
    at org.apache.geode.internal.cache.LocalRegionDataView.putEntry(LocalRegionDataView.java:152)
    at org.apache.geode.internal.cache.LocalRegion.basicPut(LocalRegion.java:5059)
    at org.apache.geode.internal.cache.LocalRegion.validatedPut(LocalRegion.java:1597)
    at org.apache.geode.internal.cache.LocalRegion.put(LocalRegion.java:1584)
    at org.apache.geode.internal.cache.AbstractRegion.put(AbstractRegion.java:413)
    at example.tests.spring.data.geode.clientserver.ResilientClientServerIntegrationTests.exampleRegionDataAccessOperationsAreSuccessful(ResilientClientServerIntegrationTests.java:86)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)