博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vertx框架编程思想
阅读量:4039 次
发布时间:2019-05-24

本文共 3514 字,大约阅读时间需要 11 分钟。

vertx框架编程思想

vert.x编程简介:

初始化一个vertx实例,

使用一个启动verticle部署多个verticle,每个verticle都有自己的使命,它们公用一个vertx实例,
vertx是基于事件驱动,verticle部署时指定接受通知后的下一步操作,
它们之间通过eventbus通信,通过eventbus消息总线异步通知每个verticle进行消息处理;
vert.x为verticle提供Event Loop线程执行非阻塞操作,
阻塞操作可以通过vertx实例创建worker-thread线程进行业务相关比较耗时的操作。

为什么选用vertx框架

vertx 线程模型是线程安全的,不需要RD再投入过多的精力考虑多线程下编程的问题,并且初中级程序员也很难写出优雅的多线程代码;vertx框架的扩展组件丰富,支持HTTP2/MONGO/REDIS/CIRCUIT-BREKER/KOTILN/等等

vert.x线程安全的线程模型

为了充分利用多核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线程下执行,从而保证线程的安全

vertx事件模型流程

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结合kotlin-coroutines

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") }
  • awaitEvent

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/

你可能感兴趣的文章
linux printf获得时间戳
查看>>
C语言位扩展
查看>>
linux dump_backtrace
查看>>
linux irqdebug
查看>>
git 常用命令
查看>>
linux位操作API
查看>>
uboot.lds文件分析
查看>>
uboot start.s文件分析
查看>>
没有路由器的情况下,开发板,虚拟机Ubuntu,win10主机,三者也可以ping通
查看>>
本地服务方式搭建etcd集群
查看>>
安装k8s Master高可用集群
查看>>
忽略图片透明区域的事件(Flex)
查看>>
忽略图片透明区域的事件(Flex)
查看>>
AS3 Flex基础知识100条
查看>>
Flex动态获取flash资源库文件
查看>>
flex中设置Label标签文字的自动换行
查看>>
Flex 中的元数据标签
查看>>
flex4 中创建自定义弹出窗口
查看>>
01Java基础语法-11. 数据类型之间的转换
查看>>
01Java基础语法-13. if分支语句的灵活使用
查看>>