引领先锋|携程基于Quasar协程的NIO实践( 二 )
协程中调用的方法是可以挂起的 。 不同于线程的阻塞会使线程休眠 , 协程在等待异步任务的结果时 , 会通知调度器将自己放入挂起队列 , 释放占用的线程以处理其他的协程 。 异步任务完毕后 , 通过回调将异步结果告知协程 , 并通知调度器将协程重新加入就绪队列执行 。
1.3 Quasar任务调度原理
Quasar()是一个开源的Java协程框架 , 通过利用Java instrument技术对字节码进行修改 , 使方法挂起前后可以保存和恢复JVM栈帧 , 方法内部已执行到的字节码位置也通过增加状态机的方式记录 , 在下次恢复执行可直接跳转至最新位置 。 以如下方法为例 , 该方法分为两步 , 第一步为initial初始化 , 第二部为通过NIO获取网络响应 。
public String instrumentDemo(){initial();String ans = getFromNIO();return ans;}Quasar会在initial前增加一个flag字段 , 表明当前方法执行的位置 。 第一次执行方法时 , 检查到flag为0 , 修改flag为1并继续往下执行initial方法 。 执行getFromNIO方法前插入字节码指令将栈帧中的数据全部保存在一个Quasar自定义的栈结构中 , 在执行getFromNIO后 , 挂起协程 , 让出线程资源 。 直至NIO异步完成后 , 协程调度器将第二次执行该方法 , 检测到flag为1 , 将会调用jump指令跳转到returnans语句前 , 并将保存的栈结构还原到当前栈中 , 最后调用人return ans语句 , 方法执行完毕 。
二、系统异步IO改造在项目中添加Quasar依赖后 , 可以使用Fiber类新建协程 。 建立的方法与线程类似 。
new Fiber(()->{//方法体}).start();2.1 整合Netty与Quasar
系统使用的Http框架是基于Netty的async-http-client() , 该框架提供了异步回调和CompletableFuture两种对响应的异步处理方式 。
CompletableFuture自JDK8推出 , 与之前的Future类最大的不同在于 , 提供了异步任务跨线程的通知和控制机制 。 即 , 任务的等待者可以在CompletableFuture注册任务完成或异常时的回调 , 而执行者也可以通过它通知等待者 。 Quaasr框架对它也做了支持 , 提供了API用于在协程中等待CompletableFuture的结果 。 调用后 , 协程将挂起 , 直至future状态为已完成 。
AsyncCompletionStage.get(future)通过CompletableFuture作为通知中介 , 我们可以将AsyncHttpClient与Quasar做整合 , 挂起协程等待IO结果 。
//创建HttpClientAsyncHttpClient httpClient = Dsl.asyncHttpClient();//创建请求Request request = createRequest();//将网络请求交给HttpClient执行CompletableFuture过程可由下图表示 。
Quasar框架AsyncCompletionStage.get内部完成的工作相当于 , 在HttpClient返回的future上注册回调 , 回调的内容是“IO操作完成后通知调度器唤醒协程” , 这样将NIO异步回调全部操作封装在协程调度器中 , 用户代码看起来是同步等待的形式 , 避免了自行实现回调处理带来的繁琐 , 解决了前文所述的回调地狱 。
推荐阅读
- 引领时尚新时代|她是饶雪漫书中的模特,和鹿晗在一起被赞般配,笑起来碾压林允!
- 引领时尚新时代|传闻她被渣男骗钱骗大肚子,无奈生下孩子给母亲抚养,气质美上天
- 引领时尚新时代|她是典型中国好媳妇,却嫁给相识不到20天的男友,穿搭霸气侧漏
- 引领时尚新时代|她从小就被亲爸说是捡来的,出道10年没谈过恋爱,美得让人着迷
- 「宁静」宁静不管穿了个啥都能引领时髦,嫌T恤配牛仔裤不够炫,再加薄纱
- 引领先锋|扔员工证的工厂到底啥来头?营收超三千亿,与富士康、伟创力齐名
- 国庆:携程发布“2020国庆旅行指北”:“大西北”搜索热度暴增475%
- 新京报|摩登日记|引领潮流的时尚偶像麦当娜
- 山东沂水提倡彩礼费1万以内|临沂沂水倡导婚俗简约 举办集体婚礼引领风尚
- 【山东沂水提倡彩礼费1万以内】临沂沂水倡导婚俗简约 举办集体婚礼引领风尚
