异步服务_微服务全链路异步化实践

1. 背景

随着公司业务的发展,核心服务流量越来越大,使用到的资源也越来越多。在微服务架构体系中,大部分的业务是基于Java 语言实现的,受限于Java 的线程实现,一个Java 线程映射到一个kernel 线程,造成了高并发场景下线程资源的极大浪费,线程成为提高系统并发和吞吐量的瓶颈。

在微服务架构下,使用同步编程模式时不仅造成了资源的极大浪费,并且在流量发生激增波动的时候,受制于系统资源而无法快速的扩容。本文将探索服务异步化在并发、吞吐量方面对系统带来的提升。

2. 如何快速提高服务吞吐量

首先,以微服务架构中的RPC 服务调用举例,测试和探索在微服务架构中,异步架构如何提高服务的吞吐量和并发。ESA Stack 是OPPO 自研的基础框架技术栈,ESA RPC 是自研的RPC 框架。本节测试服务我们使用ESA RPC 搭建。

关于ESA RPC的详情,可以参考我们之前发布的文章《Dubbo协议解析及ESA RPC实践》。

2.1 服务架构

下图所示为测试环境架构。其中Service A 既是服务端也是客户端,它模拟了生产环境中大部分服务的角色。我们对Service A 分别采用同步模型和纯异步模型进行压测,其中纯异步模型包含了客户端、服务端逻辑的异步处理。Service B 模拟一个耗时为N ms 的下游服务,为Service A 的调用提供固定的延时响应。

测试服务器的配置为8 核16G,千兆网卡。

d237b4f5c80dc96f02c74d5e577ef5c0.png

2.2 同步异步模型对比

测试场景1:

并发压测客户端200~8000,服务耗时50ms,分别对同步和异步架构进行压测,对比TPS、服务耗时、CPU 上下文切换;同步模式下,线程数和并发客户端相同;异步模式下,使用框架默认的200 线程。测试数据如下。

8db0a5b7bda6fbbf08dbd6f2a777e720.png

d36691c67133a932a663b0baa1df51d5.png

ec91233e9d3f1d98a37b1f6c42a2c230.png

测试场景2:

并发压测客户端8000,服务耗时50~500ms,分别对同步和异步模式进行压测,对比TPS、服务耗时、CPU 上下文切换;同步模式下服务端8000 线程;异步模式下,使用框架默认的200 线程。

c8cd5eaf17372fe46ad82290e539fb7a.png

c622a82d7b8e16ff6eb6162538a1480b.png

34019fe678ba6c999fae5a5fb7194db8.png

2.3 服务扩展性对比

并发指服务瞬时同时处理的任务数(包含处于IO 等待状态的任务)。服务端设置业务处理线程200,那么同步模式下能提供的并发为200;纯异步模式下服务并发不受线程限制,IO密集型服务尤其收益。在系统流量突增的情景下,异步模式具有更强的可扩展性(Scalability)。

948bba89289c292495eb7f83f4ceaf09.png

2.4 结论

根据上面的测试数据可以做出以下对比:

  • 同步模式,线程数与并发成正比,并发越高对线程的消耗越多

  • 异步模式,提高并发不需要线程增加

  • 同步模式,系统Context Switch 次数随并发提高而快速增加

  • 异步模式,系统Context Switch 次数明显小于同步模式

  • 同步模式,并发超过某个临界点后,服务耗时快速上升,系统吞吐量急剧下降

  • 异步模式,吞吐量随着并发增加,服务耗时上升速度明显低于同步模式

从而得出以下结论:

  • 可以通过异步化微服务架构,提高相同资源配置下的服务吞吐量

  • 随着下游平均耗时的增加,异步化带来的吞吐和耗时的提升作用减小

  • 线程资源有限(内核、内存),不能无限增加来提高并发能力,异步化能极大提高系统瞬时并发能力(Scalability)

