今年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