反应式编程在微服务下的重生
反應(yīng)式編程在好幾年前就已經(jīng)出現(xiàn)了,它原理是基于反應(yīng)式編宣言。但是,由于反應(yīng)式編程推廣速度比較緩慢,導(dǎo)致很多人現(xiàn)在對(duì)其不是很了解。
反應(yīng)式編宣言:
https://www.reactivemanifesto.org
本文將從微服務(wù)角度闡述反應(yīng)式編程,在深入解讀之前,先為大家簡(jiǎn)單地介紹一些反應(yīng)式編程的基本概念。
反應(yīng)式編程概念簡(jiǎn)化版
1. 設(shè)計(jì)思想
反應(yīng)式編程的提出,是在分布式編程剛興起不久。當(dāng)時(shí)沒(méi)有各種 PaaS 平臺(tái),而分布式系統(tǒng)中,常常出現(xiàn)一個(gè)節(jié)點(diǎn)出問(wèn)題,導(dǎo)致整個(gè)系統(tǒng)癱瘓的情況。所以,反應(yīng)式編程的思想是:不等不靠,即當(dāng)有一個(gè)節(jié)點(diǎn)慢下來(lái)的時(shí)候,整個(gè)系統(tǒng)都放慢,以此來(lái)避免災(zāi)難性的后果。
這樣的想法,當(dāng)然是有局限性的。一方面,雖然整個(gè)系統(tǒng)得到保全,但是系統(tǒng)的處理能力卻大大降低,作為這個(gè)系統(tǒng)之外的用戶或者其它應(yīng)用還是受到影響的。另外,隨著 PaaS 相關(guān)技術(shù)的發(fā)展,現(xiàn)在如果出現(xiàn)一個(gè)節(jié)點(diǎn)放慢的問(wèn)題,我們既可以用熔斷、限流,甚至擴(kuò)容來(lái)處理,處理的選擇有多種。
2. 組成
反應(yīng)式編程的宣言是指導(dǎo)框架,具體的實(shí)現(xiàn)是有不同的版本。但是,它們都有兩個(gè)共同的特征。
-
異步編程,非阻塞流:這是實(shí)現(xiàn)反應(yīng)式編程的基礎(chǔ)。
但是,很多人把反應(yīng)式編程和函數(shù)式編程混淆了。如 Java 這部分語(yǔ)言 ,選用函數(shù)式編程來(lái)實(shí)現(xiàn)非阻塞式的異步編程。但是,其它的語(yǔ)言,如 golang, goroutine 和 channel 已經(jīng)是異步和非阻塞的,那么它們不用函數(shù)式編程也一樣可以實(shí)現(xiàn)反應(yīng)式編程。
-
背壓:背壓是另一個(gè)自己把自己難倒的概念。
背壓就是處理數(shù)據(jù)的接收方指揮發(fā)送方何時(shí)發(fā)送信息和發(fā)多少信息,比如我們排隊(duì)過(guò)安檢,安檢的人招手了,我們才走過(guò)去。本來(lái)都是發(fā)送方有數(shù)據(jù)就發(fā)送,那么壓力就在接收方,因?yàn)樘幚聿涣司蛼炝恕,F(xiàn)在壓力反過(guò)來(lái)了,在發(fā)送方,就叫背壓。這個(gè)名字不好,如果我起,就叫“憋呀”,簡(jiǎn)單易懂。發(fā)送方數(shù)據(jù)多了怎么辦?憋著。正是這個(gè)憋,是背壓形象直觀的解釋,而它保障了系統(tǒng)不會(huì)掛。
所以,用不是很準(zhǔn)確的方式總結(jié)反應(yīng)式編程的主要部分,就是異步編程、非阻塞流和背壓。
?
微服務(wù)環(huán)境對(duì)分布式應(yīng)用架構(gòu)帶來(lái)的挑戰(zhàn)
一直以來(lái)很多人都會(huì)對(duì)反應(yīng)式編程有這樣的疑問(wèn):這樣的設(shè)計(jì),真的有用嗎?
微服務(wù)已經(jīng)算是很成熟的技術(shù)了,并且微服務(wù)是分布式系統(tǒng)的一員,所以很多人也會(huì)理所當(dāng)然的覺(jué)得分布式系統(tǒng)也應(yīng)該很成熟了。但是結(jié)果卻恰恰相反。
我個(gè)人的理解,并不是微服務(wù)走錯(cuò)方向了,而正是由于微服務(wù)的普及,產(chǎn)生了許多以前沒(méi)有遇到過(guò)的新問(wèn)題。
而其中最主要的問(wèn)題,就是微服務(wù)之間的通信問(wèn)題。首先,與單體應(yīng)用不同,微服務(wù)之間誰(shuí)也無(wú)法控制誰(shuí),是無(wú)法保障通訊的順序的, 這就要求是異步編程。同理也會(huì)要求通訊是采取非阻塞方式,不然一旦I/O被一個(gè)線程占了,其它線程就沒(méi)法用了。然后就是微服務(wù)之間如何協(xié)調(diào)通訊速度的問(wèn)題。沒(méi)錯(cuò),現(xiàn)在有service mesh, 有熔斷,限流,也有擴(kuò)容。但是,這些還不夠。因?yàn)檫@些手段都是要先觀察到異常,然后才能處置。而很多時(shí)候異常是很不容易察覺(jué)的。比如K8s的擴(kuò)容,每30秒采集一次。還要算平均值。這些都很難及時(shí)反應(yīng)。等到算出有問(wèn)題,時(shí)間已經(jīng)過(guò)了很久。而且很多的時(shí)候,故障就是小抖動(dòng),突然慢下來(lái),但無(wú)法體現(xiàn)在平均值上。吞吐量的匹配,是一個(gè)棘手的問(wèn)題。
這個(gè)時(shí)候,反應(yīng)式編程的優(yōu)點(diǎn)就體現(xiàn)出來(lái)了。它不管什么原因,處理不了就不請(qǐng)求發(fā)送。而且是立刻的。
?
微服務(wù)環(huán)境對(duì)反應(yīng)式編程的新要求
不能以為反應(yīng)式編程好像就是可以在微服務(wù)環(huán)境下安枕無(wú)憂。其實(shí),它也面臨改進(jìn)的要求。
端到端的背壓
過(guò)去的反應(yīng)式編程一般只考慮兩個(gè)分布應(yīng)用之間的通訊。但是隨著微服務(wù)架構(gòu)的復(fù)雜化,從A到B也許中間要經(jīng)過(guò)其他的環(huán)節(jié)。這個(gè)時(shí)候,怎么傳遞背壓的信息,而不是在中間環(huán)節(jié)丟失;怎么從端到端執(zhí)行背壓,就顯得特別重要。這對(duì)很多現(xiàn)有的反應(yīng)式編程框架都是挑戰(zhàn)。
與云原生環(huán)境的整合
一些早期反應(yīng)式編程框架,有自己的集群管理功能。而且這些功能,是以胖SDK的方式捆綁在反應(yīng)式編程基本功能上的。但是在強(qiáng)調(diào)云原生的今天,這似乎不是優(yōu)勢(shì)而是缺點(diǎn)。相反,把基本的反應(yīng)式編程功能與服務(wù)注冊(cè),發(fā)現(xiàn),以及負(fù)載均衡等功能分離,充分利用云原生的優(yōu)勢(shì),與之協(xié)調(diào)互補(bǔ),則是未來(lái)的趨勢(shì)。
?
性能
最后我們談一下很重要的一環(huán):性能。一直以來(lái),很多人都有疑問(wèn):背壓的通訊方式真的好嗎?如果一切環(huán)境是可控的,網(wǎng)絡(luò)帶寬是無(wú)限的,那么傳統(tǒng)的阻塞通訊是有優(yōu)勢(shì)的。這就是為什么JVM費(fèi)那么大勁實(shí)現(xiàn)這些功能的原因。因?yàn)長(zhǎng)inux其實(shí)是非阻塞的,而20多年前,應(yīng)用大多是單體的。但是在現(xiàn)實(shí)的環(huán)境下,對(duì)于分布式應(yīng)用,在數(shù)據(jù)量較大的時(shí)候,非阻塞通訊的優(yōu)勢(shì)就體現(xiàn)出來(lái)了。特別當(dāng)有合適的網(wǎng)絡(luò)通訊方式支持背壓的時(shí)候,這種優(yōu)勢(shì)更加明顯。
?
總結(jié)
最近的趨勢(shì)告訴我們,在分布式應(yīng)用架構(gòu)變成熟的過(guò)程中,反應(yīng)式編程的作用慢慢被重新認(rèn)識(shí)。事實(shí)上,反應(yīng)式編程自身也在發(fā)展中,特別是在網(wǎng)絡(luò)傳輸方面的進(jìn)展,一定會(huì)在未來(lái)分布式應(yīng)用架構(gòu)中發(fā)揮更大的作用。
?
本文作者:
Andy Shi :?
GitHub ID szihai,阿里巴巴中間件高級(jí)技術(shù)專(zhuān)家,長(zhǎng)期從事 Service Mesh 和微服務(wù)框架的技術(shù)推廣工作。
總結(jié)
以上是生活随笔為你收集整理的反应式编程在微服务下的重生的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 图文并茂的带你彻底理解悲观锁与乐观锁
- 下一篇: 华为面试改革,你怎么看?