本章介绍配置Hazelcast应用程序的选项,并说明配置时可以使用的实用程序。您可以使用以下选项之一或混合配置Hazelcast:
- 陈述性的方式
- 程序化方式
- 使用Hazelcast系统属性
- 在Spring环境中
- 在正在运行的集群上动态添加配置(从Hazelcast 3.9开始)
这是您使用XML配置文件的配置选项。下载并解压缩时hazelcast-<version>.zip,您将看到文件/bin夹中存在以下文件,这些文件是标准的XML格式配置文件:
- hazelcast.xml:Hazelcast的默认声明性配置文件。对于大多数Hazelcast用户,此XML文件中的配置应该没问题。如果没有,您可以通过添加/删除/修改属性根据您的需要定制此XML文件。
- hazelcast-full-example.xml:配置文件,包括所有Hazelcast配置元素和属性及其描述。它是“超集” hazelcast.xml。您可以将其hazelcast-full-example.xml用作参考文档以了解任何元素或属性,也可以将其名称更改为hazelcast.xml并开始将其用作Hazelcast配置文件。
的一部分hazelcast.xml被示出为下面的例子。
<group>
<name>dev</name>
</group>
<management-center enabled="false">http://localhost:8080/mancenter</management-center>
<network>
<port auto-increment="true" port-count="100">5701</port>
<outbound-ports>
<!--
Allowed port range when connecting to other members.
0 or * means the port provided by the system.
-->
<ports>0</ports>
</outbound-ports>
<join>
<multicast enabled="true">
<multicast-group>224.2.2.3</multicast-group>
<multicast-port>54327</multicast-port>
</multicast>
<tcp-ip enabled="false">
<interface>127.0.0.1</interface>
<member-list>
<member>127.0.0.1</member>
</member-list>
</tcp-ip>
</join>
</network>
<map name="default">
<time-to-live-seconds>0</time-to-live-seconds>
</map>
您可以从多个声明性配置片段组成Hazelcast成员或Hazelcast客户端的声明性配置。为了组成声明性配置,您可以使用该<import/>元素加载不同的声明性配置文件。
假设您想要从两种配置中为Hazelcast组成声明性配置:development-group-config.xml和development-network-config.xml。这两种配置如下所示。
development-group-config.xml:
<hazelcast>
<group>
<name>dev</name>
</group>
</hazelcast>
development-network-config.xml:
<hazelcast>
<network>
<port auto-increment="true" port-count="100">5701</port>
<join>
<multicast enabled="true">
<multicast-group>224.2.2.3</multicast-group>
<multicast-port>54327</multicast-port>
</multicast>
</join>
</network>
</hazelcast>
要从上面两个中获取示例Hazelcast声明性配置,请使用<import/>如下所示的元素。
<hazelcast>
<import resource="development-group-config.xml"/>
<import resource="development-network-config.xml"/>
</hazelcast>
此功能也适用于Hazelcast客户端的声明性配置。请参阅以下示例。
client-group-config.xml:
<hazelcast-client>
<group>
<name>dev</name>
</group>
</hazelcast-client>
client-network-config.xml:
<hazelcast-client>
<network>
<cluster-members>
<address>127.0.0.1:7000</address>
</cluster-members>
</network>
</hazelcast-client>
要从上面两个示例中获取Hazelcast客户端声明性配置,请使用<import/>如下所示的元素。
<hazelcast-client>
<import resource="client-group-config.xml"/>
<import resource="client-network-config.xml"/>
</hazelcast>
<import/>在XML层次结构的顶层 使用元素。 |
使用该元素<import>,您还可以从类路径和文件系统加载XML资源:
<hazelcast>
<import resource="file:///etc/hazelcast/development-group-config.xml"/> <!-- loaded from filesystem -->
<import resource="classpath:development-network-config.xml"/> <!-- loaded from classpath -->
</hazelcast>
该元素也<import>支持变量。请参阅以下示例代码段:
<hazelcast>
<import resource="${environment}-group-config.xml"/>
<import resource="${environment}-network-config.xml"/>
</hazelcast>
除声明式配置外,您还可以以编程方式配置群集。为此,您可以创建Config对象,设置/更改其属性和属性,并使用此Config对象创建新的Hazelcast成员。以下是配置一些网络和Hazelcast Map属性的示例代码。
Config config = new Config();
config.getNetworkConfig().setPort( 5900 )
.setPortAutoIncrement( false );
MapConfig mapConfig = new MapConfig();
mapConfig.setName( "testMap" )
.setBackupCount( 2 )
.setTimeToLiveSeconds( 300 );
config.addMapConfig( mapConfig );
要使用上面的示例配置创建Hazelcast成员,请传递配置对象,如下所示:
HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance( config );
在Config该Hazelcast实例启动后,不得修改。换句话说,必须在创建之前完成所有配置HazelcastInstance。可以在运行时添加某些其他配置元素,如“在群集上动态添加数据结构配置”部分中所述。 |
您还可以创建一个名为Hazelcast的成员。在这种情况下,你应该设置instanceName的Config对象,如下图所示:
Config config = new Config();
config.setInstanceName( "my-instance" );
Hazelcast.newHazelcastInstance( config );
要按名称检索现有Hazelcast成员,请使用以下命令:
Hazelcast.getHazelcastInstanceByName( "my-instance" );
要检索所有现有的Hazelcast成员,请使用以下命令:
Hazelcast.getAllHazelcastInstances();
Hazelcast通过hazelcast-config-<version>.xsdHazelcast库附带的文件执行模式验证。如果声明性或编程配置中存在错误,Hazelcast会抛出一个有意义的异常。 |
如果要指定要创建的配置文件Config,Hazelcast支持多种方式,包括文件系统,类路径,InputStream和URL:
- Config cfg = new XmlConfigBuilder(xmlFileName).build();
- Config cfg = new XmlConfigBuilder(inputStream).build();
- Config cfg = new ClasspathXmlConfig(xmlFileName);
- Config cfg = new FileSystemXmlConfig(configFilename);
- Config cfg = new UrlXmlConfig(url);
- Config cfg = new InMemoryXmlConfig(xml);
您可以使用系统属性来配置Hazelcast的某些方面。您可以通过声明性配置,编程配置或JVM系统属性将这些属性设置为名称和值对。以下是每个选项的示例。
声明的:
....
<properties>
<property name="hazelcast.property.foo">value</property>
....
</properties>
</hazelcast>
编程方式:
Config config = new Config() ;
config.setProperty( "hazelcast.property.foo", "value" );
使用JVM的System类或-D参数:
System.setProperty( "hazelcast.property.foo", "value" );
要么
java -Dhazelcast.property.foo=value
您将在本参考手册中按照某些章节中的要求查看Hazelcast系统属性。所有Hazelcast系统属性都列在“ 系统属性”附录中,其中包含其描述,默认值和属性类型作为参考。
如果您在Spring中使用Hazelcast,则可以使用命名空间声明bean hazelcast。将名称空间声明添加到beansSpring上下文文件中的元素时,可以开始使用名称空间快捷方式hz作为bean声明。以下是与Spring集成时的示例Hazelcast配置:
<hz:hazelcast id="instance">
<hz:config>
<hz:group name="dev"/>
<hz:network port="5701" port-auto-increment="false">
<hz:join>
<hz:multicast enabled="false"/>
<hz:tcp-ip enabled="true">
<hz:members>10.10.1.2, 10.10.1.3</hz:members>
</hz:tcp-ip>
</hz:join>
</hz:network>
</hz:config>
</hz:hazelcast>
有关Hazelcast-Spring集成的更多信息,请参阅Spring Integration部分。
如上所述,Hazelcast可以以声明或编程方式配置; 必须在启动Hazelcast成员之前完成配置,并且此配置在运行时不能更改,因此我们将其称为静态配置。
从Hazelcast 3.9开始,可以在运行时动态添加某些数据结构的配置; 这些可以通过调用从正在运行的成员的方法获得Config.add*Config的Config对象上的一个方法来添加HazelcastInstance.getConfig()。例如:
Config config = new Config();
MapConfig mapConfig = new MapConfig("sessions");
config.addMapConfig(mapConfig);
HazelcastInstance instance = Hazelcast.newHazelcastInstance(config);
// need to configure another map with no sync backups
MapConfig noBackupsMap = new MapConfig("dont-backup").setBackupCount(0);
// DO NOT DO THIS -- never modify the original Config object
// config.addMapConfig(noBackupsMap);
// Instead do this. The added config will be propagated to all members of the cluster
instance.getConfig().addMapConfig(noBackupsMap);
在调用add*Config方法之前,必须完全配置动态配置元素:此时,配置对象将被传递到集群的每个成员并添加到每个成员的动态配置中,因此在add*Config调用之后变更配置对象将无效。
由于动态添加的数据结构配置在所有集群成员之间传播,因此可能由于超时和网络分区等情况而发生故障。配置传播机制在内部重试每当检测到成员资格更改时添加配置。但是,如果从add*Config方法抛出异常,则配置可能已部分传播到某些集群成员,并且应由用户重试添加配置。
add*Config除以下所有方法都支持添加新的动态配置:
- JobTracker 自Hazelcast 3.8以来已被弃用
- QuorumConfig:无法动态添加新的仲裁配置,但其他配置可以引用现有静态配置中配置的仲裁
- WanReplicationConfig:无法动态添加新的WAN复制配置,但是可以从其他配置引用现有的静态复制配置,例如,新动态MapConfig可以包括WanReplicationRef静态配置的WAN复制配置。
- ListenerConfig:可以通过其他API(如HazelcastInstance.getCluster().addMembershipListener和)在运行时添加侦听器HazelcastInstance.getPartitionService().addMigrationListener。
尝试添加动态配置时,如果已存在同一元素的静态配置,则会抛出ConfigurationException。例如,假设我们在hazelcast.xml配置中使用以下片段启动成员:
<map name="sessions">
...
</map>
然后为具有名称的地图添加动态配置sessions将抛出ConfigurationException:
HazelcastInstance instance = Hazelcast.newHazelcastInstance();
MapConfig sessionsMapConfig = new MapConfig("sessions");
// this will throw ConfigurationException:
instance.getConfig().addMapConfig(sessionsMapConfig);
尝试为已添加动态配置的元素添加动态配置时,如果检测到配置冲突,ConfigurationException则将抛出该配置冲突。例如:
HazelcastInstance instance = Hazelcast.newHazelcastInstance();
MapConfig sessionsMapConfig = new MapConfig("sessions").setBackupCount(0);
instance.getConfig().addMapConfig(sessionsMapConfig);
MapConfig sessionsWithBackup = new MapConfig("sessions").setBackupCount(1);
// throws ConfigurationException because the new MapConfig conflicts with existing one
instance.getConfig().addMapConfig(sessionsWithBackup);
MapConfig sessionsWithoutBackup = new MapConfig("sessions").setBackupCount(0);
// does not throw exception: new dynamic config is equal to existing dynamic config of same name
instance.getConfig().addMapConfig(sessionsWithoutBackup);
当您在不传递Config对象的情况下启动Hazelcast成员时,如“以编程方式配置”部分所述,Hazelcast会按如下方式检查成员的配置:
- 首先,它查找hazelcast.config系统属性。如果已设置,则将其值用作路径。如果您希望能够更改Hazelcast配置,这非常有用; 你可以这样做,因为它没有嵌入到应用程序中。您可以config使用以下命令设置该选项:
-Dhazelcast.config=`*`<path to the hazelcast.xml>
路径可以是常规路径,也可以是带前缀的类路径引用classpath:。
- 如果未设置上述系统属性,则Hazelcast会检查hazelcast.xml工作目录中是否有文件。
- 如果没有,则检查是否hazelcast.xml存在于类路径中。
- 如果上述方法均无效,Hazelcast会加载hazelcast.xmlHazelcast软件包附带的默认配置()。
在配置Hazelcast之前,请尝试使用默认配置以查看它是否适合您。对于大多数用户,此默认配置应该没问题。如果没有,您可以考虑修改配置以使其更适合您的环境。
您可以提供自定义策略以将项目名称与配置模式匹配。默认情况下,Hazelcast使用简化的通配符匹配。有关此信息,请参阅使用通配符部分。可以使用成员或客户端config对象来提供自定义配置模式匹配器。请参阅以下示例代码段:
// Setting a custom config pattern matcher via member config object
Config config = new Config();
config.setConfigPatternMatcher(new ExampleConfigPatternMatcher());
// A custom config pattern matcher which throws exception(instead of using `default` config) when config is not found
// MatchingPointConfigPatternMatcher is the default one used by Hazelcast
class ExampleConfigPatternMatcher extends MatchingPointConfigPatternMatcher {
@Override
public String matches(Iterable<String> configPatterns, String itemName) throws ConfigurationException {
String matches = super.matches(configPatterns, itemName);
if (matches == null) {
throw new ConfigurationException("No config found for " + itemName);
}
return matches;
}
}
Hazelcast支持可以使用被配置所有分布式数据结构通配符配置Config,即,对所有除IAtomicLong,IAtomicReference。使用名称中的星号(\ *)字符,可以通过单个配置配置不同的映射,队列,主题,信号量等实例。
单个星号(\ *)可以放在配置名称中的任何位置。
例如,com.hazelcast.test.mymap可以使用以下配置之一配置名为的映射。
<map name="com.hazelcast.test.*">
...
</map>
<map name="com.hazel*">
...
</map>
<map name="*.test.mymap">
...
</map>
<map name="com.*test.mymap">
...
</map>
或队列com.hazelcast.test.myqueue:
<queue name="*hazelcast.test.myqueue">
...
</queue>
<queue name="com.hazelcast.*.myqueue">
...
</queue>
在Hazelcast和/或Hazelcast Client声明性配置中,您可以使用变量来设置元素的值。以编程方式设置系统属性或使用命令行界面时,此选项有效。您可以在声明性配置中使用变量来访问您设置的系统属性的值。
例如,请参阅以下用于设置两个系统属性的命令。
-Dgroup.name=dev
让我们在Hazelcast的声明性配置中获取这些系统属性的值,如下所示。
<hazelcast>
<group>
<name>${group.name}</name>
</group>
</hazelcast>
这也适用于Hazelcast Client的声明性配置,如下所示。
<hazelcast-client>
<group>
<name>${group.name}</name>
</group>
</hazelcast-client>
如果您不想依赖系统属性,可以使用XmlConfigBuilder并显式设置Properties实例,如下所示。
Properties properties = new Properties();
// fill the properties, e.g. from database/LDAP, etc.
XmlConfigBuilder builder = new XmlConfigBuilder();
builder.setProperties(properties);
Config config = builder.build();
HazelcastInstance hz = Hazelcast.newHazelcastInstance(config);
变量替换器用于在加载配置期间替换自定义字符串,例如,它们可用于掩盖敏感信息,例如用户名和密码。当然,它们的使用不限于安全相关信息。
变量替换器实现接口com.hazelcast.config.replacer.spi.ConfigReplacer,它们仅以声明方式配置:在Hazelcast的声明性配置文件中,即hazelcast.xml和hazelcast-client.xml。您可以参考ConfigReplacers Javadoc获取有关替换器如何工作的基本信息。
变量替换器在元素<config-replacers>下配置<hazelcast>,如下所示。
<hazelcast>
...
<config-replacers fail-if-value-missing="false">
<replacer class-name="com.acme.MyReplacer">
<properties>
<property name="propName">value</property>
...
</properties>
</replacer>
<replacer class-name="example.AnotherReplacer"/>
</config-replacers>
...
</hazelcast>
如您所见,<config-replacers>是替换器的父元素,它是使用<replacer>子元素声明的。您可以在<config-replacers>.下面定义多个替换器。以下是用于替换器配置的元素和属性的描述:
- fail-if-value-missing:指定在缺少替换值时是否停止加载配置过程。它是一个可选属性,其默认值为true。
- class-name:替换者的完整类名。
- <properties>:包含用于配置替换程序的属性的名称和值。使用<property>子元素定义每个属性。所有属性都将在后面的章节中介绍。
Hazelcast提供以下替换类作为ConfigReplacer接口的示例实现。请注意,您还可以实现自己的替换者。
- EncryptionReplacer
- PropertyReplacer
还有一个ExecReplacer运行外部命令并使用其标准输出作为变量的值。请参考其代码示例。 |
每个示例替换器将在以下部分中进行说明。
此示例EncryptionReplacer以普通形式替换加密变量。用于加密/解密的密钥是从密码生成的,密码可以是文件中的值和/或环境特定值,例如MAC地址和实际用户数据。
它的完整类名是com.hazelcast.config.replacer.EncryptionReplacer,并且替换器前缀是ENC。以下是用于配置此示例替换程序的属性:
- cipherAlgorithm:用于加密/解密的密码算法。其默认值为AES。
- keyLengthBits:要生成的密钥的长度(以位为单位)。其默认值为128。
- passwordFile:文件的路径,其内容应作为加密密码的一部分使用。如果未提供该属性,则不会将文件用作密码的一部分。其默认值为null。
- passwordNetworkInterface:网络接口的名称,其MAC地址应作为加密密码的一部分。如果未提供该属性,则不会将网络接口属性用作密码的一部分。其默认值为null。
- passwordUserProperties:指定是否应将当前用户属性(user.name和user.home)用作加密密码的一部分。其默认值为true。
- saltLengthBytes:随机密码salt的长度(以字节为单位)。其默认值为8。
- secretKeyAlgorithm:与生成的密钥相关联的密钥算法的名称。其默认值为AES。
- secretKeyFactoryAlgorithm:用于从密码生成密钥的算法。其默认值为PBKDF2WithHmacSHA256。
- securityProvider:用于检索已配置的密钥工厂和密码的Java安全提供程序的名称。其默认值为null。
较旧的Java版本可能不支持用作默认值的所有算法。请使用Java版本支持的属性值。 |
作为一个用法示例,让我们创建一个密码文件,并从该文件中生成加密的字符串。
1 - 创建密码文件: echo '/Za-uG3dDfpd,5.-' > /opt/master-password
2 - 定义加密变量:
java -cp hazelcast-*.jar \
-DpasswordFile=/opt/master-password \
-DpasswordUserProperties=false \
com.hazelcast.config.replacer.EncryptionReplacer \
"aGroup"
$ENC{Gw45stIlan0=:531:yVN9/xQpJ/Ww3EYkAPvHdA==}
java -cp hazelcast-*.jar \
-DpasswordFile=/opt/master-password \
-DpasswordUserProperties=false \
com.hazelcast.config.replacer.EncryptionReplacer \
"aPasswordToEncrypt"
$ENC{wJxe1vfHTgg=:531:WkAEdSi/YWEbwvVNoU9mUyZ0DE49acJeaJmGalHHfA=}
3 - 配置替换程序并将加密变量放入配置中:
<hazelcast>
<config-replacers>
<replacer class-name="com.hazelcast.config.replacer.EncryptionReplacer">
<properties>
<property name="passwordFile">/opt/master-password</property>
<property name="passwordUserProperties">false</property>
</properties>
</replacer>
</config-replacers>
<group>
<name>$ENC{Gw45stIlan0=:531:yVN9/xQpJ/Ww3EYkAPvHdA==}</name>
<password>$ENC{wJxe1vfHTgg=:531:WkAEdSi//YWEbwvVNoU9mUyZ0DE49acJeaJmGalHHfA=}</password>
</group>
</hazelcast>
4 - 检查解密是否有效:
java -jar hazelcast-*.jar
Apr 06, 2018 10:15:43 AM com.hazelcast.config.XmlConfigLocator
INFO: Loading 'hazelcast.xml' from working directory.
Apr 06, 2018 10:15:44 AM com.hazelcast.instance.AddressPicker
INFO: [LOCAL] [aGroup] [3.10-SNAPSHOT] Prefer IPv4 stack is true.
正如您在日志中看到的那样,使用了正确解密的组名称值(“aGroup”)。
在PropertyReplacer用给定名称的属性替代变量。通常使用系统属性,例如${user.name}。无需在声明性配置文件中定义它。
它的完整类名是com.hazelcast.config.replacer.PropertyReplacer,并且replacer前缀是空字符串(“”)。
您还可以提供自己的替换器实现。所有替换者都必须实现该接口com.hazelcast.config.replacer.spi.ConfigReplacer。一个简单的片段如下所示。
public interface ConfigReplacer {
void init(Properties properties);
String getPrefix();
String getReplacement(String maskedValue);
}