java如何使用vertx3进行异步CacheOnTopFDatabase查询WithUpdate
下面是一个关于如何使用asyncvertx-mongo-client
在数据库顶部使用内存中缓存的示例。它尽可能的简约。它是完全可执行的,上面有重要的东西
不幸的是,在建立缓存项时,没有任何东西可以阻止对同一密钥的多个数据库访问和缓存插入。使用标准锁定机制是不可能的,因为它会阻止事件循环
我需要一个异步缓存和数据库调用,这样cache.get()
调用,在实际命中数据库的第一个调用之后,将“返回到事件循环”(我可以这么说吗?)正在等待缓存项变为可用。(多么可怕的一句话,我道歉)
我如何做到这一点?我正在考虑研究一些vertx
模块源代码,例如vertx-mongo-client
,以了解它是如何完成的。但如果有人能在这里提供答案,那就太好了
package q;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.mongo.MongoClient;
import java.util.HashMap;
import java.util.Map;
public class ExampleVerticle extends AbstractVerticle
{
@Override
public void start() throws Exception {
MongoClient mongoClient = MongoClient.createShared(vertx, new JsonObject().put("db_name", "example_db"));
SomeCache cache = new SomeCache();
vertx.eventBus().consumer("sesame_street", messageHandler -> {
Integer lookUpKey = Integer.valueOf(messageHandler.body().toString());
JsonObject result = cache.get(lookUpKey);
if(result != null) {
messageHandler.reply(result);
System.out.println("Was served from cache");
} else {
mongoClient.findOne("example_collection", new JsonObject().put("_id", lookUpKey),
new JsonObject(), resultHandler -> {
if(resultHandler.succeeded()) {
messageHandler.reply(resultHandler.result());
cache.put(lookUpKey, resultHandler.result());
System.out.println("Value stored in cache");
} else {
messageHandler.fail(0xBADC0DE, resultHandler.cause().toString());
}
});
}
});
}
static class SomeCache
{
Map<Integer, JsonObject> elMapa = new HashMap<>();
public void put(Integer key, JsonObject value) {
elMapa.put(key, value);
}
public JsonObject get(Integer key) {
return elMapa.get(key);
}
}
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
vertx.deployVerticle(new ExampleVerticle(), completionHandler -> {
if(completionHandler.succeeded()) {
vertx.eventBus().send("sesame_street", 1, replyHandler -> {
if(replyHandler.succeeded()) {
//Comment out this println and you'll maybe see 'Value stored in cache' twice in the console output.
System.out.println("Yes! " + replyHandler.result().body());
vertx.eventBus().send("sesame_street", 1);
}
vertx.close();
});
}
});
}
}
# 1 楼答案
Vertx具有
Asynchronous Lock
的概念。这不会阻塞,但会在获得锁后调用具有锁的处理程序看看:
http://vertx.io/docs/vertx-core/java/#_cluster_wide_locks http://vertx.io/docs/apidocs/io/vertx/core/shareddata/Lock.html