结论分析:

  • 高并发下同步模型大量线程在内核态度/用户态、不同CPU 核之间进行切换,Context Switch 增加,系统性能下降

  • 下游平均耗时增加时,系统CPU 繁忙程度降低,Context Switch 对性能系统影响下降

3. 异步模型探索

3.1 阻塞与非阻塞

在操作系统中,线程是CPU 调度的基本单位;阻塞调用是指发起调用后,线程进入阻塞状态(让出CPU),直到获得结果或异常返回;非阻塞调用是指不等待结果,调用不阻塞线程直接返回。

27b0a81f2a2ff1ee25ef21a529fc4bcc.png

3.2 同步与异步

同步和异步关注的是消息通信机制;同步就是在发起调用后就得到返回结果(未必是完整结果),也就是由调用者主动等待结果;异步则是调用在发出之后直接返回,通过信号通知、回调函数处理来通知结果。

40b86770b465ac5b96618cdf27d84d10.png

b505ec66d265142a59ed2b9bab82154b.png

2282ecb9d7f659b0df38526e050fd784.png

5ad261b40e4291f370b13c55a7b49a4c.png

bbd924681e77c0f75b7032e969cdf2f3.png

3.3 四种IO 模型

非IO 系统调用层面, 阻塞/非阻塞和同步/异步基本是同义词;在IO 系统调用层面,同步/异步和阻塞/非阻塞有以下组合:

  • 同步阻塞调用,线程同步等待阻塞调用结果

  • 同步非阻塞调用,线程通过轮训获取非阻塞调用结果

  • 异步阻塞调用,IO 事件阻塞,IO 操作不阻塞

  • 异步非阻塞调用,调用立即返回,信号/回调处理结果

47869cd4d727d6c6f42a686c8da36689.png

我们通过一个简单的客户端来介绍四种IO 模型的代码写法:

55214b2469ccbf0c62964a388f426556.png

同步阻塞IO

6c3098ecbe6ce8aee1dbebe8fefecdff.png

非同步阻塞IO

58fc04d97d9dfd13b555c92ea72d190e.png

多路复用IO

4ef3972a0c2f6adafb14b970e0af7dd4.png

Asynchnorous IO

对四中IO 模型,有以下的对比:

  • 同步阻塞式IO 模型,编程简单但线程阻塞,资源利用率低;

  • 同步非阻塞式IO 模型,需要轮训CPU,浪费资源;

  • 异步非阻塞AIO 模型,不阻塞线程,使用回调方式处理数据,但是编程难度高;

  • 多路复用IO 模型,能够实现异步非阻塞IO,且编程简单,方便实现同步和异步调用,因此成为RPC 框架的首选。

4. 全链路异步编程指南

4.1 全链路组成及现状

微服务架构下的全链路包含了网关层、WEB 服务、RPC 服务、数据层等。目前公司的网关层已经实现了纯异步架构,Web 框架和RPC 框架支持纯异步编程,数据存储层目前异步方案还不成熟。

f7c1e3d7bfca6939d72cda2679adeccb.png

4.2 网关异步化

网关层由于其特殊性,不需要访问业务数据库只做协议转换和流量转发,目前已经使用了纯异步的架构;其IO 密集型的特点,特别适合纯异步的架构,可以极大的节省资源。

4.3 Web 服务异步化

Web 服务作为微服务体系内的重要组成,服务节点众多,传统的Web 服务框架SpringMVC 不支持纯异步化编程,OPPO 自研Web 框架Restlight 支持纯异步编程,且性能远超SpringMVC。下面是性能对比及Restlight 异步实践。

37e3a2cc2cbbcba9bbfe54853ae457c9.png

Restlight 框架异步编程实践:通过Controller 方法返回值区分同步和异步调用,且支持三种异步调用方式,CompletableFuture、ListenableFuture(Guava)、Future(Netty)。

c6a3ddbaeb30e3975f0067f88d8ef1b1.png

4.4 RPC 调用异步化

