Hazelcast集群服务(2)——Hazelcast基本配置
為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??
? ? 在入門及使用案例一文介紹了什么是Hazelcast,并展示了一個(gè)簡(jiǎn)單的使用例子。原理大家都懂了,后面的篇章會(huì)給兄弟們更多干貨。
????本篇博文將細(xì)說(shuō)如何配置Hazelcast,聽(tīng)我慢慢給你們侃。
XML基本配置
? ? 如果用戶沒(méi)有指定或提供任何配置文件,Hazelcast默認(rèn)會(huì)使用jar包中自帶的配置文件——"hazelcast-default.xml"來(lái)配置Hazelcast的運(yùn)行環(huán)境。Hazelcast默認(rèn)采用XML格式作為配置文件,當(dāng)然也支持其他配置方法,后文會(huì)詳細(xì)說(shuō)明。我們先看看下面這個(gè)簡(jiǎn)單的配置文件例子。
<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>????如果你看到上面的配置內(nèi)容有點(diǎn)蒙圈,建議你先看看上一篇Hazelcast基礎(chǔ)介紹的文章。
? ? 前面已經(jīng)介紹,Hazelcast以分布式的方式實(shí)現(xiàn)了Java中的絕大部分?jǐn)?shù)據(jù)結(jié)構(gòu),這些數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù)都以分區(qū)表的方式存儲(chǔ),因此可以推斷XML配置文件中的<map></map>元素就是用來(lái)配置分布式map的相關(guān)參數(shù)的,這里先不細(xì)說(shuō)每個(gè)參數(shù)的定義,從字面上看,大概就是配置map的備份副本個(gè)數(shù)、釋放策略、釋放比率等等。有了<map></map>當(dāng)然還有<queue></queue>、<set></set>、<list></list>等針對(duì)各種數(shù)據(jù)結(jié)構(gòu)的配置元素。
? ? <network></network>是非常重要的元素,他指定了Hazelcast的網(wǎng)絡(luò)環(huán)境。上面這個(gè)簡(jiǎn)短的配置文件例子指定網(wǎng)絡(luò)使用5700到5800端口,使用組播協(xié)議來(lái)進(jìn)行組網(wǎng)。
? ? 我們?cè)趧?chuàng)建Hazelcast集群時(shí)可以引入配置文件。下面的代碼例子展示了如何引入自定義的配置文件。(文中所有例子的源碼均在github:https://github.com/chkui/hazelcast-demo。使用“git clone”到本地用maven就可以運(yùn)行。)
/** 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");// 獲取網(wǎng)絡(luò)配置NetworkConfig netConfig = config.getNetworkConfig();// 獲取用戶定義的map配置MapConfig mapConfigXml = config.getMapConfig("demo.config");// 獲取系統(tǒng)默認(rèn)的map配置MapConfig mapConfigDefault = config.getMapConfig("default");// 輸出集群監(jiān)聽(tīng)的起始端口號(hào)System.out.println("Current port:" + netConfig.getPort());// 輸出監(jiān)聽(tīng)端口的累加號(hào)System.out.println("Current port count:" + netConfig.getPortCount());// 輸出自定義map的備份副本個(gè)數(shù)System.out.println("Config map backup count:" + mapConfigXml.getBackupCount());// 輸出默認(rèn)map的備份副本個(gè)數(shù)System.out.println("Default map backup count:" + mapConfigDefault.getBackupCount());// 測(cè)試創(chuàng)建Hazelcast實(shí)例并讀寫測(cè)試數(shù)據(jù)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來(lái)生成Config實(shí)例,它表示從classpath路徑來(lái)加載配置文件。?從上面的代碼例子還可以看出,我們能夠從Config實(shí)例中讀取各種各樣的配置信息,例如網(wǎng)絡(luò)配置、Map配置等等。既然能get,當(dāng)然也可以set,在Hazelcast沒(méi)有初始化之前,都可以隨意設(shè)置各種配置屬性。下面的例子展示了如何在代碼中修改Hazelcast的配置參數(shù)。
/** 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) {// 創(chuàng)建默認(rèn)config對(duì)象Config config = new Config();// 獲取network元素<network></network>NetworkConfig netConfig = config.getNetworkConfig();System.out.println("Default port:" + netConfig.getPort());// 設(shè)置組網(wǎng)起始監(jiān)聽(tīng)端口netConfig.setPort(9701);System.out.println("Customer port:" + netConfig.getPort());// 獲取join元素<join></join>JoinConfig joinConfig = netConfig.getJoin();// 獲取multicast元素<multicast></multicast>MulticastConfig multicastConfig = joinConfig.getMulticastConfig();// 輸出組播協(xié)議端口System.out.println(multicastConfig.getMulticastPort());// 禁用multicast協(xié)議multicastConfig.setEnabled(false);// 初始化HazelcastHazelcast.newHazelcastInstance(config);} }????上面的例子中,我們首先從Config中獲取了NetworkConfig實(shí)例,然后調(diào)用NetworkConfig::setPort方法將集群的監(jiān)聽(tīng)起始端口設(shè)置為9701(默認(rèn)為5701)。運(yùn)行以上代碼會(huì)輸出以下片段內(nèi)容:
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配置與源碼配置? ??
????看到這兄弟可能要問(wèn)了:“又是XML配置,又是代碼級(jí)配置的,他兩到底啥關(guān)系呢?”。其實(shí)他兩是相輔相成的,既可以只用XML配置、也可以只在代碼中進(jìn)行配置、還可以兩者混合使用——先加載XML配置再對(duì)其進(jìn)行修改以滿足各種需要。
一個(gè)簡(jiǎn)單的例子
我們先看一個(gè)簡(jiǎn)單的例子,再深入了解Hazelcast實(shí)現(xiàn)XML到Java對(duì)象映射的原理。
<!-- XML配置 --> <hazelcast><network><join><multicast enabled="true"><multicast-group>224.2.2.3</multicast-group><multicast-port>54327</multicast-port></multicast></join></network> </hazelcast> // 代碼讀取數(shù)據(jù) Config config = new Config(); NetworkConfig networkConfig = config.getNetworkConfig(); JoinConfig joinConfig = networkConfig .getJoin(); MulticastConfig multicastConfig = joinConfig.getMulticastConfig(); int multicastPort = multicastConfig.getMulticastPort();? ?在上面這個(gè)XML配置和代碼的例子中,<hazelcast></hazelcast>對(duì)應(yīng)Java中Config對(duì)象,而<hazelcast>中包含<network></network>,因此Config::getNetwork方法可以獲取NetworkConfig對(duì)象的實(shí)例。繼續(xù)往下,<network>中包含<join></join>,因此NetworkConfig::getJoin可以得到JoinConfig。因?yàn)?lt;join>包含<multicast></multicast>,所以JoinConfig::getMulticastConfig可以得到MulticastConfig。
? ? 看到這里應(yīng)該都明白了吧:就是每個(gè)XML元素對(duì)應(yīng)一個(gè)Java實(shí)體或數(shù)據(jù),只要按照XML配置文件的樹形關(guān)系來(lái)調(diào)用get或set,就可以在源碼中獲取和設(shè)置所有配置數(shù)據(jù)。
XML和源碼配置的映射關(guān)系
? ? 友情提示:如果僅僅是想了解如何使用Hazelcast,建議直接跳過(guò)這一段。對(duì)XML定義、DTD、XSD不了解的話看多了反而容易混亂。
????前文已經(jīng)提到Hazelcast的配置文件已經(jīng)預(yù)定義了所有要使用的 參數(shù)(對(duì)應(yīng)XML的Element和Attribuet),定義文件是hazelcast-<version>.jar包中的hazelcast-3.*.xsd(目前是3.6版本)。XSD文件中所有?類型(XSD:Type)不為 預(yù)定義類型(xs:boolean、xs:unsignedInt?等)的 元素(XSD:Element)映射到Java中都對(duì)應(yīng)一個(gè) 實(shí)體(Entity或Pojo)。如果 元素 中還包含 類型?不為預(yù)定義類型的 元素,則對(duì)應(yīng)到Java數(shù)據(jù)結(jié)構(gòu)時(shí)?實(shí)體?中還包含另外一個(gè) 實(shí)體。若XSD文件中定義的 元素類型?為 預(yù)定義類型,則對(duì)應(yīng)一個(gè)Java基本數(shù)據(jù)值(int、String等)。
? ? 例如下面這些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,因此他是一個(gè)名為NetworkConfig的實(shí)體。XML文件中在<network>元素內(nèi)還有一個(gè)<join></join>元素,<join>元素的type為join,因此調(diào)用NetworkConfig::getJoin方法可以得到一個(gè)JoinConfig實(shí)例。以此類推,<join>內(nèi)的<multicast></multicast>元素也是一個(gè)名為MulticastConfig的實(shí)體,而<multicast>中的<multicast-port></multicast-port>對(duì)應(yīng)一個(gè)Java的基本數(shù)據(jù)值——int,因?yàn)樗赬SD中的類型為xs:unsignedShort。
? ? 如果使用的XML配置文件中出現(xiàn)了XSD文件中沒(méi)有定義的元素和屬性,在解析過(guò)程中會(huì)拋出meaningful異常。
Hazelcast配置文件詳解
? ? 前面通過(guò)幾個(gè)例子介紹了Hazelcast如何配置,后面的篇幅將會(huì)逐一介紹Hazelcast所有配置細(xì)節(jié)及其參數(shù)定義。如果某位仁兄現(xiàn)在已經(jīng)需要將Hazelcast引入到現(xiàn)在的項(xiàng)目中,建議您仔細(xì)閱讀。? ??
加載配置文件
? ? 當(dāng)調(diào)用Hazelcast.newHazelcastInstance()或Hazelcast.newHazelcastInstance(null)時(shí),Hazelcast會(huì)從指定的路徑加載XML配置文件或者加載默認(rèn)配置文件。執(zhí)行過(guò)程如下。
? ? 首先,可以通過(guò)系統(tǒng)配置參數(shù)(system property)指定XML配置文件的加載路徑。Hazelcast將在創(chuàng)建實(shí)例時(shí)檢查是否設(shè)置了"hazelcast.config"這個(gè)啟動(dòng)參數(shù)并引用。可以通過(guò)Jvm 參數(shù)或 System參數(shù)來(lái)指定它:
#!/bin/sh java?-Dhazelcast.config=/user/my_hazelcast_config.xml ....? ? 或
// Java System.setProperty( "hazelcast.config", "/user/my_hazelcast_config.xml" );?? ? 其次,如果沒(méi)有設(shè)置這個(gè)參數(shù)或者指定路徑的文件不存在,Hazelcast會(huì)搜尋當(dāng)前classpath路徑檢查是否存在一個(gè)名為“hazelcast.xml”,有則使用。
? ? 最后,如果通過(guò)以上2個(gè)步驟都沒(méi)有加載到配置文件,則使用jar包中的“hazelcast-default.xml”。
在編碼中加載配置文件
? ? 除了上面指定系統(tǒng)參數(shù)的方法,還可以通過(guò)編碼實(shí)現(xiàn)加載配置文件。Hazelcast提供了多種初始化配置文件的方法,主要有:ClasspathXmlConfig、FileSystemXmlConfig、UrlXmlConfig、InMemoryXmlConfig、XmlConfigBuilder。
? ? 得到Config實(shí)例之后使用?HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance(config)可以創(chuàng)建HazelcastInstance實(shí)例。
? ? 在Config中使用Config::setInstanceName方法可以設(shè)置實(shí)例名稱。此后使用這個(gè)名稱可以獲取同一個(gè)HazelcastInstance 實(shí)例。例如:
//Java // 創(chuàng)建配置 Config cfg = new XmlConfigBuilder(inputStream).build(); // 設(shè)置實(shí)例名稱 config.setInstanceName("my-instance"); // 創(chuàng)建Hazelcast實(shí)例 Hazelcast.newHazelcastInstance(cfg); // 獲取已創(chuàng)建的實(shí)例 Hazelcast.getHazelcastInstanceByName("my-instance");在配置文件中使用通配符
? ? 在XML配置文件中,可以使用通配符*來(lái)匹配某些元素的名稱。例如像下面這樣配置一個(gè)分布式Map的名稱:
<map name="map.*"> ... </map>????在使用時(shí),下面的方法都是獲得同一個(gè)Map。
Map map1 = hazelcastInstance.getMap("map.1");Map map2 = hazelcastInstance.getMap("map.2");Map map3 = hazelcastInstance.getMap("map.3");在配置文件中使用變量
? ? Hazelcast提供了使用變量來(lái)配置XML中元素值的方法,通過(guò)在配置文件中使用${}來(lái)指定變量要替換的參數(shù)。
? ? 首先,可以通過(guò)系統(tǒng)參數(shù)來(lái)設(shè)置Hazelcast參數(shù)。例如像下面這樣設(shè)置變量:
-Dgroup.name=dev -Dgroup.password=somepassword????或
System.setProperty( "group.name", "demo" ); System.setProperty( "group.password", "passwd" );? ? 可以在XML配置文件中可以像下面這樣設(shè)置${}:
<hazelcast><group><name>${group.name}</name><password>${group.password}</password></group> </hazelcast>????在創(chuàng)建配置文件時(shí),${}會(huì)被變量替換。
? ? 其次,可以通過(guò)XML中的<properties></properties>元素配置參數(shù)。如下:
<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>? ? 引入配置文件后,會(huì)將properties中的變量替換到對(duì)應(yīng)的${}中。
? ? 最后,還可以通過(guò)標(biāo)準(zhǔn)的properties文件來(lái)配置參數(shù)。如下面示例代碼:
/** 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;// 構(gòu)建XML配置XmlConfigBuilder builder = new XmlConfigBuilder(path);// 設(shè)置propertiesbuilder.setProperties(getProperties());// 創(chuàng)建Config,此時(shí)會(huì)替換${}Config config = builder.build();// 輸出Config參數(shù)System.out.println(config.getGroupConfig().getName());} catch (FileNotFoundException e) {e.printStackTrace();}}// get Propertiesprivate 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;} }????代碼對(duì)應(yīng)的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>????對(duì)應(yīng)properties文件:
#https://github.com/chkui/hazelcast-demo/blob/master/src/main/resources/properties/variable-config.propertiesgroup.name=demo group.password=demopasswd? ? 上面的代碼先創(chuàng)建了一個(gè)XmlConfigBuilder實(shí)例,然后調(diào)用XmlConfigBuilder::setProperties方法設(shè)置Properties到?XmlConfigBuilder中。在build時(shí),會(huì)用Properties定義的變量替換XML中對(duì)應(yīng)的${}參數(shù)。通過(guò)使用properties來(lái)控制配置參數(shù),我們可以使用更多的工具來(lái)管理Hazelcast配置,例如使用Maven的<resources>元素管理properties。
結(jié)構(gòu)化配置
? ? 和spring的配置文件一樣,Hazelcast的XML配置文件也可以通過(guò)<import>元素來(lái)整合多個(gè)配置文件。例如有下面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>元素同樣支持參數(shù):
<hazelcast><import resource="${param1}-group-config.xml"/><import resource="${param2}-network-config.xml"/> </hazelcast>? ? 有了結(jié)構(gòu)化配置的方法,可以把一份大文檔,劃分成很多相關(guān)部分去維護(hù)。
? ? 至此,Hazelcast的基本配置介紹完畢,后續(xù)的博文會(huì)介紹Hazelcast的各種分布式功能,包括網(wǎng)絡(luò)環(huán)境如何管理,分布式數(shù)據(jù)結(jié)構(gòu)使用(Map、Queue、List、Set、Topic、Semaphore等)、分布式事件驅(qū)動(dòng)、分布式計(jì)算、分布式查詢等等。等哥消息…………。
原文地址:https://www.chkui.com/article/hazelcast/hazelcast_configuration_management
轉(zhuǎn)載于:https://my.oschina.net/chkui/blog/732408
總結(jié)
以上是生活随笔為你收集整理的Hazelcast集群服务(2)——Hazelcast基本配置的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [PE格式分析] 3.IMAGE_NT_
- 下一篇: 如何巧妙的使用ArrayList的Clo