今年4月開始倒騰openfire,過程當中經歷了許多,更學到了許多。特別是在集羣方面有了不少的認識,真正開始認識到集羣的概念及應用方法。java
在openfire中使用的集羣解決方案是代理+分佈式內存。所謂代理即是經過一個入口轉發請求到多個服務實例。而分佈式內存就是解決服務實例間數據共享問題。經過這兩步就能夠搭建出一套水平擴展的集羣系統。node
openfire使用的分佈式內存計算框架是hazelcast,並不瞭解它,大概只知道它是分佈式網格內存計算框架。聽許多openfire開發者都吐槽hazelcast有許多問題,集羣效果上不太好,也所以意外間的發現了Ignite。git
Ignite是apache基金的一個開源項目,功能與hazelcast很是相似:github
Apache Ignite內存數據組織是高性能的、集成化的以及分佈式的內存平臺,他能夠實時地在大數據集中執行事務和計算,和傳統的基於磁盤或者閃存的技術相比,性能有數量級的提高。web
特性:
能夠將Ignite視爲一個獨立的、易於集成的內存組件的集合,目的是改進應用程序的性能和可擴展性,部分組件包括:spring
已經有國內的大神作了翻譯,能夠看看這個連接:https://www.zybuluo.com/liyuj/note/481591
這裏面有Ignite的手冊,介紹的仍是比較清楚的。express
只要少許的代碼咱們就能夠將Ignite應用到本身的系統中,好比我須要作一個緩存。apache
<dependency> <groupId>org.apache.ignite</groupId> <artifactId>ignite-core</artifactId> <version>${ignite.version}</version> </dependency>
這樣就行啦。。緩存
Ignite ignite = Ignition.start();
這一句代碼就啓動了一個Ignite節點,整個過程不須要配置就這麼簡單的跑起來了。session
好了,再建立一個緩存用來存用戶的ID和姓名:
IgniteCache<Integer, String> cache = ignite.getOrCreateCache("userInfo");
cache.put(1, "小明");
這樣就over了,是否是感受和使用hashmap差很少?但重要的是什麼,若是有另一個ignite節點起來了,它們會自動發現並組成集羣,那麼userInfo這個緩存就會自動的完成分佈式存儲咯。
只不過有點問題,默認狀況下緩存模式是分區模式,固然分區模式下須要設置緩存的備份數量backups,若是不設置的話緩存並不會在其餘節點上作備份。
什麼意思呢?就是說系統中有一個節點node1,這時候存了userInfo,此時node2啓動了,而且自動發現後node1和node2創建了集羣,不過node1忽然掛了,此時系統會訪問node2的數據,結果就失敗啦。也就是說默認配置下數據是不會自帶分佈式存儲的。須要作一下緩存的配置才行。
能夠在建立緩存的時候指定一下緩存的配置:
CacheConfiguration cfg = new CacheConfiguration(); cfg.setCacheMode(CacheMode.PARTITIONED); cfg.setBackups(1); cfg.setName("userInfo"); IgniteCache<Integer, String> cache = ignite.getOrCreateCache(cfg); cache.put(1, "小明");
Ignite提供了三種不一樣的緩存操做模式,分區、複製和本地。能夠參考這裏的介紹:https://www.zybuluo.com/liyuj/note/393469#33緩存模式
我最開始拿Ignite的用處主要是作緩存使用,並且其支持JCache的特性和集羣化作緩存很是合適,特別是將來部署成分佈式也很平滑。可是目前我使用的還比較淺,估計入門都不算,這也可見Ignite使用多麼簡單,基本上看看手冊就能夠上手了。
這些天我仍是想嘗試一下Ignite的WebSession的集羣功能,爲之後Web系統集羣作一個基礎。以前的使用Redis的方案總以爲不是特別爽,雖然對代碼的侵入性低,但不是java系列的。目前Ignite官方給出了WebSession集羣的指南:https://www.zybuluo.com/liyuj/note/393469#318web會話集羣化
我根據這個指南作了嘗試,效果基本達到,可是對於像我這樣的初學者面對這個手冊會遇到一些問題。首先在配置後啓動系統後發現會報一個異常:
嚴重: Exception starting filter IgniteWebSessionsFilter class org.apache.ignite.IgniteException: Cache for web sessions is not started (is it configured?): partitioned at org.apache.ignite.cache.websession.WebSessionFilter.initCache(WebSessionFilter.java:336) at org.apache.ignite.cache.websession.WebSessionFilter.init(WebSessionFilter.java:292) at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279) at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:260) at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:105) at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4854) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5546) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1575) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1565) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)
這個問題我查了蠻久,後來仍是@李玉珏給了指導解決了。問題的緣由是WebSessionFilter初始化時找不到對應的緩存。我查看了代碼:
@SuppressWarnings("unchecked") void initCache() { cache = webSesIgnite.cache(cacheName); binaryCache = webSesIgnite.cache(cacheName); if (cache == null) throw new IgniteException("Cache for web sessions is not started (is it configured?): " + cacheName);
報錯的代碼就是由於cache爲null致使的。這裏比較重要的是
cache = webSesIgnite.cache(cacheName);
在前面舉的例子中咱們獲取一個緩存是用getOrCreateCache方法,這個方法會在緩存不存在的狀況下自動建立一個緩存,可是cache方法卻不會。因此要解決這個問題就是要在Ignite啓動後先把緩存建立好。
可是整個過程咱們並無手動顯式的去啓動Ignite,是WebSessionFilter在Init的時候獲取的,因此咱們能夠經過配置的方式將緩存首先建立。
如何指定Ignite XML文件加載?
須要建立一個XML文件,並將其放在Web目錄的META-INF目錄下面,好比建立一個default-config.xml文件,文件內容以下:
<?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean class="org.apache.ignite.configuration.IgniteConfiguration" > <property name="cacheConfiguration"> <bean class="org.apache.ignite.configuration.CacheConfiguration"> <!-- Cache name. --> <property name="name" value="partitioned"/> <property name="cacheMode" value="PARTITIONED"/> <property name="backups" value="1"/> </bean> </property> </bean> </beans>
這裏的配置意思是建立一個name爲partitioned的緩存,使用分區模式,備份數爲1.再次啓動web程序就能夠啦。
對於使用Spring的應用是能夠集成Ignite緩存的,配置方式須要經過一個緩存抽象類來完成org.apache.ignite.cache.spring.SpringCacheManager。
在本身項目的Spring裏作以下配置:
<!-- Provide configuration bean. --> <bean id="cacheManager" class="org.apache.ignite.cache.spring.SpringCacheManager"> <property name="configuration"> <bean class="org.apache.ignite.configuration.IgniteConfiguration"> <property name="cacheConfiguration"> <bean class="org.apache.ignite.configuration.CacheConfiguration"> <!-- Cache name. --> <property name="name" value="partitioned"/> <property name="cacheMode" value="PARTITIONED"/> <property name="backups" value="1"/> </bean> </property> </bean> </property> </bean>
能夠看到Ignite的使用仍是很是簡單的,特別是其配置的簡單性,很容易上手,輕鬆就搭建了一套分佈式內存系統。並且對於Ignite來講還有更多的高級特性,參考"特性"部分。接下來還須要再繼續深刻了解。
另外對於做爲緩存使用我在j2cache開源項目裏有簡單的集成,代碼能夠看:https://github.com/mini188/j2cache