《使用微服務,你考慮好了嗎?》要點:
本文介紹了使用微服務,你考慮好了嗎?,希望對您有用。如果有疑問,可以聯系我們。
微服務已經成為了當前最熱門的架構模式,然而也許微服務對你來說并不適用,繼續閱讀來尋找答案吧.
目前,幾乎所有人都對微服務趨之若鶩.打開你的新聞聚合客戶端你會發現,幾乎每篇文章都在講微服務架構,沒有一個公司不是通過微服務技術拯救了他們的研發部門.也許你曾經在這么一家公司工作過,通過這種輕量魔術般的服務來解決了所有遺留系統帶來的問題.
當然,事后看來,我們反而離真相更遠了.就像我們能看到視力表最末行,其實是由于提前看過了視力表導致的.
作為一個嘗試將單體應用拆分為微服務來拯救世界的公司員工,我將討論微服務運動的一些主要謬誤和陷阱.當然這篇博客并非簡單的將微服務與不好劃等號,只是希望大家通過閱讀它能夠思考微服務架構是否真的適合你們.
世界上沒有標準的定義,微服務應該包含什么、不應該包含什么.當然一些人已經成功實施微服務的人將規范編撰成冊.
我再強調一點,微服務不是一個單體.確切的說,單個微服務只處理一個非常有限的領域,它只處理它在你的技術棧中應當處理的工作.一個更確切一點的例子比如:一個銀行在線銀行業務中有一個“交易服務”(起名太困難,你懂就好),現在你打算增加一個訪問用戶交易記錄的業務,你應當把它放到交易服務之外.
另外,大家談論微服務時,總是隱含地討論微服務彼此之間需要遠程通訊.盡管他們是顯而易見的不同進程,并且通常運行在不同的計算節點上.所以通常服務之間使用REST或者其他RPC協議進行通訊.
剛剛開始時,這一切看起來還非常簡單.似乎我們只需要簡單的把領域服務通過RESTAPI暴露給其他微服務,讓微服務之間通過網絡訪問即可.然而根據我的經驗,大多數人認為的五項事實實際上并非實情:
謬誤1:微服務能讓我的代碼更簡潔
“不要把網絡邊界當作寫更好代碼的借口.”
一個簡單的事實是,任何技術棧,包括微服務在內,都不能成為寫更簡潔更易于維護的代碼的動力.雖然當條件減少時,你寫出來不科學的代碼的可能性會降低,但是這就像是通過減少商店里的貴重物品來降低犯罪率一樣,沒有解決任何問題.
一個流行的方法是圍繞一個領域的邏輯服務構建你的代碼結構.這反映了微服務的理念:它可以幫助你顯式地管理領域所需的依賴關系,并使得關鍵業務邏輯不會蔓延到多個地方.此外這些服務之間的調用不再過度使用網絡,也避免了一些潛在問題的發生.
這種方法的好處在于,基于良好的前期設計和對領域的準確理解,你很容易將它抽取出來,一旦你決定了采用微服務架構,它能幫助你非常準確地圍繞微服務構建面向服務架構.一個堅固的SOA方法開始于代碼本身,并隨著時間地推移,將它擴展到整個技術棧當中.
謬誤2:微服務容易實現
“分布式事務從來不簡單.”
雖然最開始看起來非常簡單,但是大多數領域(尤其是對那些初創公司需要經過多次原型迭代和改造的領域)并不適合將他們規規矩矩地劃分成為不同的領域.通常一個特定的子領域需要訪問其他子域的數據來正確地完成相應的工作.當需要向它自己以外的領域寫入數據時,事情會變得更加的復雜.一旦你打破了自己的業務范圍,并且需要其他人參與請求流來存儲修改數據時,那你就必須面對分布式事務(有時被稱作Sagas).
在一個請求中涉及到多個遠程服務需要通訊時,復雜的問題便隨之而來了.例如調用是否可以并行,或者必須串行完成?你是否意識到這些調用中任何一個環節都有潛在地發生錯誤的可能性(包括應用錯誤和網絡錯誤)?這對請求本身來說意味著什么?通常每個分布式事務都需要他們自己來處理可能發生的故障,這很可能帶來巨大的工作量,不僅僅是錯誤的解析、錯誤的處理,更包括如何在出現錯誤時恢復事務.
謬誤3:微服務更快
“一些簡單的優化可以在單體系統中獲得巨大的性能提升.”
這條似乎很難被否定,因為事實上你可以通過減少單個系統的依賴或者做事情的數量來提高他們的速度.但這是一個看起來如此的方法.我并不懷疑轉向微服務架構后通過代碼路徑的隔離讓系統速度提升,但是你也應該意識到,系統內增加了通過網絡的調用.網絡請求永遠不會像同一系統中調用那樣快,盡管通常它可以足夠快.
此外,許多關于性能提升的故事實際上是在宣傳一種新的語言或者技術棧帶來的好處,而不僅僅是通過將代碼架構遷移到微服務上.將原有系統從RubyonRails、Django或者NodeJS遷移至像Scala和Go(微服務架構中兩種流行的選擇),這樣語言技術本身就能帶來很多性能改善.但是這些語言并不真的“關心”是否工作在“微”服務里面,他們只是單純的為了提高性能而存在.
此外,對于大多數應用來講,CPU和內存永遠不是性能瓶頸,I/O才是.通過網絡進行的調用,會為你的系統增加更多的I/O請求.
謬誤4:對開發人員更簡單
“開發人員工作在彼此隔離的代碼庫時容易導致‘不是我的問題’綜合癥.”
雖然聽起來一個小團隊專注于一個問題上,處理問題會更加簡單,然而這會帶來許多其他的問題,比如更難以從根本上解決問題.
最大的問題是你必須多做許多工作,你必須運行越來越多的服務,即使為了很小的一個變化.這樣你不得不投入一些精力來建立和維護能讓工程師在本地運行他們的辦法.Docker技術可以讓著更容易些,但是仍需要有人來維護他們.
另外,這讓寫測試也變得更加困難,因為一個恰當的集成測試意味著需要理解并覆蓋所有服務之間的彼此調用,以及捕獲處理相應的錯誤等.這也意味著需要花更多的時間來理解系統才能更好的開發.雖然我永遠不會說工程師花時間理解系統是在浪費時間,但是我要警告大家的是,不要過早地添加這些復雜性,除非你真的認為你需要他們.
最后,它也會造成一些社交上的問題.跨越多個服務的Bug需要多處修改才能解決,多個團隊需要同步協調他們解決問題的進程.它也有可能造成一種情況,就是人們對Bug缺乏責任感,并盡可能地將問題推給其他團隊.當工程師在同一個代碼庫中進行工作時,他們共享所有的知識,承擔共同的責任,而不是成為孤立王國的國王和王后.
謬誤5:可擴展性更強
“擴容微服務就像擴容單體應用一樣簡單.”
將服務打包成離散單元,然后通過類似Docker的方式進行擴展,這似乎是一個水平伸縮的好方法,不過遺憾的是,這種說法并不對.
說它不正確,是因為這種方法不僅僅能用于微服務,更可以用于單體服務.你可以為你的單體應用創建邏輯集群,只處理某項業務的流量.比如API請求、前端儀表盤和后臺任務服務器可以在相同的代碼庫里面,但并不需要每個都處理三個不同的業務.
好處就像是微服務一樣,不同的集群承擔不同的工作負載,可以單獨擴容一個集群來應對流量的激增.所以,雖然微服務提供了很多方法,你同樣可以把這些方法引入到單體應用中去.
“當你準備好成為一個工程化組織時.”
最后我想說,時間恰當時,可以遷移至微服務(或者你知道這是否是正確的開始方式).
實現微服務的一個至關重要最堅實可行的重要步驟是,你能夠正確理解你正在工作的領域.如果你不理解它,或者你正在試圖弄清它,那么微服務則是有害無利.當你真正深刻地理解你的領域,知道邊界在哪里依賴是什么,那么遷移至微服務架構才有可能是正確的選擇.
另一個重要的事情是處理你的業務流,具體來說,就是業務如何進行分布式事務.如果你知道每一類請求通過系統的路徑,并且了解每個路徑上可能失敗的位置、方式和原因,那么你可以著手開始構建一個處理請求的分布式模型.
除了了解您的業務流之外,還需要監控你的工作流程.監控是微服務和單體之爭的事情,但是它應當是你的工程化的核心工作之一.因為你需要大量的數據來發現系統為何性能不佳甚至引發錯誤.只有你能找到一個可靠的方法來監視系統的各個部分,你才可以知道如何來優化它.
最后,當你真正可以向研發團隊和業務方展示價值時,遷移到微服務才可以幫助你承擔增長的業務、擴容和賺錢.雖然說嘗試新鮮事物是有趣的,但是你真正開始前,應當明白對于許多公司來說,什么是他們的底線.如果因為一篇博客文章告訴你單體應用不科學,而導致新功能的延期交付進而影響到業務收入時,你必須去迎合你的業務.有時候這些權衡是值得的,有時候不是.能正確認識到當前應當著力解決的問題,并以此來做技術的權衡,長期來看才是真正有益的.
最后的最后
希望下次有人提出微服務架構時,你能想明白實施微服務架構的條件是否成熟.就像我一開始所說的,本文并不是來說微服務是糟糕的,是希望你開始之前,能夠避免這條道路上會出現的一些坑.
如果你問我應當怎么做,我建議通過代碼中清晰定義的模塊結構來建立內部服務,并且隨著時間的推移,逐漸將他們劃分成獨立的服務.這種方法不一定是最好,但也不失為避免爛代碼進入系統的一個方法.當你準備好時,它能很快地幫你遷移到微服務架構上.
文章出處:Docker(訂閱號ID:dockerone)