Spring,Infinispan和JGroups - 以编程方式配置

时间:2018-05-29 15:23:04

标签: spring caching config infinispan jgroups

我使用的是Spring 4.3,Infinispan 9.11和JGroups 4.0.6。对于JGroups,我使用的是xml配置,其中包含:

<TCPPING async_discovery="true"
         initial_hosts="${jgroups.tcpping.initial_hosts: HOSTS}"
(...)

假设我想在xml中保留配置,但是,我需要应用另一个(yml)配置文件中的主机列表。一种方法可能是从Java读取yml属性(我有那部分)并将它们设置为JGroups配置。

这是我到目前为止所尝试的:

EmbeddedCacheManager cacheManager = new DefaultCacheManager(
            GlobalConfigurationBuilder.defaultClusteredBuilder()
                    .transport()
                    .nodeName(nodeName)
                    .addProperty(JGroupsTransport.CONFIGURATION_FILE, "tcp.xml")
                    .addProperty(JGroupsTransport.CONFIGURATION_STRING, "jgroups.tcpping.initial_hosts: HOSTS")
                    .build(),
            new ConfigurationBuilder()
                    ...
                    .build()
    );

但是,配置字符串不起作用。

更新。另一种尝试:

JGroupsTransport transport = (JGroupsTransport)(cacheManager.getCacheManagerConfiguration().transport().transport());
    TCPPING ping = transport.getChannel().getProtocolStack().findProtocol(TCPPING.class);
    ping.setPortRange(1);
    ping.setInitialHosts(Arrays.asList(new IpAddress("HOST1:PORT1"), new IpAddress("HOST2:PORT2")));

这似乎不起作用。

3 个答案:

答案 0 :(得分:2)

如果你有JGroups JChannel,你可以像这样抓取TCPPING:channel.getProtocolStack().findProtocol(TCPPING.class)然后调用setter来设置它的初始化。

答案 1 :(得分:2)

正如Bela Ban和Altanis指出的那样,问题是Infinispan在我能够修改传输属性之前调用JChannel.connect()。我找到了一个解决方法:

public class JGroupsChannelLookupImpl implements JGroupsChannelLookup {

    @Override
    public JChannel getJGroupsChannel(Properties p) {
        JChannel channel = null;
        try {
            channel = new JChannel("tcp.xml");
            TCPPING ping = channel.getProtocolStack().findProtocol(TCPPING.class);
            ping.setInitialHosts(Arrays.asList(HOST1, HOST2, HOST3, ...));
        }
        catch (Exception ex) {
            // do sth with the ex
        }
        Objects.requireNonNull(channel);
        return channel;
    }

(...)

}

然后在创建DefaultCacheManager时,不要直接从xml加载配置,只需加载频道查找:

new DefaultCacheManager(
            GlobalConfigurationBuilder.defaultClusteredBuilder()
                    .transport()
                    .nodeName(nodeName)
                    .addProperty(JGroupsTransport.CHANNEL_LOOKUP, JGroupsChannelLookupImpl.class.getName())
                    .build(),
           (...)

按预期工作!

答案 2 :(得分:0)

在深入Infinispan内部之前,让我试一试。

您是否知道应用程序启动时的所有主机?如果是这样,您可以使用环境变量(或系统属性)来注入主机列表。只需执行java myApp -Djgroups.tcpping.initial_hosts=host1..

另一种方法是像你一样深入Infinispan内部。唯一的问题是你的实现太迟了(JGroups通道已经在那时初始化)。所以你需要注入一个视图(可能使用INJECT_VIEW协议,请参阅manual