聊聊微服務的分佈式通信

微服務目前比較熱,可是微服務最難的仍是可靠性問題,由於一個系統微服務可能幾百個,網絡調用頻繁,網絡的容錯性就很是重要,由於對於分佈式系統,須要默認網絡環境是不可靠的,丟包或堵塞等狀況都是可能會發生的,這裏面其實就是經典的拜占庭將軍問題,兩個將軍想約定某個時候一塊兒進攻,可是不能確保這個信息可否可靠地傳遞給對方,是路途耽誤了仍是送信的人死了永遠不可能送達,都沒法肯定,網絡之間的通信也是如此,A給B發個TCP數據包,這個數據包是由於網絡繁忙暫時堵塞,仍是就是被丟棄了呢?雙方都不知道。
固然有很多人使用Dubbo這樣的開源分佈式服務框架,Dubbo使用RPC實現服務之間同步調用,RPC實際是Java中一種遠程調用方式,RPC也是沒法避免網絡通信問題,若是A服務更新了數據庫,而調用B服務時網絡出錯,或者B服務內部調用數據庫時出錯,可是A服務中數據庫已經更新,這就可能發生業務上二者數據庫不一致了。
因此,只要涉及到分佈式系統,包括分佈式服務,分庫分表,甚至Web這種瀏覽器前端與後端之間調用,都須要根據CAP定理進行權衡。
不少人習慣進行服務的同步調用,其實這是和一般方法調用習慣致使,分佈式系統中同步調用好像很快,其實很是脆弱,網絡容錯性差,一旦網絡堵塞,同步調用RPC就容易失敗。 所以,在分佈式系統中,異步調用好像是異步,沒有同步快,實際是未必然,異步調用是CAP中的C強一致性和A可用性的妥協,使用最終一致性得到可用性的提升,同時又可以保證必定的網絡容錯性; 而RPC同步調用,則是選擇了CAP中C和A,相似2PC分佈式事務,可是網絡容錯性不好,網絡稍微有點堵塞,RPC調用就會受到影響,若是RPC調用嵌套了好幾個,某個點的網絡堵塞會點爆整個調用鏈條的崩潰。
因此,微服務架構中,跟蹤和恢復變得很是重要,固然這些經過專門的跟蹤工具實現,可是這些都是過後控制了。
那麼微服務之間的通信推薦使用異步方式,如何具體實現呢? 首先經過異步消息實現微服務之間調用,在架構設計是鬆耦合的,可見個人另一篇《軟件架構的靈活設計》,另外,異步不表明性能慢,由於在分佈式系統中,總體快慢是取決於最慢的那個環節,因此,總體性能是講究效率的,並且這個性能快慢實際就是延遲與可用性問題,又回到前面CAP問題上。
那麼異步消息傳遞在兩個服務之間傳遞什麼呢? 固然是傳參,這樣兩個微服務之間經過服務調用進行參數傳遞,實現數據共享,沒必要將彼此的數據庫共享給對方訪問,微服務擁有本身的獨立數據庫是微服務嚴格定義中的重要特徵。
目前消息系統有三種消息傳遞方式: 有至少一次傳遞; 至多一次傳遞; 正好一次傳遞。
至少一次意思是一個消息至少傳遞一次以上,固然會形成消息內容重複冗餘,可是可靠性提升了; 而至多一次是服務器的消息最多傳遞一次,若是再傳遞一次,就會形成負面影響,好比會重複執行一些下游的非冪等的服務。 正好一次是經過消息接收方發送確認收到的方式試圖保障每次消息傳遞都能可靠傳遞完成,可是在理論上認爲這是不可能的,由於這個發送、收到和確認的過程當中一旦出現問題,就沒法保證傳遞完成。
其實若是咱們從另一個角度來看消息傳遞,從網絡數據廣播角度看,服務器之間實現原子廣播是否可能? Kafka(卡夫卡)的創始人Jay Kreps發表過專門一篇文章談論這個問題,他認爲原子廣播至關於consensus共識,由於共識多是分佈式系統中研究最多的問題。 共識是否可能? 其實這是衆所周知的算法主攻的問題,如Paxos和Raft已經在現代分佈式系統實踐中獲得普遍實現。 最後他得出結論: 共識是現代分佈式系統發展的支柱。 卡夫卡其中心抽象是分佈式一致的日誌,其實是您能夠想象成最純粹的相似於多方共識的模擬。 因此若是你不相信共識是可能的話,那麼你也不相信卡夫卡是可能的,在這種狀況下,你不用擔憂卡夫卡的正好一次支持的可能性!
那麼使用卡夫卡如何實現相似正好一次的消息傳遞? 關鍵是將偏移量和你要保存的狀態經過JDBC事務或者JTA事務保存到數據庫,失敗恢復時從這個偏移量開始從卡夫卡中從新讀取,保證了消息和你的業務狀態數據的一致性。也實現了有效effectively地消息傳遞,,實際病不是嚴格意義上的正好一次,可是這在實踐夠用了,注意,可別使用完美主義看待這個問題,不然你永遠得不到可行的解決方案。

本文分享自微信公衆號 - 物流IT圈(exiter18)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。前端

相關文章
相關標籤/搜索