我有一个客户端应用程序每1秒从网址请求一些信息。
在服务器(servlet和JSP应用程序)中,为了避免在没有必要时访问数据库,它已经实现了下一个解决方案。这是一个片段:
//a static HashMap where we save the last record inserted in db
public static Map<Long, Long> VALUES = new HashMap<Long, Long>();
// A lastRecordRead sent by the client
if (VALUES.get(id) != lastRecordRead) {
//Access the database to get some information
//cause the last value read is different from the last record inserted
...
}else{
//Do nothing
//It's not necessary access DB cause the parameters match
}
这在开发环境中按预期工作。
当我们拥有集群环境时,问题就出现了。我们将服务器部署在两个节点中(使用jboss),每个节点都有自己的HashMap,以及它自己的值。因此,根据我们攻击的节点,我们可以 得到不同的价值......
¿有没有办法在两个节点之间共享这个HashMap?我正在寻找一些答案,我不需要更新2个地图,这意味着节点之间没有呼叫......
任何形式的帮助都将受到赞赏。
编辑:我现在正在玩HazelCast,看起来很容易,我担心我做错了什么......在我的服务器中,我现在使用HazelCast而不是HasMap:
public static Map<Long, Long> VALUES = (Hazelcast.newHazelcastInstance(new Config())).getMap("VALUES");
插入记录时:
if (((VALUES.get(id) == null)||(VALUES.get(id) < lastIdInserted))) {
VALUES.put(id, lastIdInserted);
}
客户端应用程序调用服务器时:
// A lastRecordRead sent by the client
if (VALUES.get(id) != lastRecordRead) {
//Access the database to get some information
//cause the last value read is different from the last record inserted
...
}else{
//Do nothing
//It's not necessary access DB cause the parameters match
}
我认为,就是这样。任何人都可以确认这是否正常或我错过了什么......?这个解决方案真的遍布整个节点吗?我一直在用2只猫咪进行测试,它确实有效,但是它能用于不同的ips吗?
答案 0 :(得分:4)
您有两种选择:
......还有很多其他人。
使用'publisher-subscriber'概念并按事件更新每个HashMap实例。这通常通过一些JMS代理实现:
http://docs.oracle.com/cd/E19717-01/819-7759/aerbk/index.html https://www.rabbitmq.com/tutorials/tutorial-three-java.html
选择取决于您的需求:对于最快的读取和搜索,没有网络延迟但更新缓慢 - 使用第二个选项。对于不经常更改的数据,这是一个很好的解决方案:地理名称,地址等。
作为一般情况 - 使用第一拳。
答案 1 :(得分:2)
您需要使用分布式HashMap 。那里有一些框架。 hazelcast就是一个例子。您可以使用Hazelcast社区版(免费)。
您也可以使用Redisson(分布式计算):https://github.com/mrniko/redisson
答案 2 :(得分:0)
你确定进入数据库是一个你无法负担的开销吗?如果您使用数据库,那么您可以确保正确处理锁定和并发访问。使用HashMap意味着您必须自己处理并发读写访问,这可能会显着增加您的设计,构建和测试工作。
你确定这不是一个不成熟的优化吗?