異步服務_微服務全鏈路異步化實踐

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.pswp.cn/news/395274.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/395274.shtml
英文地址,請注明出處:http://en.pswp.cn/news/395274.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

win7打開計算機死機,怎么樣解決Win7系統運行程序引起的死機問題

Win7系統不僅需要使用到電腦中自帶的一些程序,同時,也需要在win7旗艦版電腦中有選擇的自己去安裝一些程序。但是經常有用戶會碰到Win7電腦突然跳出運行程序未響應,出現電腦死機的情況,特別是開的瀏覽器窗口多的時候更是死機的頻繁…

(poj)1064 Cable master 二分+精度

題目鏈接:http://poj.org/problem?id1064 DescriptionInhabitants of the Wonderland have decided to hold a regional programming contest. The Judging Committee has volunteered and has promised to organize the most honest contest ever. It was decided…

PHP中如何解決高并發

PHP中如何解決高并發 1:硬件方面 普通的一個p4的服務器每天最多能支持大約10萬左右的IP,如果訪問量超過10W那么需要專用的服務器才能解決,如果硬件不給力 軟件怎么優化都是于事無補的。主要影響服務器的速度 有:網絡-硬盤讀寫速度…

es6 迭代器_揭秘ES6迭代器和迭代器

es6 迭代器by Tiago Lopes Ferreira由Tiago Lopes Ferreira 揭秘ES6迭代器和迭代器 (Demystifying ES6 Iterables & Iterators) ES6 introduces a new way to interact with JavaScript data structures — iteration. Let’s demystify it.ES6引入了一種與JavaScript數據…

JS之this與語句分號問題v(**V**)v

1 <script >2 //this知識 單詞知識&#xff1a;property&#xff1a;屬性 prototype&#xff1a;原型3 //*Q&#xff1a;什么是this&#xff1f;4 //*A&#xff1a;所有函數內部都有一個this&#xff0c;任何函數本質上都是通過某個對象來調用的&#xff0c;…

計算機聯系函范文,致客戶聯絡函

致客戶聯絡函 相關內容:收到貴支部所發的“函調證明”通知&#xff0c;很高興我校畢業生xxx同學能成為貴支部的黨員發展對象&#xff0c;現對其在我校上學其間的表現證明如下&#xff1a;xxx&#xff0c;女&#xff0c;xxx年7月28日生&#xff0c;團員&#xff0c;XX年8月——X…

c語言堆棧基本代碼入棧出棧_c語言的簡單的進棧出棧

這個代碼運行時只能輸入4個以內的數有輸出4個以上就沒有輸出了求大神看看#include#include#defineStack_Size50typedefstructSeqstack{intelem[Stack_Size];inttop...這個代碼運行時只能輸入4個以內的數有輸出 4個以上就沒有輸出了 求大神看看 #include #include #define Stack…

P1401 城市(30分,正解網絡流)

題目描述 N(2<n<200)個城市&#xff0c;M(1<m<40000)條無向邊&#xff0c;你要找T(1<T<200)條從城市1到城市N的路&#xff0c;使得最長的邊的長度最小&#xff0c;邊不能重復用。 輸入輸出格式 輸入格式&#xff1a; 第1行三個整數N,M,T用空格隔開。 第2行到…

sqlserver游標概念與實例全面解說

引言 我們先不講游標的什么概念&#xff0c;步驟及語法&#xff0c;先來看一個例子&#xff1a; 表一 OriginSalary 表二 AddSalary 現在有2張表&#xff0c;一張是OriginSalary表--工資表&#xff0c;有三個字段0_ID 員工…

為什么Docker對初創企業有意義

by Charly Vega查理維加(Charly Vega) 為什么Docker對初創企業有意義 (Why Docker makes sense for startups) Docker is becoming the standard to develop and run containerized applications.Docker正在成為開發和運行容器化應用程序的標準。 Long ago, this piece of te…

MyEclipse中Maven Web項目部署路徑設置

轉載于:https://www.cnblogs.com/langzichanglu/p/10336805.html

小米電視聯網后顯示無法解析小米電視服務器,小米電視連上無線不能上網怎么回事?教你解決辦法...

原標題&#xff1a;小米電視連上無線不能上網怎么回事&#xff1f;教你解決辦法互聯網電視憑借在線觀看影視劇這個獨有的優勢受到越來越多家庭的喜愛。特別是配置不俗的小米電視&#xff0c;然而隨之而來的的問題也讓很多用戶頭疼&#xff0c;比如家里的小米電視突然上不了網了…

配置Server Side TAF

實驗環境&#xff1a;Oracle 11.2.0.4 RAC1.為設置TAF在RAC集群上新建服務2.啟動server_taf服務3.檢查確認服務正在運行4.找到剛創建服務的service_id5.根據service_id審查服務的信息6.給服務添加server side failover參數7.再次審查服務可以看到Method, Type和Retries值8.檢查…

fgets阻塞 stdin 退出_來自stdin問題的fgets[c]

我試過你的代碼,但無法重現問題。以下代碼的工作方式正是您所期望的,它會提示您輸入名稱,等待您鍵入名稱,然后提示您輸入地址,等等。我想知道你是否不需要在提示輸入更多信息之前閱讀stdin并清空它?typedef struct {char* name;char* address;}employeeRecord;int readrecord(…

2016.08.19

轉載于:https://www.cnblogs.com/hiramlee0534/p/5789453.html

服務器上運行arp,服務器ARP病毒的特征及防護說明

服務器ARP病毒的特征及防護說明更新時間&#xff1a;2008年01月29日 15:50:33 作者&#xff1a;服務器ARP病毒的特征及防護說明近期有些用戶反映服務器上所有網站被插入了病毒代碼,但是這些病毒代碼在服務器的源文件上并不能找到,因此,網管想清理病毒也無從下手,這是什么原因…

使用React Native進行氣泡動畫

by Narendra N Shetty由納倫德拉N謝蒂(Narendra N Shetty) 使用React Native進行氣泡動畫 (Bubble animation with React Native) 使用Animated和PanResponder構建React Native應用程序時獲得的經驗教訓 (Lessons learned while building a React Native App using Animated a…

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憑證&#xff0c;啟用宏&#xff0c;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…

mysql for update 鎖_MySql FOR UPDATE 鎖的一點問題……

問題描述假設一個情況&#xff0c;這里只是假設&#xff0c;真實的情況可能不會這樣設計&#xff0c;但是假如真的發生了....鐵老大有一張這樣的ticket表&#xff0c;用來存放北京到上海的票。iduidstart_addrend_addrbook_time11300009860上海北京1386666032120上海北京30上海…