Vert.x内核模块 共享数据,分布式锁,集群范围计数器(十二)

Vert.x使用共享数据

共享数据包含允许,在应用的不同部分,或者在同一个Vert.x实例的不同应用中,或者集群中的不同Vert.x实例中安全共享数据的功能。共享数据包括本地共享映射表,分布的,群集范围的映射表,异步群集范围的锁和异步群集范围的计数器。

重要:分布式数据结构的行为依赖于你使用集群管理器。在面对网络分区时,备分(复制)和行为由集群管理器及其配置进行定义。参考集群文档以及下面的框架文档。

 本地共享映射表

本地共享映射表允许在同一个Vert.x实例不同的事件循环中安全共享数据(例如不同的verticle)。本地共享映射仅容许特定的数据类型用作键和值。这些类型必须是不可变的,或者是象Buffer能被复制的特定其他类型,在后一种情况下,在向本地映射中添加时键和值将会被复制。这种方法能确保,在你的Vert.x应用的不同线程间没有对可变状态的共享访问。所以,不用担心通过同步访问保护状态。

这时一个使用共享本地映射的例子:

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 tomap

// 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");

 群集范围同步映射

群集范围同步映射允许群集里任意节点设置和接收数据。这使得在集群服务器管理的Vert.x应用保存会话状态时真得有用。可以调用getClusterWideMap方法获取AsyncMap实例。获取映射是异步的,这会导致在你指定的处理器得到AsyncMap。这是一个例子:

SharedData sd = vertx.sharedData();

 sd.<String,String>getClusterWideMap("mymap", res -> {

  if(res.succeeded()) {

   AsyncMap<String, String> map = res.result();

  } else{

    //Something went wrong!

  }

});

 向映射中设置数据

调用put方法向映射中添加数据。实际的put方法是异步的,一旦完成添加将会通知处理器。

map.put("foo", "bar",resPut -> {

  if(resPut.succeeded()) {

    //Successfully put the value

  } else{

    //Something went wrong!

  }

});

 从映射中获取数据

用get方法从映射中获取数据。

实际的get异步执行,在调用get一些时间后,将会调用处理器并传入获得的数据。

map.get("foo", resGet -> {

  if(resGet.succeeded()) {

    //Successfully got the value

   Object val = resGet.result();

  } else{

    //Something went wrong!

  }

});

其他操作

可以从异步的映射中移除实体,清除映射并获取大小。参见API文档获取更多信息。

 群集范围的锁

群集范围的锁允许在整个群集里包含排他锁,这为在任何时间,应用仅需要在群集中的一个节点做些事或访问资源是有用的。群集范围的锁有一个异步API,与其他阻塞调用线程直到获取锁的大部分API不同。

使用getLock获取锁。这不会阻塞,但是一旦获取锁,传入Lock实例的处理器将被调用,预示着现在你获得了锁。在你获得了锁,没有调用者,集群的任何地方能获取这个锁。在用完锁后,调用release方法释放锁。接着另外调用者获得锁。

sd.getLock("mylock", res -> {

  if(res.succeeded()) {

    //Got the lock!

    Locklock = res.result();

     // 5seconds later we release the lock so someone else can get it

    vertx.setTimer(5000, tid -> lock.release());

   } else{

    //Something went wrong

  }

});

在获取锁时可以设置超时。如果超时时间内获取锁失败,将会调用超时处理器处理失败。

sd.getLockWithTimeout("mylock",10000, res -> {

  if(res.succeeded()) {

    //Got the lock!

    Locklock = res.result();

   } else{

    //Failed to get lock

  }

});

群集范围计数器

跨应用的不同节点维护一个原子的计数据通常很有用。用Counter做这件事,用getCounter方法获取Counter实例:

sd.getCounter("mycounter", res ->{

  if(res.succeeded()) {

   Counter counter = res.result();

  } else{

    //Something went wrong!

  }

});

一旦有了Counter实例,就可以获取当前计数,用多种方法原子增加或减少,或给其加上一个值。参看API文档获取更多信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值