我们在Java中有一个使用Gemfire和spring-data-gemfire的大型Web应用程序。我们在客户端服务器配置中运行gemfire。
我们遇到以下问题:在启动期间,在bean连接阶段,spring-data-gemfire想要连接到gemfire的定位器。但是,定位器可能尚未启动。然后,应用程序将抛出com.gemstone.gemfire.cache.NoSubscriptionServersAvailableException: Primary discovery failed
异常。
这导致我们服务的启动过程缓慢且脆弱,这很不方便,尤其是在我们的自动化测试期间。
是否有任何好的解决方案让客户端等待并定期轮询直到定位器运行?
答案 0 :(得分:3)
作为Jens D条评论,您可以尝试locator-wait-time
GemFire(系统)属性。但是,正如documentation指出......
尝试加入分布式系统时,如果定位器不可用,成员应等待定位器启动的秒数。当您一次启动定位器和对等时,请使用此设置。此超时允许对等方在尝试加入分布式系统之前等待定位器完成启动。
这特别指的是加入分布式系统/集群的“对等成员”,因此可能对客户端(缓存)没有任何影响。
在这种情况下,我使用了其他使用Spring的技术(特别是在涉及客户端/服务器拓扑的集成测试中),导致客户端阻塞等待服务器(或定位器)变得可用。在我的测试中,测试分支GemFire JVM进程运行服务器,而测试VM充当缓存客户端。
通过将GemFire与 Spring Session 集成,特别是在httpsession-gemfire-clientserver示例中,您可以在我最近的开发工作中看到这方面的示例。
在这里,我使用BeanPostProcessor
导致客户端缓存,特别是PoolFactoryBean / Pool阻止(在postProcessBeforeInitialization(..)
中)阻止池完全初始化,直到服务器可用(可以也适用于定位器。)
wait仅attempts to open a Socket connection to the Server(或定位器)来验证连接性。
另一种方法是create a CountDownLatch
,在registered GemFire ClientMembershipListener
中使用它并再次与BeanPostProcessor
结合使用,这次仅在postProcessAfterInitialization(..)
方法中使用。
从技术上讲,2种方法中只有1种是必需的。虽然我将其用于测试目的,但它也可用于实际应用程序,并且在实际应用程序中也不常见。
然而,理想情况下,您在开始使用Locator之前,因为形成一个集群取决于它。
希望这有帮助。
干杯! 约翰