首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Wicket集群会话存储、页存储、数据存储

Wicket集群会话存储、页存储、数据存储
EN

Stack Overflow用户
提问于 2014-07-28 09:04:44
回答 1查看 2.2K关注 0票数 4

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

集群中有两个节点,节点一个失败,用户应该能够在没有注意到的情况下继续流,页面处于状态状态,有大量ajax请求。现在,我将wicket会话存储在rmi上的自定义存储中,并试图扩展DiskPageStore。新的挑战是SessionEntry内部类,它仍然被ConcurrentMap所控制。

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

EN

回答 1

Stack Overflow用户

发布于 2016-04-18 11:44:36

我的建议是忘记DiskPageStore和SessionEntry在您的情况。您提到的ConcurrentMap保存在本地堆中。一旦其中一个节点失败,就无法访问它的ConcurrentMap,从ConcurrentMap中引用的Wicket资源将不可能被释放。

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

我已经为生产中的企业级web应用程序中使用的Apache启用了web会话和数据存储集群,并且它一直运行得很好。我使用的软件是:

其思想是使用阿帕奇伊格尼特进行web会话集群,并且按照其对Web会话聚类的说明非常简单。

获得web会话集群后,我将数据存储(其中已经包括页面存储)放入Ignite分布式数据网格,同时禁用Wicket应用程序作用域缓存(以确保所有数据都是群集的)。查看有关Wicket的页面存储的文档,了解如何配置数据存储。

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

代码语言:javascript
复制
import java.util.concurrent.TimeUnit;
import javax.cache.expiry.Duration;
import javax.cache.expiry.TouchedExpiryPolicy;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.cache.CacheMemoryMode;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.eviction.lru.LruEvictionPolicy;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.wicket.pageStore.IDataStore;
import org.apache.wicket.pageStore.memory.IDataStoreEvictionStrategy;
import org.apache.wicket.pageStore.memory.PageTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class IgniteDataStore implements IDataStore {

    private static final Logger log = LoggerFactory.getLogger(IgniteDataStore.class);

    private final IDataStoreEvictionStrategy evictionStrategy;
    private Ignite ignite;
    IgniteCache<String, PageTable> igniteCache;

    public IgniteDataStore(IDataStoreEvictionStrategy evictionStrategy) {
        this.evictionStrategy = evictionStrategy;

        CacheConfiguration<String, PageTable> cacheCfg = new CacheConfiguration<String, PageTable>("wicket-data-store");
        cacheCfg.setCacheMode(CacheMode.PARTITIONED);
        cacheCfg.setBackups(1);

        cacheCfg.setMemoryMode(CacheMemoryMode.OFFHEAP_VALUES);
        cacheCfg.setOffHeapMaxMemory(2 * 1024L * 1024L * 1024L); // 2 Gigabytes.

        cacheCfg.setEvictionPolicy(new LruEvictionPolicy<String, PageTable>(10000));

        cacheCfg.setExpiryPolicyFactory(TouchedExpiryPolicy.factoryOf(new Duration(TimeUnit.SECONDS, 14400)));
        log.info("IgniteDataStore timeout is set to 14400 seconds.");

        ignite = Ignition.ignite();
        igniteCache = ignite.getOrCreateCache(cacheCfg);
    }

    @Override
    public synchronized byte[] getData(String sessionId, int id) {
        PageTable pageTable = getPageTable(sessionId, false);
        byte[] pageAsBytes = null;
        if (pageTable != null) {
            pageAsBytes = pageTable.getPage(id);
        }
        return pageAsBytes;
    }

    @Override
    public synchronized void removeData(String sessionId, int id) {
        PageTable pageTable = getPageTable(sessionId, false);
        if (pageTable != null) {
            pageTable.removePage(id);
        }
    }

    @Override
    public synchronized void removeData(String sessionId) {
        PageTable pageTable = getPageTable(sessionId, false);
        if (pageTable != null) {
            pageTable.clear();
        }
        igniteCache.remove(sessionId);
    }

    @Override
    public synchronized void storeData(String sessionId, int id, byte[] data) {
        PageTable pageTable = getPageTable(sessionId, true);
        if (pageTable != null) {
            pageTable.storePage(id, data);
            evictionStrategy.evict(pageTable);
            igniteCache.put(sessionId, pageTable);
        } else {
            log.error("Cannot store the data for page with id '{}' in session with id '{}'", id, sessionId);
        }
    }

    @Override
    public synchronized void destroy() {
        igniteCache.clear();
    }

    @Override
    public boolean isReplicated() {
        return true;
    }

    @Override
    public boolean canBeAsynchronous() {
        return false;
    }

    private PageTable getPageTable(String sessionId, boolean create) {  
        if (igniteCache.containsKey(sessionId)) {
            return igniteCache.get(sessionId);
        }

        if (!create) {
            return null;
        }

        PageTable pageTable = new PageTable();
        igniteCache.put(sessionId, pageTable);
        return pageTable;
    }
}

希望能帮上忙。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24991767

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档