RPC 调用等待下游response 返回时,线程不应处于block 状态;作为微服务架构中数据流量最大的一部分,RPC 调用异步化的收益巨大;目前ESA RPC 已经具备了纯异步化的能力,提供RPC 调用的服务一般既是客户端也是服务端,因此包含了客户端异步调用能力和服务端异步处理能力;为了兼容存量接口,ESA RPC 既支持CompletableFuture 也支持普通返回值的接口。

客户端异步化实践:底层使用异步非阻塞IO 收发网路数据包,使用CompletableFUture传递IO 事件以实现响应式编程,客户端不被RPC 调用阻塞,可继续调用其他服务。

接口返回CompletableFuture 来实现异步调用:

7dfe0c22157cab0b73cdedfa7b9e527c.png

ed629ca45cc01fc6050b1efc8020ad69.png

普通接口使用ESARpcContext::asyncCall 实现异步调用:

5e78e2e19ae9fa1137299c24ca3e15ba.png

e52a37a5443776e052559cf1762da942.png

服务端异步化实践:通过服务端异步功能返回CompletableFuture 给框架以释放Biz 线程,自定义线程池或者IO 线程池收到下游response 后,完成返回给框架的Future。

接口定义返回CompletableFuture 来实现异步调用:

32e0c897eaaa4c1a4614738af0500bcd.png

55cacbfd69be1ea9aaf3ecef9306ab8c.png

普通接口通过ESARpcContext::startAsync 开启服务端异步:

829236d1719217b780cd5d2f6ed27863.png

e44c54e05278299c2b1950659e4c8bc2.png

4.5 存储层异步化

数据操作是每个请求调用链的终点,纯异步的架构必须使用异步存储层客户端,目前OPPO 没有自研的存储层异步客户端,但业界开源方案欣欣向荣:

  • 数据库:Vert.x JDBC 客户端

  • Redis:Redisson、Lettuce

  • Queue:基本都支持异步调用

691453854bdc9dd89198c8f1d030e26c.png

4.6 纯异步与伪异步

异步调用目的在于防止当前业务线程被阻塞。伪异步将任务包装为Runnable 放入另一个线程执行并等待,当前Biz 线程不阻塞;纯异步为响应式编程模型,通过IO 实践驱动任务完成。他们的区别不在于是否将请求放入另一个线程池执行,而在于是否有线程阻塞等待Response。

9df35c7452c68250d32de7d2618b47e7.png

5. 异步化未来发展

5.1 异步化带来的问题

相比于同步模型,异步模型存在以下问题:

  • 代码可读性和可维护性较差,可能出现Callback Hell

  • 框架SDK 变得复杂,使用门槛增加

  • 业务可能不清楚代码逻辑执行线程

  • 大量的ThreadLocal 需要手动export/import

简单来说,异步编程就是以编程的简单性(simplity)来交换性能(performance)。

5.2 使用协程实现异步非阻塞

目前在其他语言中,Erlang、Go、Kotlin 等都支持了协程,使用协程的好处是在语言层面支持了异步调用,业务代码可以使用同步的写法达到异步的效果,线程不被阻塞,避免大量的CPU 上下文切换,提升系统的性能。

目前Java 对协程的支持也在进行中, Project Loom 就是Java 的协程项目:http://openjdk.java.net/projects/loom/。

主要有以下几个概念:

  • Fiber,轻量级线程(用户态线程),基于Continuation 实现

  • Continuation,指令执行单元, 阻塞时调用Continuation::yield , 恢复时调用Continuation::run

  • Scheduler,用户态Fiber 调度器(ForkJoinPool),使用有限Workers 线程执行任意数量Fibers

开发者可以使用 Fiber 来执行业务代码块,当遇到LockSupport::park、socket io 等阻塞调用时,Fiber 中的代码单元执行会被阻塞,但是底层的线程并不会被阻塞。由此达到了开发同步模式代码,运行时达到异步执行的目的。

