Spring、Infinispan 和 JGroups - 以编程方式配置
Spring, Infinispan and JGroups - configuration programmatically
我正在使用 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")));
这似乎也不起作用。
如果您有 JGroups JChannel,您可以像这样获取 TCPPING:channel.getProtocolStack().findProtocol(TCPPING.class)
然后调用 setter 以在其上设置 initial_hosts。
在深入 Infinispan 内部结构之前,让我先试试简单的方法。
你知道应用程序启动时的所有主机吗?如果是这样,您可以使用环境变量(或系统 属性)来注入主机列表。只需执行 java myApp -Djgroups.tcpping.initial_hosts=host1..
.
另一种方法是像您一样深入研究 Infinispan 的内部结构。唯一的问题是您的实现做得太晚了(此时 JGroups 通道已经初始化)。所以你需要注入一个视图(可能使用 INJECT_VIEW
协议,参见 manual)
正如 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(),
(...)
按预期工作!
我正在使用 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")));
这似乎也不起作用。
如果您有 JGroups JChannel,您可以像这样获取 TCPPING:channel.getProtocolStack().findProtocol(TCPPING.class)
然后调用 setter 以在其上设置 initial_hosts。
在深入 Infinispan 内部结构之前,让我先试试简单的方法。
你知道应用程序启动时的所有主机吗?如果是这样,您可以使用环境变量(或系统 属性)来注入主机列表。只需执行 java myApp -Djgroups.tcpping.initial_hosts=host1..
.
另一种方法是像您一样深入研究 Infinispan 的内部结构。唯一的问题是您的实现做得太晚了(此时 JGroups 通道已经初始化)。所以你需要注入一个视图(可能使用 INJECT_VIEW
协议,参见 manual)
正如 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(),
(...)
按预期工作!