第一次聽到reactive這個詞仍是在幾年前,偶然瞭解到了Rxjava這個項目,彷彿爲我打開了一扇新的大門,Rxjava是ReactiveX的java實現,ReactiveX家族除了Rxjava還有RxJS, Rx.NET,RxScala等等。java
ReactiveX的本質就是Observer+Iterator+函數編程+異步。是一個事件驅動的,異步的,可觀察的序列。react
使用RxJava能夠將異步的回調改寫成爲鏈式調用。在代碼上看起來很是簡潔明瞭。固然JDK也提供了CompletionStage提供了相似的解決回調的功能。web
更多內容請訪問 www.flydean.com
Rxjava只是一個java的基本庫,若是咱們想要構建響應式的服務器,響應式的web,響應式的數據訪問,甚至是響應式的微服務,又該如何處理呢?spring
這個時候我瞭解到了Vert.x。Vert.x就是用來構建Reactive的應用程序的。編程
Vert.x是Eclipse基金會旗下的產品,基於事件驅動和非阻塞編程。api
Vert.x是模塊化的,裏面有Core,web,Data access,Reactive,Microservices,MQTT,Authentication and Authorisation,Messaging,Event bus Bridge,Devops,Testing,Clustering,Services和Cloud等模塊。可謂是應有盡有。安全
其實java界一直都在向reactive靠近,除了JDK自己的api新特性意外,好比業界有名的Spring也在spring 5中添加了webflux框架,這就是一款reactive的web框架。服務器
在上一節咱們提到了Rxjava和Vert.x,裏面有一些共同的關鍵字,好比異步,事件驅動,觀察者模式,函數式編程,消息驅動等,全部的一切都是爲了讓現代系統更加健壯,運行的更快,更加富有彈性,從而更好。架構
系統從好久以前的單一服務器,到如今的多服務器架構,從秒級響應到如今的毫秒級響應。從90%可用都如今的99.999%可用。不論從系統設計,架構仍是程序編碼都發生了極大的變化。負載均衡
咱們迫切的須要一個可以知足以上需求的通用的系統架構解決方案。
那麼什麼是響應式系統呢?
響應式系統須要具有這些特徵:及時響應性(Responsive)、恢復性(Resilient)、有彈性(Elastic)以及消息驅動(Message Driven)。咱們把具備上面四個特性的系統就叫作響應式系統。
上面的四個特性中,及時響應性(Responsive)是系統最終要達到的目標,恢復性(Resilient)和有彈性(Elastic)是系統的表現形式,而消息驅動(Message Driven)則是系統構建的手段。
因而咱們獲得了響應式系統的終極架構圖:
使用響應式系統的架構,能夠保證系統的可維護性,和可擴展性,而且在系統出現問題的時候可以有更好的可容忍性。
在定義響應式系統的時候,咱們提到了及時響應性(Responsive)、恢復性(Resilient)、有彈性(Elastic)以及消息驅動(Message Driven)這四大特色。
接下來咱們將會具體描述這四大特色到底有什麼奧祕。
Responsive就是系統可以馬上響應請求,這應該包含兩個方面的含義。
第一,響應請求的時間要夠短,若是用戶請求一個頁面,等待2秒鐘估計已是極限了。再長的時間估計就要失去這個用戶了。
時代在變,技術也在變,十幾年前下載一個幾百K的文件要一分鐘估計就算是很快了,如今沒有個幾M每秒,確定會讓人抓狂不已。
在現代CPU,服務集羣和光纖傳輸的飛速發展和頁面承載信息的巨大變化,一個普通的頁面可能就要包含十幾二十個請求。每一個請求的時間已經提高到了毫秒甚至是微妙級。同時在頁面展現方面也產生了不少新的變化,好比異步加載和預加載等技術。
最終是爲了建立一個可以及時響應的系統。而系統背後的各類技術和新的請求方式都是爲這個目標來服務的。
第二,對於錯誤的響應時間要短。
一方面對於用戶來講,要及時的提醒用戶可能出現的錯誤。不論是系統自己的錯誤亦或是用戶的使用錯誤,都須要在一個有限的時間內進行響應。
另外一方面,對於系統自己來講,要可以快速的定位和響應問題。這是提高系統自己的穩定性和安全性的基本要求。
如何發現和響應系統自己的問題呢?第一要有完善的錯誤記錄系統,讓一切都有章可循。第二就是要有相應的監控措施,讓系統出現的任何問題都可以及時的進行通知和報警。
可恢復性是指系統在遇到失敗或者錯誤時仍然可以對外提供服務。
首先,要求咱們的系統足夠穩健,可以抗住正常的訪問,而且可以可預見的應對熱點訪問。
其次,現代系統的功能是各類各樣的,一個簡單的APP的後臺可能有多達幾十種服務。因此咱們須要區分出來哪些是關鍵的服務,哪些是非關鍵的服務。對於關鍵的服務咱們必定要確保其的穩定性,對於非關鍵性的服務,咱們能夠在首先保障關鍵服務的前提下再進行考慮。
好比說一個訂單系統,下單確定就是關鍵服務了,而商品的點贊數,評論等則就沒有那麼重要。
區分好了關鍵服務和非關鍵服務,就要對他們進行區分和隔離。非關鍵服務的任何錯誤或者異常都不可以影響到關鍵服務。
再次,若是服務發送了錯誤,咱們應該儘量的縮小影響範圍,不要一點小錯誤影響全部的服務。
最後,對於失敗要有恢復措施,而且這個恢復措施不可以影響其餘的系統服務。好比咱們能夠對現有的系統作一個複製,在某個服務失敗的時候,能夠用備用的服務進行替代。
只有這樣,纔可以保證系統的可靠性。
彈性的意思就是在須要的時候服務能夠動態擴展,在不須要的時候能夠停用服務以節約資源。
如今不少雲服務都提供了動態擴展的功能,若是系統是咱們本身實現的,那就須要區分出熱點問題和非熱點問題。
只有熱點問題才須要考慮彈性,系統不能有瓶頸,而且可以進行分片或者複製,從而實現分佈式的動態負載功能。
負載均衡技術多是咱們最經常使用的彈性功能,可是如何動態的自動的進行負載的均衡多是一個很是有意義的話題。
彈性能夠經過軟件或者硬件的方式來實現,固然咱們須要在成本和效果之間達成一個平衡。
消息驅動的本質就是發送消息,接收消息而後進行處理。如今大型系統不多有不使用消息中間件的。使用這些消息中間件的好處就是能夠解耦和異步驅動。
異步的好處這裏就很少講了,大概就是不用一直傻傻的等待,而是充分利用時間去作更有效率的事情。
解耦的做用就更大了,現代系統基本上都是由不少個服務組成的。要想保證這麼多系統的平穩運行,確定要作解耦操做,不然一個服務的失敗就會致使全部服務的不可用,想一想都以爲懼怕。
而消息驅動,就是這些不一樣的服務組件之間溝通的橋樑。告訴他們要作什麼,等待他們的反饋消息。
或者咱們能夠把這些服務看作一個一個的人,多人之間的溝通就是經過語言。語言驅動或者也能夠叫作消息驅動。
這裏再講一個消息驅動中常見的一個概念:back-pressure。
咱們知道發送消息和接收消息的服務其處理速度是有限的,當發送消息的速度快過與接收消息的速度時候,就會發送消息阻塞,當消息阻塞過多的時候,就有可能發送消息丟失或者服務崩潰的狀況。而且若是太多消息一直都沒有被處理,沒有獲得響應的話,對於用戶體驗也是很是很差的。
這裏就須要使用到back-pressure的概念,若是消息接收方消息處理不過來,則能夠通知消息發送方,告知其正在承受壓力,須要下降負載。back-pressure是一種消息反饋機制,從而使系統得以優雅地響應負載, 而不是在負載下崩潰。
reactive是近幾年很是流行的一個概念,如何經過reactive來設計出知足咱們須要的系統,是咱們須要考慮的問題。
本文做者:flydean程序那些事本文連接:http://www.flydean.com/reactive-system-overview/
本文來源:flydean的博客
歡迎關注個人公衆號:程序那些事,更多精彩等着您!