RPC 異步響應(yīng)式調(diào)用

同步調(diào)用的缺點(diǎn)

我們假設(shè)一個電子商城用戶購買商品的場景: 創(chuàng)建訂單前的驗(yàn)證方法砾跃。

/**
 * 驗(yàn)證訂單是否合法
 * 
 * @param userId 用戶id
 * @param itemId 商品id
 * @param discount 折扣
 * @return
 */
public boolean verifyOrder(long userId, long itemId, double discount) {
    
    // 驗(yàn)證用戶能否享受這一折扣盹牧,RPC調(diào)用
    boolean verifyDiscount = discountService.verify(userId, itemId, discount);
    
    if(!verifyDiscount) {
        // 該用戶無法享受這一折扣
        return false;
    }
    
    // 獲取商品單價加派,RPC調(diào)用
    double itemPrice = storeService.getPrice(itemId);
    
    // 用戶實(shí)際應(yīng)該支付的價格
    double realPrice = itemPrice * discount;
    
    // 獲取用戶賬號余額熟尉,限定了只能使用余額購買熏版,RPC調(diào)用
    double balance = userService.getBalance(userId);
            
    return realPrice <= balance;
}

這個方法里面涉及到了 3 個 rpc 調(diào)用纷责,假設(shè)每個 rpc 調(diào)用都需要 10ms,那么
verifyOrder 這個方法總耗時將不低于 30ms撼短。

在同步調(diào)用系統(tǒng)中再膳,延遲同時會導(dǎo)致吞吐量的下降。如果只有一個線程曲横,那么系統(tǒng)每秒的吞吐量將不會高于 1000ms / 30ms喂柒,也就是最多 33 qps。同步系統(tǒng)要提高吞吐量禾嫉,唯一的辦法就是加大線程數(shù)灾杰。同時啟用 1,000 個線程,吞吐量理論值可以上升到 33,333 qps熙参。不過實(shí)際使用中艳吠,這并不是完美的方案:增加線程數(shù)量會導(dǎo)致頻繁的上下文切換,系統(tǒng)整體性能將會嚴(yán)重下降孽椰。

Future 的不足

為了解決同步系統(tǒng)的問題昭娩,Java 5 引入了 Future。有了 Future 后黍匾,上面的方法可以修改為:

/**
 * 驗(yàn)證訂單是否合法
 * 
 * @param userId 用戶id
 * @param itemId 商品id
 * @param discount 折扣
 * @return
 */
public boolean verifyOrder(long userId, long itemId, double discount) {
    
    // 驗(yàn)證用戶能否享受這一折扣栏渺,RPC調(diào)用
    Future<Boolean> verifyDiscountFuture = discountService.verify(userId, itemId, discount);
    
    // 獲取商品單價,RPC調(diào)用
    Future<Double> itemPriceFuture = storeService.getPrice(itemId);
    
    // 獲取用戶賬號余額锐涯,限定了只能使用余額購買磕诊,RPC調(diào)用
    Future<Double> balanceFuture = userService.getBalance(userId);

    if(!verifyDiscountFuture.get()) {
        // 該用戶無法享受這一折扣
        return false;
    }

    // 用戶實(shí)際應(yīng)該支付的價格
    double realPrice = itemPriceFuture.get() * discount;

    // 用戶賬號余額
    double balance = balanceFuture.get();
            
    return realPrice <= balance;
}

3 個 rpc 調(diào)用可以同時進(jìn)行了,系統(tǒng)延遲降低為之前的 1/3纹腌。不過延遲降低吞吐量的問題還是沒有解決霎终,依然需要通過增加線程數(shù)來提升吞吐量。

CompletableFuture 才是王道

引入 CompletableFuture 后升薯,我們可以使用如下形式:

/**
 * 驗(yàn)證訂單是否合法
 * 
 * @param userId 用戶id
 * @param itemId 商品id
 * @param discount 折扣
 * @return
 */
public CompletableFuture<Boolean> verifyOrder(long userId, long itemId, double discount) {
    
    // 驗(yàn)證用戶能否享受這一折扣莱褒,RPC調(diào)用
    CompletableFuture<Boolean> verifyDiscountFuture = discountService.verify(userId, itemId, discount);
    
    // 獲取商品單價,RPC調(diào)用
    CompletableFuture<Double> itemPriceFuture = storeService.getPrice(itemId);
    
    // 獲取用戶賬號余額覆劈,限定了只能使用余額購買保礼,RPC調(diào)用
    CompletableFuture<Double> balanceFuture = userService.getBalance(userId);
        
    return CompletableFuture
        .allOf(verifyDiscountFuture, itemPriceFuture, balanceFuture)
        .thenApply(v -> {
            if(!verifyDiscountFuture.get()) {
                // 該用戶無法享受這一折扣
                return false;
            }

            // 用戶實(shí)際應(yīng)該支付的價格
            double realPrice = itemPriceFuture.get() * discount;

            // 用戶賬號余額
            double balance = balanceFuture.get();
                    
            return realPrice <= balance;
        });    
}