未来,ESAStack服务框架会支持协程。目前 Restlight框架已经支持协程并在内部开始试用,ESARPC也有支持协程的计划。框架提供的服务线程使用 Fiber 执行业务逻辑,业务实现中数据库请求、下游服务调用均在 Fiber 之中执行, 其包含的 IO 等阻塞调用只挂起 Fiber 而不阻塞所在线程,从而避免了过多的上下文切换提升 了吞吐量,达到了和异步模式一样的效果。

☆ END ☆

招聘信息

OPPO互联网基础技术团队招聘一大波岗位,涵盖C++、Go、OpenJDK、Java、DevOps、Android、ElasticSearch等多个方向,请点击这里查看详细信息及JD

你可能还喜欢

OPPO自研ESA DataFlow架构与实践

Dubbo协议解析与ESA RPC实践

自研代码审查系统火眼Code Review实践

OPPO异地多活实践——缓存篇

更多技术干货

扫码关注

OPPO互联网技术

49fdae681d12cd48ae9f62fdf6e6e6e0.png 我就知道你“在看”67f28602d5ef62573b23d7df5bda1b33.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/395274.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

win7打开计算机死机,怎么样解决Win7系统运行程序引起的死机问题

Win7系统不仅需要使用到电脑中自带的一些程序,同时,也需要在win7旗舰版电脑中有选择的自己去安装一些程序。但是经常有用户会碰到Win7电脑突然跳出运行程序未响应,出现电脑死机的情况,特别是开的浏览器窗口多的时候更是死机的频繁…

sqlserver游标概念与实例全面解说

引言 我们先不讲游标的什么概念,步骤及语法,先来看一个例子: 表一 OriginSalary 表二 AddSalary 现在有2张表,一张是OriginSalary表--工资表,有三个字段0_ID 员工…

MyEclipse中Maven Web项目部署路径设置

转载于:https://www.cnblogs.com/langzichanglu/p/10336805.html

小米电视联网后显示无法解析小米电视服务器,小米电视连上无线不能上网怎么回事?教你解决办法...

原标题:小米电视连上无线不能上网怎么回事?教你解决办法互联网电视凭借在线观看影视剧这个独有的优势受到越来越多家庭的喜爱。特别是配置不俗的小米电视,然而随之而来的的问题也让很多用户头疼,比如家里的小米电视突然上不了网了…

2016.08.19

转载于:https://www.cnblogs.com/hiramlee0534/p/5789453.html

服务器上运行arp,服务器ARP病毒的特征及防护说明

服务器ARP病毒的特征及防护说明更新时间:2008年01月29日 15:50:33 作者:服务器ARP病毒的特征及防护说明近期有些用户反映服务器上所有网站被插入了病毒代码,但是这些病毒代码在服务器的源文件上并不能找到,因此,网管想清理病毒也无从下手,这是什么原因…

Machine Learning from Start to Finish with Scikit-Learn

2019独角兽企业重金招聘Python工程师标准>>> Machine Learning from Start to Finish with Scikit-Learn This notebook covers the basic Machine Learning process in Python step-by-step. Go from raw data to at least 78% accuracy on the Titanic Survivors …

Excel 宏编码实现,指定列的字符串截取

