引领先锋|携程基于Quasar协程的NIO实践
IO密集型系统在高并发场景下 , 会有大量线程处于阻塞状态 , 性能低下 , JAVA上成熟的非阻塞IO(NIO)技术可解决该问题 。 目前Java项目对接NIO的方式主要依靠回调 , 代码复杂度高 , 降低了代码可读性与可维护性 。 近年来Golang、Kotlin等语言的协程(Coroutine)能达到高性能与可读性的兼顾 。
本文利用开源的Quasar框架提供的协程对系统进行NIO改造 , 解决以下两个问题:
1)提升单机任务的吞吐量 , 保证业务请求突增时系统的可伸缩性 。
2)使用更轻量的协程同步等待IO , 替代处理NIO常用的异步回调 。
一、Java异步编程与非阻塞IO本文改造的系统处理来自前台的任务 , 通过HTTP请求对端服务 , 还通过RPC调用内部服务 。 当业务高峰时 , 系统会遇到瞬时并发任务量数十倍激增的情况 , 系统的线程数量急剧增加造成性能下降 。 为此 , 不得不扩容以保证业务高峰时期的性能 。
基于epoll的NIO框架Netty在一些框架级别的应用中已经得到了广泛使用 , 但在快速迭代的业务系统中的应用依然有一定的局限性 。 NIO 消除了线程的同步阻塞 , 意味着只能异步处理IO的结果 , 这与业务开发者顺序化的思维模式有一定差异 。 当业务逻辑复杂以及出现多次远程调用的情况下 , 多级回调难以实现和维护 。
1.1 Java中的异步工具
Java项目大多使用JDK8 , 除线程外可以获得的异步的编程支持包括CompletableFuture , 以及开源的RxJava、Vert.x等反应式编程框架等 。 这些工具使用了基于响应式编程的链式调用逐级传递事件 , 未从根本解决回调问题 。
如下为将一段简单的逻辑判断使用CompletableFuture进行异步改造后的对比 。 原始版本使用getA方法获得第一步的请求结果 , 根据其相应选择使用getB1还是getB2获取第二步的响应作为结果 。
HttpResponse a = getA();HttpResponse b ;if(a.getBody().equals("1")){b=getB1();}else{b=getB2();}String ans=b.getBody();首先将三个获取响应的方法改为异步 。 此处假设getB1与getB2内部已经具有复杂逻辑 , 且不属于同一领域 , 不适合合并为一个方法 。
private CompletableFuture getA();private CompletableFuture getB1();private CompletableFuture getB2();然后使用CompletableFuture的链式调用 , 将两个步骤组合起来:
String ans = getA().thenCompose(a -> {if (a.getBody().equals("1")) {return getB1();} else {return getB2();}}).get().getBody();使用CompletableFuture的链式回调后 , 代码变得不友好 。 RxJava等框架同样具有这个问题 。 这类反应式的编程工具更适合于数据流的传递 。 对于if/else、switch/case , 乃至while/for、break/continue这类过程控制语句 , 实现与维护的难度都很大 。 业务系统需要类似于线程的同步等待 , 同时具有低资源消耗的编码工具 , 配合 NIO使用 。 当时使用NIO时 , 由于可以不占用线程 , 可以使用一种资源消耗更小的协程来等待 。
1.2 协程
协程是一种进程自身来调度任务的调度模式 。 协程与线程不同之处在于 , 线程由内核调度 , 而协程的调度是进程自身完成的 。 协程只是一种抽象 , 最终的执行者是线程 , 每个线程只能同时执行一个协程 , 但大量的协程可以只拥有少量几个线程执行者 , 协程的调度器负责决定当前线程在执行那个协程 , 其余协程处于休眠并被调度器保存在内存中 。
和线程类似 , 协程挂起时需要记录栈信息 , 以及方法执行的位置 , 这些信息会被协程调度器保存 。 协程从挂起到重新被执行不需要执行重量级的内核调用 , 而是直接将状态信息还原到执行线程的栈 , 高并发场景下 , 协程极大地避免了切换线程的开销 。 下图展示了协程调度器内部任务的流转 。
推荐阅读
- 引领时尚新时代|她是饶雪漫书中的模特,和鹿晗在一起被赞般配,笑起来碾压林允!
- 引领时尚新时代|传闻她被渣男骗钱骗大肚子,无奈生下孩子给母亲抚养,气质美上天
- 引领时尚新时代|她是典型中国好媳妇,却嫁给相识不到20天的男友,穿搭霸气侧漏
- 引领时尚新时代|她从小就被亲爸说是捡来的,出道10年没谈过恋爱,美得让人着迷
- 「宁静」宁静不管穿了个啥都能引领时髦,嫌T恤配牛仔裤不够炫,再加薄纱
- 引领先锋|扔员工证的工厂到底啥来头?营收超三千亿,与富士康、伟创力齐名
- 国庆:携程发布“2020国庆旅行指北”:“大西北”搜索热度暴增475%
- 新京报|摩登日记|引领潮流的时尚偶像麦当娜
- 山东沂水提倡彩礼费1万以内|临沂沂水倡导婚俗简约 举办集体婚礼引领风尚
- 【山东沂水提倡彩礼费1万以内】临沂沂水倡导婚俗简约 举办集体婚礼引领风尚
