Session Wicket群集会话存储、页面存储、数据存储

Session Wicket群集会话存储、页面存储、数据存储,session,cluster-computing,wicket-1.6,Session,Cluster Computing,Wicket 1.6,我正在处理wicket会话存储、数据存储和页面存储的自定义实现。我有cu集群wicket,并使其在以下情况下工作: 集群中有2个节点,其中一个节点出现故障,用户应该能够在不注意的情况下继续流,页面是状态完整的,有大量ajax请求。目前,我正在通过rmi将wicket会话存储在自定义存储中,并尝试扩展DiskPageStore。新的挑战是SessionEntry内部类,它仍然由ConcurrentMap控制 我的问题是:以前有人这样做过吗?您对如何实现这一点有什么建议吗?我的建议是,在您的情况下,

我正在处理wicket会话存储、数据存储和页面存储的自定义实现。我有cu集群wicket,并使其在以下情况下工作:

集群中有2个节点,其中一个节点出现故障,用户应该能够在不注意的情况下继续流,页面是状态完整的,有大量ajax请求。目前,我正在通过rmi将wicket会话存储在自定义存储中,并尝试扩展DiskPageStore。新的挑战是SessionEntry内部类,它仍然由ConcurrentMap控制


我的问题是:以前有人这样做过吗?您对如何实现这一点有什么建议吗?

我的建议是,在您的情况下,忘掉DiskPageStore和SessionEntry。您提到的ConcurrentMap保存在本地堆中。一旦其中一个节点出现故障,就无法访问其ConcurrentMap,从ConcurrentMap引用的Wicket资源将无法释放

因此,在集群环境中,需要对Wicket页面存储进行集群。页面版本可以根据特定策略过期,或者在相应会话过期时故意删除

我已经为生产中的企业web应用程序中使用的ApacheWicket启用了web会话和数据存储集群,并且工作得非常好。我使用的软件有:

  • JDK 1.8.0_60
  • ApacheTomcat 8.0.33()
  • Wicket 6.16(版本6.22.0和7.2.0也应适用)
  • ApacheIgnite1.7.0
  • 负载平衡器:
  • Ubuntu 14.04.1
其思想是用于web会话集群,并且按照其说明进行操作非常简单

一旦对web会话进行集群,我就将数据存储(已经包括页面存储)放入Ignite分布式数据网格,同时禁用Wicket应用程序范围的缓存(以确保所有数据都是集群的)。查看上的文档,了解如何配置数据存储

或者,您应该能够使用Wicket HttpSessionDataStore将数据存储放入会话中。在对会话进行集群时,数据存储将自动进行集群。但是这种方法与ApacheIgnite不兼容。因此,我使用自己的IDataStore接口实现,它将数据存储放入Ignite分布式数据网格。请参见下面的实现

import java.util.concurrent.TimeUnit;
导入javax.cache.expiry.Duration;
导入javax.cache.expiry.TouchedExpiryPolicy;
导入org.apache.ignite.ignite;
导入org.apache.ignite.IgniteCache;
导入org.apache.ignite.Ignition;
导入org.apache.ignite.cache.CacheMemoryMode;
导入org.apache.ignite.cache.CacheMode;
导入org.apache.ignite.cache.execution.lru.LruEvictionPolicy;
导入org.apache.ignite.configuration.CacheConfiguration;
导入org.apache.wicket.pageStore.IDataStore;
导入org.apache.wicket.pageStore.memory.idatastorejectionstrategy;
导入org.apache.wicket.pageStore.memory.PageTable;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
公共类IgniteDataStore实现了IDataStore{
私有静态最终记录器log=LoggerFactory.getLogger(IgniteDataStore.class);
私人最终IDatastore驱逐策略驱逐策略;
私人点火;
点燃缓存点燃缓存;
公共数据存储(IDataStoreRejectionStrategy RejectionStrategy){
this.executionstrategy=executionstrategy;
CacheConfiguration cacheCfg=新的CacheConfiguration(“wicket数据存储”);
cacheCfg.setCacheMode(CacheMode.PARTITIONED);
3.挫折(1);
cacheCfg.setMemoryMode(CacheMemoryMode.OFFHEAP_值);
cacheCfg.setOffHeapMaxMemory(2*1024L*1024L*1024L);//2 GB。
cacheCfg.setexecutionpolicy(新的LruEvictionPolicy(10000));
cacheCfg.setExpiryPolicyFactory(touchedeExpiryPolicy.factoryOf(新的持续时间(TimeUnit.SECONDS,14400));
info(“IgniteDataStore超时设置为14400秒”);
点火=点火。点火();
igniteCache=ignite.getOrCreateCache(cacheCfg);
}
@凌驾
公共同步字节[]getData(字符串sessionId,int id){
PageTable PageTable=getPageTable(sessionId,false);
byte[]pageAsBytes=null;
if(pageTable!=null){
pageAsBytes=pageTable.getPage(id);
}
返回pageAsBytes;
}
@凌驾
公共同步的void removeData(字符串sessionId,int-id){
PageTable PageTable=getPageTable(sessionId,false);
if(pageTable!=null){
pageTable.removePage(id);
}
}
@凌驾
公共同步的void removeData(字符串sessionId){
PageTable PageTable=getPageTable(sessionId,false);
if(pageTable!=null){
pageTable.clear();
}
igniteCache.remove(sessionId);
}
@凌驾
公共同步的void存储数据(字符串sessionId,int-id,字节[]数据){
PageTable PageTable=getPageTable(sessionId,true);
if(pageTable!=null){
pageTable.storePage(id,数据);
逐出策略逐出(页面表);
igniteCache.put(sessionId,pageTable);
}否则{
log.error(“无法在id为“{}”、id为、sessionId为的会话中存储id为“{}”的页面的数据);
}
}
@凌驾
公共同步的void destroy(){
igniteCache.clear();
}
@凌驾
公共布尔值是复杂的(){
返回true;
}
@凌驾
公共布尔值canBeAsynchronous(){
返回false;
}
私有页表getPageTable(字符串sessionId,布尔创建){
if(igniteCache.containsKey(sessionId)){
返回igniteCache.get(sessionId);
}
如果(!创建){
返回null;
}
PageTable PageTable=ne