Hazelcast集羣服務(2)——Hazelcast基本配置

XML基本配置

    如果用戶沒有指定或提供任何配置文件,Hazelcast默認會使用jar包中自帶的配置文件——"hazelcast-default.xml"來配置Hazelcast的運行環境。Hazelcast默認採用XML格式作爲配置文件,當然也支持其他配置方法,後文會詳細說明。我們先看看下面這個簡單的配置文件例子。

<hazelcast xsi:schemaLocation="//" xmlns="//" xmlns:xsi="">
    <group>
        <name>dev</name>
        <password>dev-pass</password>
    </group>
    <management-center enabled="false">http://localhost:8080/mancenter</management-center>
    <network>
		<port auto-increment="true" port-count="110">7701</port>
		<outbound-ports>
			<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="demo.config">
		<backup-count>1</backup-count>
		<time-to-live-seconds>0</time-to-live-seconds>
		<max-idle-seconds>0</max-idle-seconds>
		<eviction-policy>NONE</eviction-policy>
		<max-size policy="PER_NODE">0</max-size>
		<eviction-percentage>25</eviction-percentage>
		<merge-policy>com.hazelcast.map.merge.LatestUpdateMapMergePolicy
		</merge-policy>
	</map>
</hazelcast>

    如果你看到上面的配置內容有點蒙圈,建議你先看看上一篇Hazelcast基礎介紹的文章

    前面已經介紹,Hazelcast以分佈式的方式實現了Java中的絕大部分數據結構,這些數據結構的數據都以分區表的方式存儲,因此可以推斷XML配置文件中的<map></map>元素就是用來配置分佈式map的相關參數的,這裏先不細說每個參數的定義,從字面上看,大概就是配置map的備份副本個數、釋放策略、釋放比率等等。有了<map></map>當然還有<queue></queue><set></set><list></list>等針對各種數據結構的配置元素。

    <network></network>是非常重要的元素,他指定了Hazelcast的網絡環境。上面這個簡短的配置文件例子指定網絡使用5700到5800端口,使用組播協議來進行組網。

    我們在創建Hazelcast集羣時可以引入配置文件。下面的代碼例子展示瞭如何引入自定義的配置文件。(文中所有例子的源碼均在githubhttps://github.com/chkui/hazelcast-demo。使用“git clone”到本地用maven就可以運行。

/** https://github.com/chkui/hazelcast-demo/blob/master/src/main/java/org/palm/hazelcast/config/HazelcastConfigSimple.java */
public class HazelcastConfigSimple {
	public static void main(String[] args) {
		// 從classpath加載配置文件
		Config config = new ClasspathXmlConfig("xmlconfig/simple-config.xml");
		// 獲取網絡配置
		NetworkConfig netConfig = config.getNetworkConfig();
		// 獲取用戶定義的map配置
		MapConfig mapConfigXml = config.getMapConfig("demo.config");
		// 獲取系統默認的map配置
		MapConfig mapConfigDefault = config.getMapConfig("default");
		// 輸出集羣監聽的起始端口號
		System.out.println("Current port:" + netConfig.getPort());
		// 輸出監聽端口的累加號
		System.out.println("Current port count:" + netConfig.getPortCount());
		// 輸出自定義map的備份副本個數
		System.out.println("Config map backup count:" + mapConfigXml.getBackupCount());
		// 輸出默認map的備份副本個數
		System.out.println("Default map backup count:" + mapConfigDefault.getBackupCount());

		// 測試創建Hazelcast實例並讀寫測試數據
		HazelcastInstance instance1 = Hazelcast.newHazelcastInstance(config);
		HazelcastInstance instance2 = Hazelcast.newHazelcastInstance(config);

		Map<Integer, String> defaultMap1 = instance1.getMap("defaultMap");
		defaultMap1.put(1, "testMap");
		Map<Integer, String> configMap1 = instance1.getMap("configMap");
		configMap1.put(1, "configMap");

		Map<Integer, String> testMap2 = instance2.getMap("defaultMap");
		System.out.println("Default map value:" + testMap2.get(1));
		Map<Integer, String> configMap2 = instance2.getMap("configMap");
		System.out.println("Config map value:" + configMap2.get(1));
	}
}

   上面的例子使用ClasspathXmlConfig來生成Config實例,它表示從classpath路徑來加載配置文件。 從上面的代碼例子還可以看出,我們能夠從Config實例中讀取各種各樣的配置信息,例如網絡配置、Map配置等等。既然能get,當然也可以set,在Hazelcast沒有初始化之前,都可以隨意設置各種配置屬性。下面的例子展示瞭如何在代碼中修改Hazelcast的配置參數。

/** https://github.com/chkui/hazelcast-demo/blob/master/src/main/java/org/palm/hazelcast/config/HazelcastConfigRuntimeModify.java */
public class HazelcastConfigRuntimeModify {
	public static void main(String[] args) {
		// 創建默認config對象
		Config config = new Config();
		
		// 獲取network元素<network></network>
		NetworkConfig netConfig = config.getNetworkConfig();
		System.out.println("Default port:" + netConfig.getPort());
		
		// 設置組網起始監聽端口
		netConfig.setPort(9701);
		System.out.println("Customer port:" + netConfig.getPort());
		// 獲取join元素<join></join>
		JoinConfig joinConfig = netConfig.getJoin();
		// 獲取multicast元素<multicast></multicast>
		MulticastConfig multicastConfig = joinConfig.getMulticastConfig();
		// 輸出組播協議端口
		System.out.println(multicastConfig.getMulticastPort());
		// 禁用multicast協議
		multicastConfig.setEnabled(false);
		
		// 初始化Hazelcast
		Hazelcast.newHazelcastInstance(config);
	}
}

    上面的例子中,我們首先從Config中獲取了NetworkConfig實例,然後調用NetworkConfig::setPort方法將集羣的監聽起始端口設置爲9701(默認爲5701)。運行以上代碼會輸出以下片段內容:

class:com.hazelcast.instance.DefaultAddressPicker
info: [LOCAL] [dev] [3.6.3] Picked Address[192.168.1.100]:9701, using socket ServerSocket[addr=/0:0:0:0:0:0:0:0,localport=9701], bind any local is true

XML配置與源碼配置    

    看到這兄弟可能要問了:“又是XML配置,又是代碼級配置的,他兩到底啥關係呢?”。其實他兩是相輔相成的,既可以只用XML配置、也可以只在代碼中進行配置、還可以兩者混合使用——先加載XML配置再對其進行修改以滿足各種需要。

一個簡單的例子

我們先看一個簡單的例子,再深入瞭解Hazelcast實現XML到Java對象映射的原理。

<!-- XML配置 -->
<hazelcast>
	<network>
		<join>
			<multicast enabled="true">
				<multicast-group>224.2.2.3</multicast-group>
				<multicast-port>54327</multicast-port>
			</multicast>
		</join>
	</network>
</hazelcast>
// 代碼讀取數據
Config config = new Config();
NetworkConfig networkConfig = config.getNetworkConfig();
JoinConfig joinConfig = networkConfig .getJoin();
MulticastConfig multicastConfig = joinConfig.getMulticastConfig();
int multicastPort = multicastConfig.getMulticastPort();

   在上面這個XML配置和代碼的例子中,<hazelcast></hazelcast>對應JavaConfig對象,而<hazelcast>中包含<network></network>,因此Config::getNetwork方法可以獲取NetworkConfig對象的實例。繼續往下,<network>中包含<join></join>,因此NetworkConfig::getJoin可以得到JoinConfig。因爲<join>包含<multicast></multicast>,所以JoinConfig::getMulticastConfig可以得到MulticastConfig

    看到這裏應該都明白了吧:就是每個XML元素對應一個Java實體或數據,只要按照XML配置文件的樹形關係來調用get或set,就可以在源碼中獲取和設置所有配置數據。

XML和源碼配置的映射關係

    友情提示:如果僅僅是想了解如何使用Hazelcast,建議直接跳過這一段。對XML定義、DTD、XSD不瞭解的話看多了反而容易混亂。

    前文已經提到Hazelcast的配置文件已經預定義了所有要使用的 參數(對應XMLElementAttribuet),定義文件是hazelcast-<version>.jar包中的hazelcast-3.*.xsd(目前是3.6版本)。XSD文件中所有 類型(XSDType)不爲 預定義類型(xs:booleanxs:unsignedInt 等)的 元素(XSD:Element)映射到Java中都對應一個 實體(EntityPojo)。如果 元素 中還包含 類型 不爲預定義類型的 元素,則對應到Java數據結構時 實體 中還包含另外一個 實體。若XSD文件中定義的 元素類型 爲 預定義類型,則對應一個Java基本數據值(intString等)。

    例如下面這些XSD文件片段:

<xs:element name="network" type="network" minOccurs="0" maxOccurs="1"/>

<xs:element name="join" type="join" minOccurs="0" maxOccurs="1"/>

<xs:element name="multicast" type="multicast" minOccurs="0"/>

<xs:element name="multicast-port" type="xs:unsignedShort" minOccurs="0" maxOccurs="1" default="54327">

    <network></network>元素在xsd文件中定義的類型爲network,因此他是一個名爲NetworkConfig的實體。XML文件中在<network>元素內還有一個<join></join>元素,<join>元素的type爲join,因此調用NetworkConfig::getJoin方法可以得到一個JoinConfig實例。以此類推,<join>內的<multicast></multicast>元素也是一個名爲MulticastConfig的實體,而<multicast>中的<multicast-port></multicast-port>對應一個Java的基本數據值——int,因爲它在XSD中的類型爲xs:unsignedShort

    如果使用的XML配置文件中出現了XSD文件中沒有定義的元素和屬性,在解析過程中會拋出meaningful異常。

Hazelcast配置文件詳解

    前面通過幾個例子介紹了Hazelcast如何配置,後面的篇幅將會逐一介紹Hazelcast所有配置細節及其參數定義。如果某位仁兄現在已經需要將Hazelcast引入到現在的項目中,建議您仔細閱讀。    

加載配置文件

    當調用Hazelcast.newHazelcastInstance()Hazelcast.newHazelcastInstance(null)時,Hazelcast會從指定的路徑加載XML配置文件或者加載默認配置文件。執行過程如下。

    首先,可以通過系統配置參數(system property)指定XML配置文件的加載路徑。Hazelcast將在創建實例時檢查是否設置了"hazelcast.config"這個啓動參數並引用。可以通過Jvm 參數或 System參數來指定它:

#!/bin/sh
java -Dhazelcast.config=/user/my_hazelcast_config.xml ....

    或

// Java
System.setProperty( "hazelcast.config", "/user/my_hazelcast_config.xml" );

     其次,如果沒有設置這個參數或者指定路徑的文件不存在,Hazelcast會搜尋當前classpath路徑檢查是否存在一個名爲“hazelcast.xml”,有則使用。

    最後,如果通過以上2個步驟都沒有加載到配置文件,則使用jar包中的“hazelcast-default.xml”。

在編碼中加載配置文件

    除了上面指定系統參數的方法,還可以通過編碼實現加載配置文件。Hazelcast提供了多種初始化配置文件的方法,主要有:ClasspathXmlConfigFileSystemXmlConfigUrlXmlConfigInMemoryXmlConfigXmlConfigBuilder

  1. ClasspathXmlConfig:從classpath路徑加載配置文件。通常情況下,除了Java的運行環境路徑,classpath的根目錄可以認爲是classes文件夾。因此如果一個文件存放於....../target/classes/xmlconfig/simple-config.xml。那麼Config cfg = new ClasspathXmlConfig("xmlconfig/simple-config.xml")即可加載該配置文件。
  2. FileSystemXmlConfig:從文件系統加載配置文件。文件系統是指從操作系統的文件路徑加載文件,因此如果文件存放在 linux:/user/local/hazelcast/hazelcast.xml 或 windows:D:\local\hazelcast\hazelcast.xml。那麼使用new FileSystemXmlConfig("/user/local/hazelcast/hazelcast.xml") new FileSystemXmlConfig("D:\\local\\hazelcast\\hazelcast.xml") 即可獲取配置文件。
  3. UrlXmlConfig:從網絡地址獲取配置文件。
  4. InMemoryXmlConfig:從內存中的xml字符串生成配置文件。
  5. XmlConfigBuilder:InputStream流中讀取配置文件。使用Config cfg = new XmlConfigBuilder(inputStream).build()可以創建一個Config實例。

    得到Config實例之後使用 HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance(config)可以創建HazelcastInstance實例。

    在Config中使用Config::setInstanceName方法可以設置實例名稱。此後使用這個名稱可以獲取同一個HazelcastInstance 實例。例如:

//Java
// 創建配置
Config cfg = new XmlConfigBuilder(inputStream).build();
// 設置實例名稱
config.setInstanceName("my-instance");
// 創建Hazelcast實例
Hazelcast.newHazelcastInstance(cfg);
// 獲取已創建的實例
Hazelcast.getHazelcastInstanceByName("my-instance");

在配置文件中使用通配符

    在XML配置文件中,可以使用通配符*來匹配某些元素的名稱。例如像下面這樣配置一個分佈式Map的名稱:

<map name="map.*">
...
</map>

    在使用時,下面的方法都是獲得同一個Map

Map map1 = hazelcastInstance.getMap("map.1");

Map map2 = hazelcastInstance.getMap("map.2");

Map map3 = hazelcastInstance.getMap("map.3");

在配置文件中使用變量

    Hazelcast提供了使用變量來配置XML中元素值的方法,通過在配置文件中使用${}來指定變量要替換的參數。

    首先,可以通過系統參數來設置Hazelcast參數。例如像下面這樣設置變量:

-Dgroup.name=dev 
-Dgroup.password=somepassword

    或

System.setProperty( "group.name", "demo" );
System.setProperty( "group.password", "passwd" );

    可以在XML配置文件中可以像下面這樣設置${}:

<hazelcast>
  <group>
    <name>${group.name}</name>
    <password>${group.password}</password>
  </group>
</hazelcast>

    在創建配置文件時,${}會被變量替換。

    其次,可以通過XML中的<properties></properties>元素配置參數。如下:

<hazelcast>
	<properties>
		<property name="group.name">dev</property>
		<property name="group.passwd">devpasswd</property>
	</properties>
    <group>
		<name>${group.name}</name>
		<password>${group.passwd}</password>
	</group>
</hazelcast>

    引入配置文件後,會將properties中的變量替換到對應的${}中。

    最後,還可以通過標準的properties文件來配置參數。如下面示例代碼:

/** https://github.com/chkui/hazelcast-demo/blob/master/src/main/java/org/palm/hazelcast/config/HazelcastConfigVariable.java */
public class HazelcastConfigVariable {
	// XML配置文件存放路徑
	final static String DEF_CONFIG_FILE = "xmlconfig/variable-config.xml";
	// properties文件路徑
	final static String DEF_PROPERTIES_FILE = "properties/variable-config.properties";
	public static void main(String[] args) {
		try {
			// 獲取配置文件磁盤路徑
			final String path = Thread.currentThread().getContextClassLoader().getResource("").toString() + DEF_CONFIG_FILE;
			// 構建XML配置
			XmlConfigBuilder builder = new XmlConfigBuilder(path);
			// 設置properties
			builder.setProperties(getProperties());
			// 創建Config,此時會替換${}
			Config config = builder.build();
			// 輸出Config參數
			System.out.println(config.getGroupConfig().getName());
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	// get Properties
	private static Properties getProperties() {
		Properties p = null;
		try (InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(DEF_PROPERTIES_FILE)) {
			if (null != in) {
				p = new Properties();
				p.load(in);
			}
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(0);
		}
		return p;
	}
}

    代碼對應的XML配置文件:

<!-- https://github.com/chkui/hazelcast-demo/blob/master/src/main/resources/xmlconfig/variable-config.xml -->
<hazelcast>
	<group>
		<name>${group.name}</name>
		<password>${group.password}</password>
	</group>
	<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>

    對應properties文件:

#https://github.com/chkui/hazelcast-demo/blob/master/src/main/resources/properties/variable-config.properties

group.name=demo
group.password=demopasswd

    上面的代碼先創建了一個XmlConfigBuilder實例,然後調用XmlConfigBuilder::setProperties方法設置Properties到 XmlConfigBuilder中。在build時,會用Properties定義的變量替換XML中對應的${}參數。通過使用properties來控制配置參數,我們可以使用更多的工具來管理Hazelcast配置,例如使用Maven<resources>元素管理properties。

結構化配置

    和spring的配置文件一樣,Hazelcast的XML配置文件也可以通過<import>元素來整合多個配置文件。例如有下面2份配置文件。

group-config.xml :

<hazelcast>
  <group>
      <name>dev</name>
      <password>dev-pass</password>
  </group>
</hazelcast>

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>

    然後我們可以像下面這樣把2份配置整合在一起。

<hazelcast>
  <import resource="group-config.xml"/>
  <import resource="network-config.xml"/>
</hazelcast>

    <import>元素同樣支持參數:

<hazelcast>
  <import resource="${param1}-group-config.xml"/>
  <import resource="${param2}-network-config.xml"/>
</hazelcast>

    有了結構化配置的方法,可以把一份大文檔,劃分成很多相關部分去維護。

    至此,Hazelcast的基本配置介紹完畢,後續的博文會介紹Hazelcast的各種分佈式功能,包括網絡環境如何管理,分佈式數據結構使用(Map、Queue、List、Set、Topic、Semaphore等)、分佈式事件驅動、分佈式計算、分佈式查詢等等。等哥消息…………。

原文地址:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章