Vert.x 3学习笔记---08

时间:2022-03-16 18:02:22

Using Shared Data with Vert.x
在功能上vertx允许,在一个应用的不同部分,或者同一个vertx实例的不同应用,再或者一个集群的vertx实例,之间分享数据。
Shared data includes local shared maps, distributed, cluster-wide maps, asynchronous cluster-wide locks and asynchronous cluster-wide counters.

Local shared maps

Local shared maps 允许你在同一个vertx实例的不同event loop之间安全的分享数据。
Local shared maps 只支持特定的几种类型作为key和value。这些类型必须是不可改变的,或者某些其他类型可以被复制到缓冲区。后一种情况下,在数据被放到map之前会被copy。这样我们就可以确保没有共享访问不同线程之间的可变状态。

SharedData sd = vertx.sharedData();

LocalMap<String, String> map1 = sd.getLocalMap("mymap1");

map1.put("foo", "bar"); // Strings are immutable so no need to copy

LocalMap<String, Buffer> map2 = sd.getLocalMap("mymap2");

map2.put("eek", Buffer.buffer().appendInt(123)); // This buffer will be copied before adding to map

// Then... in another part of your application:

map1 = sd.getLocalMap("mymap1");

String val = map1.get("foo");

map2 = sd.getLocalMap("mymap2");

Buffer buff = map2.get("eek");

Cluster-wide asynchronous maps

这个map的作用:在集群中的一个节点上放入数据,在在集群中的另一个节点*问数据。

You get an instance of AsyncMap with getClusterWideMap method。此操作是异步的。

SharedData sd = vertx.sharedData();

sd.<String, String>getClusterWideMap("mymap", res -> {
if (res.succeeded()) {
AsyncMap<String, String> map = res.result();
} else {
// Something went wrong!
}
});

Putting data in a map

map.put("foo", "bar", resPut -> {
if (resPut.succeeded()) {
// Successfully put the value
} else {
// Something went wrong!
}
});

Getting data from a map

map.get("foo", resGet -> {
if (resGet.succeeded()) {
// Successfully got the value
Object val = resGet.result();
} else {
// Something went wrong!
}
});

Other map operations

请查看文档

Cluster-wide locks

全局锁

Cluster-wide locks 允许在集群中设置高级的锁。例如:集群中我们只允许在同一时间一个节点访问某一个资源或者做什么事情。
Cluster-wide locks有一些异步的API。
通过调用getLock方法,得到一个lock。

sd.getLock("mylock", res -> {
if (res.succeeded()) {
// Got the lock!
Lock lock = res.result();//Lock对象的实例

// 5 seconds later we release the lock so someone else can get it
vertx.setTimer(5000, tid -> lock.release());

} else {
// Something went wrong
}
});

如上例。这不会阻塞,但是当lock可用时,handler就会被执行,这也表明,你拥有了这个lock。当你操作完毕后,你需要调用 lock.release() 来释放lock。

我们也可以给获取lock的操作设置超时时间。当超时时,handler也会被调用。

sd.getLockWithTimeout("mylock", 10000, res -> {
if (res.succeeded()) {
// Got the lock!
Lock lock = res.result();

} else {
// Failed to get lock
}
});

Cluster-wide counters

全局计数器

You can do this with Counter.

You obtain an instance with getCounter:

sd.getCounter("mycounter", res -> {
if (res.succeeded()) {
Counter counter = res.result();
} else {
// Something went wrong!
}
});

Once you have an instance you can retrieve the current count, atomically increment it, decrement and add a value to it using the various methods.
使用Counter 的相应方法来增加、减少计数。