本文共 3514 字,大约阅读时间需要 11 分钟。
初始化一个vertx实例,
使用一个启动verticle部署多个verticle,每个verticle都有自己的使命,它们公用一个vertx实例, vertx是基于事件驱动,verticle部署时指定接受通知后的下一步操作, 它们之间通过eventbus通信,通过eventbus消息总线异步通知每个verticle进行消息处理; vert.x为verticle提供Event Loop线程执行非阻塞操作, 阻塞操作可以通过vertx实例创建worker-thread线程进行业务相关比较耗时的操作。vertx 线程模型是线程安全的,不需要RD再投入过多的精力考虑多线程下编程的问题,并且初中级程序员也很难写出优雅的多线程代码;vertx框架的扩展组件丰富,支持HTTP2/MONGO/REDIS/CIRCUIT-BREKER/KOTILN/等等
为了充分利用多核CPU的性能,Vert.x中提供了一组Event Loop线程 基于Netty的NioEventLoopGroup实现。
每个Event Loop线程都可以处理事件。为了保证线程安全,防止资源争用, Vert.x保证了某一个Handler总是被同一个Event Loop线程执行, 这样不仅可以保证线程安全,而且还可以在底层对锁进行优化提升性能 注意:在部署Verticle的时候,vert.x会根据配置创建一个Context并绑定到verticle上,以后该verticle绑定的Handler都会在该Context上执行,Context对应唯一一个EventLoop线程,而一个EventLoop线程对应多个Context,so 每个Handler都会在同一个EventLoop线程下执行,从而保证线程的安全Vert.x以非阻塞IO的思想来实现高性能,非阻塞IO的实现,基于Event Loop Vertical和Worker Vertical的分离,
在Vert.x中,Event Loop用于接收,并将短业务操作交由其内部的Vertical来处理,该模块是非阻塞的,这样可以保证请求的处理效率; 阻塞任务通过Vert.x的事件机制脱离当前线程,转移到Worker Vertical中执行,并执行结果返回给Event Loop Vertical。 vert.x-worker-thread vert.x-eventloop-thread 这一过程完成的核心是Event Bus,Event Bus中注册了所有的事件,通过事件匹配完成事件转移和结果返回,从而将整个流程衔接起来。vertx-lang-kotlin-coroutines集成了Kotlin coroutines,用于执行异步操作和事件处理。
这导致看起来像在使用同步执行代码的编程模型,但它并不阻塞内核线程。 vertx-lang-kotlin-coroutines使用协程: 协程是非常轻量级的线程,不同于底层内核线程, 因此当协程需要“阻塞”时,它将被暂停并释放其当前的内核线程,以便另一个协程可以处理事件coroutines是异步回调的替代者
//标准vert.x timerAPI写法vertx.setTimer(1000, tid -> { System.out.println("Event fired from timer")});//使用coroutines launch(vertx.dispatcher()) { awaitEvent{ handler -> vertx.setTimer(1000, handler) } println("Event fired from timer") }
The awaitEvent function suspends the execution of the coroutine until the timer fires and returns the value that was given to the handler
awaitEvent方法暂停执行协程,直到定时器返回结果给handler
标准的vert.x timerAPI是异步的,且逻辑也是写在回调Handler里的,所以代码看起来会是嵌套的,
但是上面的coroutines例子你会发现没有这个问题,所有的逻辑都是在变量timerId后面, 也就是说逻辑是线性的,直觉符合人类的思考方式,你会觉得上面的会阻塞1秒下面才会执行。还需要想办法把vert.x的回调型API改成同步的,所以这里你会看到一个新的方法awaitEvent,
通过这个方法可以把handler(异步回调)以协程的方式进行处理,从而可以直接得到一个返回值,使之变成同步返回awaitResult
vertx 中存在很多这种Handler< AsynResult<…>>
可以通过awaitResult 绑定该种类型的handler,以顺序的方式获取异步代码的执行结果
launch or suspend
可以通过这两种方式在代码中使用协程,如下:
/** *awaitResult方法暂停执行协程,直到定时器返回结果给handler */ suspend fun awaitResultExample(){ val eb = vertx.eventBus() //注册消息的监听 val message : MessageConsumer= eb.consumer ("com.sdmjhca") message.handler { message -> println("msg received : ${message.body()}"+System.currentTimeMillis()) message.reply("地瓜,你好,收到") } //开始发送消息,等待响应 val res = awaitResult > { handler -> println(Thread.currentThread().name+"开始发送消息") //eb.send("com.sdmjhca","土豆,你好,收到请回复") //调用eb发送消息,并将发送的结果,付给handler eb.send("com.sdmjhca","土豆,你好,收到请回复",handler) } println("收到土豆的回复 : ${res.body()}"+System.currentTimeMillis()) }--------------------------------------/** * process one-shot event * Calling launch allows running Vert.x handlers on a coroutine * with no suspend */ fun awaitEventExample(){ launch(vertx.dispatcher()){ var timerId = awaitEvent { h: Handler -> vertx.setTimer(1000,h) println("定时器将在1秒后执行="+System.currentTimeMillis()) } println("定时器执行完成Event fired from timer with id $timerId -------------"+System.currentTimeMillis()) } }
vertx 相关代码的demo :
转载地址:http://lkjdi.baihongyu.com/