1、打开Excel凭证,启用宏,ALTF11 或 菜单“视图”-"宏-查看宏" Sub 分割字符串1() Dim i As Integer Dim b() As String Dim length 用length表示数组的长度 Dim sublength Dim bb() As String 筛选日期 2 点 For i 2 To 20000 b() Split(Ce…

css 画三角形

CSS三角形绘制方法#triangle-up {width: 0;height: 0;border-left: 50px solid transparent;border-right: 50px solid transparent;border-bottom: 100px solid red;}#triangle-down {width: 0;height: 0;border-left: 50px solid transparent;border-right: 50px solid trans…

mysql 慢日志报警_一则MySQL慢日志监控误报的问题分析

之前因为各种原因,有些报警没有引起重视,最近放假马上排除了一些潜在的人为原因,发现数据库的慢日志报警有些奇怪,主要表现是慢日志报警不属实,收到报警的即时通信提醒后,隔一会去数据库里面去排查&#xf…

无限复活服务器,绝地求生无限复活模式怎么玩 无限复活新手教程

相信不少的绝地求生玩家们最近都听说了其无限复活模式吧?因此肯定想要知道这种模式究竟该怎么玩,所以下面就来为各位带来此玩法的攻略相关,希望各位在看了如下的内容之后恩呢狗狗了解到新手教程攻略一览。“War”模式的设定以及玩法规则如下&#xff1a…

mysql date time year_YEAR、DATE、TIME、DATETIME和TIMESTAMP详细介绍[MySQL数据类型]

为了方便在数据库中存储日期和时间,MySQL提供了表示日期和时间的数据类型,分别是YEAR、DATE、TIME、DATETIME和TIMESTAMP。下面列举了这些MSL中日期和时间数据类型所对应的字节数、取值范围、日期格式以及零值。从上图中可以看出,每种日期和时…

安装Tengine

1.安装VMware2.安装CentOS6.53.配置网络a.修改 /etc/sysconfig/network-scripts/ifcfg-eth0配置文件,添加如下内容DEVICEeth0HWADDR00:0C:29:96:01:6BTYPEEthernetUUID41cbd943-024b-4341-ac7a-e4d2142b4938ONBOOTyesNM_CONTROLLEDyesBOOTPROTOnoneIPADDRxxx.xxx.x.xxx#例如:IP…

【OCR技术系列之八】端到端不定长文本识别CRNN代码实现

CRNN是OCR领域非常经典且被广泛使用的识别算法,其理论基础可以参考我上一篇文章,本文将着重讲解CRNN代码实现过程以及识别效果。 数据处理 利用图像处理技术我们手工大批量生成文字图像,一共360万张图像样本,效果如下:…

杜比服务器系统安装教程,win10杜比音效如何安装?win10安装杜比音效的详细教程...

杜比音效想必大家都不陌生,听歌或者看电影开启杜比音效可以给人一种身临其境的感觉。不少朋友都升级了win10系统却不知道如何安装杜比音效?如何为自己的系统安装杜比音效呢?感兴趣的小伙伴请看下面的操作步骤。win10安装杜比音效的方法&#…

前端if else_应该记录的一些项目代码(前端)

1.共享登录(单点登录)主要是前端部分主要是根据是否有cookie来判断是否已经登录主系统,然后再根据是否有当前系统的登录信息来(这块主要是sessionStorage做的)判断是否要再登录当前系统。设置、读取和设置cookie的方法…

Mac端解决(含修改8.0.13版的密码):Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)...

1. 安装mysql但是从来没启动过,今天一启动就报错: Cant connect to local MySQL server through socket /tmp/mysql.sock (2) 其实是mysql服务没起来。。。 localhost:~ miaoying$ mysql.server start Starting MySQL ... SUCCESS! 然后再去sudo mysql就…

塔塔建网站服务器,塔塔帝国忘记哪个区怎么办

7条解答1.在哪个区玩战舰帝国忘记了怎么办?忘了的话可以去官网登陆看看自己的 充值 或者礼包记录 有没有对应的区服 或者电话联系问问客服 通过账号 角色名字来查询2.我忘记在哪个区怎么找如果你有游戏人生资格的话,就很容易找了,在游戏人生的个人主页里…

Ixia推出首款太比特级网络安全测试平台

2016年11月18日,Ixia宣布推出全新CloudStorm平台。作为首款太比特级网络安全测试平台,该平台拥有前所未有的非凡性能,可用于测试及验证超大规模云数据中心不断扩大的容量、效率以及弹性。 ▲Ixia CloudStorm安全测试平台 CloudStorm的正式面市…

服务器选择重装系统,云服务器重装系统选择

云服务器重装系统选择 内容精选换一换将外部镜像文件注册成云平台的私有镜像后,您可以使用该镜像创建新的云服务器,或对已有云服务器的系统进行重装和更换。本节介绍使用镜像创建云服务器的操作。您可以按照通过镜像创建云服务器中的操作指导创建弹性云服…