延遲降低為原來 1/3,同時吞吐量也不會因?yàn)檠舆t而降低责语。非常完美炮障,簡單高效,CompletableFuture 絕對稱得上是大殺器坤候。在 rpc 異步調(diào)用這個問題上胁赢,沒什么比 CompletableFuture 更適合的解決方案了。CompletableFuture 是 Doug Lea 的又一力作白筹,徹底解決了 Future 的缺陷智末,把 Java 帶入了異步響應(yīng)式編程的新世界。

motan dubbo 的解決方案是否完美

不完美徒河,會陷入回調(diào)地獄系馆,motan 和 dubbo 的設(shè)計(jì)者應(yīng)該考慮引入 CompletableFuture 了。

Akka RxJava Reactor 是否可用顽照?

這 3 個方案都能完美解決上述問題由蘑。但我個人認(rèn)為這 3 個方案都有一些不足之處,不過這非常帶有主觀性偏見代兵,僅供讀者參考尼酿。后面我可能會從 代碼量 代碼復(fù)雜度 性能 等方面給出更全面客觀評測。

  1. Akka
    從來沒見過這樣復(fù)雜的系統(tǒng)植影,我覺得我搞不定它裳擎。actor 機(jī)制盡管有一堆的優(yōu)點(diǎn),但在我看來這東西就是新形式的 goto思币。跳來跳去悠忽不定鹿响,簡直就是系統(tǒng)維護(hù)的地獄,完全搞不定它支救。

  2. RxJava 和 Reactor
    沒什么大問題抢野,主要是引入了很多新的概念。要使用他們需要先花一段時間研究各墨,這對在團(tuán)隊(duì)中推廣很不利指孤。不過如果你的團(tuán)隊(duì)對這兩個中的任意一個已經(jīng)有過深入研究的話,我覺得用起來完全沒問題贬堵。

廣告時間

Turbo 采用 CompletableFuture 作為異步解決方案恃轩,性能非常好。

更多內(nèi)容詳見:
https://github.com/hank-whu/turbo-rpc

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末黎做,一起剝皮案震驚了整個濱河市叉跛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蒸殿,老刑警劉巖筷厘,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸣峭,死亡現(xiàn)場離奇詭異,居然都是意外死亡酥艳,警方通過查閱死者的電腦和手機(jī)摊溶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來充石,“玉大人莫换,你說我怎么就攤上這事≈枇澹” “怎么了拉岁?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長惰爬。 經(jīng)常有香客問我喊暖,道長,這世上最難降的妖魔是什么撕瞧? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任哄啄,我火速辦了婚禮,結(jié)果婚禮上风范,老公的妹妹穿的比我還像新娘咨跌。我一直安慰自己,他們只是感情好硼婿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布锌半。 她就那樣靜靜地躺著,像睡著了一般寇漫。 火紅的嫁衣襯著肌膚如雪刊殉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天州胳,我揣著相機(jī)與錄音记焊,去河邊找鬼。 笑死栓撞,一個胖子當(dāng)著我的面吹牛遍膜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瓤湘,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼瓢颅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弛说?” 一聲冷哼從身側(cè)響起挽懦,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎木人,沒想到半個月后信柿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冀偶,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年渔嚷,在試婚紗的時候發(fā)現(xiàn)自己被綠了蔫磨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡圃伶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蒲列,到底是詐尸還是另有隱情窒朋,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布蝗岖,位于F島的核電站侥猩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏抵赢。R本人自食惡果不足惜欺劳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望铅鲤。 院中可真熱鬧划提,春花似錦、人聲如沸邢享。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽骇塘。三九已至伊履,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間款违,已是汗流浹背唐瀑。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留插爹,地道東北人哄辣。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像赠尾,于是被迫代替她去往敵國和親柔滔。 傳聞我的和親對象是個殘疾皇子铣口,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理虎敦,服務(wù)發(fā)現(xiàn)庆亡,斷路器吊档,智...
    卡卡羅2017閱讀 134,633評論 18 139
  • 轉(zhuǎn)載:Dapper恬涧,大規(guī)模分布式系統(tǒng)的跟蹤系統(tǒng) 當(dāng)代的互聯(lián)網(wǎng)的服務(wù)穷绵,通常都是用復(fù)雜的、大規(guī)模分布式集群來實(shí)現(xiàn)的嘶朱《昱鳎互...
    meng_philip123閱讀 1,061評論 0 7
  • 轉(zhuǎn)自:http://blog.csdn.net/kesonyk/article/details/50924489 ...
    晴天哥_王志閱讀 24,787評論 2 38
  • 科胡特在上世紀(jì)六十年代由于身為反對越戰(zhàn)活躍分子的兒子湯姆而被捕。湯姆·科胡特回憶由于他的激進(jìn)疏遏,身處當(dāng)時社會政治環(huán)境...
    田凱心理閱讀 272評論 0 2
  • 清夢飛揚(yáng) 時光不攬逍遙客脉课, 嗔怪當(dāng)時思域多。 千恩萬謝酬知己财异, 慢納胸懷定風(fēng)波倘零。 清夢飛揚(yáng)在吉林與你共享美好時光
    清夢飛揚(yáng)閱讀 167評論 0 1