Vertx-Sync 手册

源文档
[很有趣的一个库,一并翻译了。]

本文依照 知识共享许可协议(署名-非商业性使用-禁止演绎) 发布。


Vertx-sync 是一组工具集,其特点是在不阻塞内核线程的同时,允许用户以同步的方式接收事件、执行异步操作。

简介

比起很多历史遗留的程序库,Vert.x的一个关键优点是完全非阻塞(于内核线程而言)--这使它用少量的内核线程就可以处理大量的并发(例如,很多的连接、消息之类),具有良好的可扩展性。

Vert.x非阻塞性的结果是异步的API 。异步API 可以有多种风格,包括像回调、promise、Rx(Java的风格)。Vert.x在绝大多数地方使用回调(尽管它也支持Rx)。

某些情况下,使用异步API 编程比起直接使用同步API 要更具挑战,特别是当你有好几个操作要按顺序完成时。同时,使用异步API 时,错误的传递也会变得更复杂。

Vertx-sync 可以让你在熟悉的同步风格下继续使用异步API 。

在此,通往自由之路的功臣乃fiber(这个词国内有译作纤程,类似协程-coroutine)。Fiber 是超轻量级的线程,并不是对应于底层的那种内核线程,它们被阻塞时不会导致内核线程也被阻塞。

Vert.x 借助Quasar 库来实现fiber 。

注意:Vertx-sync 当前只适用于Java 。


SyncVerticle

要使用Vertx-sync 库,你的代码需要继承io.vertx.ext.sync.SyncVerticle类,并重载start()方法和stop()方法(stop 非必需)。

这些方法还必须加上@Suspendable的标注。

写好的sync verticle,其部署方法和其他verticle完全一样。


Instrumentation

Vert.x用到了Quasar 库,这个库借助字节码增强(bytecode instrumentation)的技术实现了fiber 。(字节码增强的)工作是在运行时(run-time)由java agent 完成的。

要使这个特性正常工作,需要在启动JVM 时指定quasar-core jar包为java agent jar包:
-javaagent:/path/to/quasar/core/quasar-core.jar

如果你用的是vertx命令行工具,可以在执行vertx前设置环境变量ENABLE_VERTX_SYNC_AGENTture,这样可以启用agent 的配置。

你也可以使用quasar-maven-plugin 达成离线增强(a offline instrumentation, 指非运行时织入字节码)的效果。更多细节请参考 Quasar documentation


获得一次性的异步操作结果

Vert.x 的领域里,很多操作都会接受一个Handler<AsyncResult<T>>作为最后的参数。例如用Vert.x 的 Mongo 客户端执行一次查询或者发送一个event bus 消息然后拿到回应。

Vertx-sync 可以让你用同步的方式拿到这种一次性的异步操作的结果。

这是通过调用Sync.awaitResult 方法达成的。

运行这个方法时,需将想要执行的异步操作以Consumer的形式指定为其参数;handler 参数会在运行时传给此consumer 。

看下面的例子:

EventBus eb = vertx.eventBus();

// Send a message and get the reply synchronously

Message<String> reply = awaitResult(h -> eb.send("someaddress", "ping", h));

System.out.println("Received reply " + reply.body());

上面的例子中,在回应返回前,fiber 会一直被阻塞住;而内核线程不会。


获得一次性的事件

Vertx-sync 也能以同步的方式获得一次性的事件,例如定时器的触发,或者end handler(关于end handler 的例子可以参见Vert.x 核心包文档中 HTTP 服务器与客户端 一节) 的执行。这是通过Sync.awaitEvent 方法达成的。

看下面的例子:

long tid = awaitEvent(h -> vertx.setTimer(1000, h));

System.out.println("Timer has now fired");

事件流

很多时候,Vert.x 的handler 接收到的是事件流,例如event bus 消息的消费者(consumer)、HTTP 服务器里的HTTP 服务端请求(server request)。

Vertx-sync 使你能以同步的方式从这种流中接收事件。

你需要一个同时实现了Handler Receiver接口的HandlerReceiverAdaptor 类实例。Sync.streamAdaptor 方法可以创建这样一个实例。

你可以把它当成一个普通的handler ,然后可以用实现自Receiver 接口的方法来同步地接收事件。

下面是一个 event bus 消息消费者的例子:

EventBus eb = vertx.eventBus();

HandlerReceiverAdaptor<Message<String>> adaptor = streamAdaptor();

eb.<String>consumer("some-address").handler(adaptor);

// Receive 10 messages from the consumer:
for (int i = 0; i < 10; i++) {

  Message<String> received1 = adaptor.receive();

  System.out.println("got message: " + received1.body());

}

使用FiberHandler

如果你想在一般的handler 中使用fiber --例如Http 服务器的请求handler ,那得首先把这个一般的handler 转换为fiber handler 。

Fiber handler 会在fiber 里运行那个一般的handler 。

看例子:

EventBus eb = vertx.eventBus();

vertx.createHttpServer().requestHandler(fiberHandler(req -> {

  // Send a message to address and wait for a reply
  Message<String> reply = awaitResult(h -> eb.send("some-address", "blah", h));

  System.out.println("Got reply: " + reply.body());

  // Now end the response
  req.response().end("blah");

})).listen(8080, "localhost");

更多示例

examples repository 这里有一打示例,展示了vertx-sync 的用法(官方示例简单明了,不妨一览)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容