hi,這裡桑小榆。 本篇,我們開始探討微服務架構這塊內容,並打算專門寫一個微服務的專欄。寫微服務的知識體系其實早有動機,把微服務架構知識梳理完整,由於很多因素沒能開展開來,所以一直擱置了。 這次,我繼續持大道至簡的思想,來探討微服務架構的全面內容。儘管我們在實際工作中並沒有用到這塊內容,本職本分或許 ...
hi,這裡桑小榆。
本篇,我們開始探討微服務架構這塊內容,並打算專門寫一個微服務的專欄。寫微服務的知識體系其實早有動機,把微服務架構知識梳理完整,由於很多因素沒能開展開來,所以一直擱置了。
這次,我繼續持大道至簡的思想,來探討微服務架構的全面內容。儘管我們在實際工作中並沒有用到這塊內容,本職本分或許是螺絲釘角色,但微服務的熱門程度以及發展趨勢,迫切使你很有必要瞭解這塊內容,並當作知識儲備起來,也許有朝一日在面試中或者和碼友談論時也能夠有些觀點。
我們先不直接引出微服務的概念,我們先瞭解一下軟體架構的演進,畢竟瞭解一個事務最好的出發點是瞭解它的背景,由來以及發展,為後續瞭解微服務更加的得心應手。
單體架構
在早期90年代互聯網發展中,產生了軟體工程,並催生了以C語言為代表的面向對象的高級語言。同時,單體架構也由此產生,我相信從事it行業的小伙伴對單體架構並不陌生。當時軟體概念還沒普及,面對需求更多以一個單體項目開發的功能模塊,所有的代碼邏輯耦合在一起,一兩個人就可以負責所有的功能業務開發,對於當時的用戶使用量來說,單體架構足夠應付。
單體架構的方式,直接幹練,到目前為止使用量也不在少數,畢竟這種架構方式也符合人類便捷思維的一種方式。類似的提出面向對象思想之前,使用的面向過程思想,一個功能按照有序的順序一步步編寫有序調用,這也是人們傾向的思考思維。
很明顯,我們能夠看到單體架構的優勢:
易於開發,直接使用開發工具創建一個項目即可入手開發。
易於部署,開發完之後,直接打包部署在適應的伺服器,例如:apache,iis,tomcat等。
易於擴展,需要擴展的功能我們也可以直接下手開發,甚至可以將項目打包多份運行在多台伺服器實現負載均衡。
然而,以現在用戶使用量的角度來看單體架構,它的弊處也隨處可見。
龐大的單體代碼庫,會嚇倒自己和同事,也會嚇跑新手。一時接手也需要花不少時間去逐個理解,單體架構龐大之後沒有清晰的模塊劃分,可能會隨著時間推移,且每個人代碼習慣也會面臨不一樣,導致模塊被分解,整體代碼變得越來越難理解,代碼的質量也逐漸下降,也就是我們俗稱的“shit mountain。”誰碰誰倒霉!
IDE過載較大,面臨成堆的代碼量,你可能早上高興上班,啟動項目的時間就已經喝了兩杯咖啡了,或許新同事的不正確操作引來一堆紅色警告,上午時間沒了,血壓也上去了。
持續部署的困難。面臨大型單體應用程式,剛開始開發完很順利,部署也很順利。然而,產品經理每次經過你的崗位,面帶微笑,提了一堆需求給你,今晚改完發佈。
改完之後你需要重新部署整個應用程式,有時還得先中斷其他後臺任務,無論受不受你當前更改的影響,最終導致問題的概率會增加。
或許因為新需求改動了組件,一部署即error警告,此時整個項目便無法運行,或許你在代碼里不小心寫了一行讓cpu飆升的代碼,導致伺服器宕機整個服務也無法使用了,真讓人頭大。
擴展應用程式可能變得困難,單體架構擴展只能在本身程式里擴展。我們雖然可以通過複製部署到多台伺服器或者雲服務來部署實現負載均衡,並根據負載數量來調整實例數量(也就是拷貝部署多少個服務)。
但是在與數據交互時,所有服務始終都是使用一個資料庫訪問所有數據,這很顯然降低了緩存效率並增加了記憶體消耗和IO流量,也就是數據訪問量上來了,本該走緩存了卻直接跑去訪問資料庫,大量訪問資料庫的同時需要頻繁調度記憶體以及頻繁輸送數據,這將會是很糟糕的情況。
擴展開發的障礙。單體應用也會阻礙擴展開發,到了一定規模之後,我們很難將UI,商品,庫存分開獨立開發,都將在一個應用程式里開發,任何一個出問題或者拖延了開發周期都將會影響到整個的服務,團隊也將必須協調開發工作和重新部署。
需要對技術堆棧做出長期承諾。開發單體程式被迫使你在開發之初時選擇的技術棧要保持一致。如果我們當初選擇了C#開發,那麼後期想使用Go開發,那麼將會是一件困難的事情,因為單體程式很難相容其他的技術棧使用,要麼將選擇重構,面對龐大的單體程式重構一堆“shit mountain”將會面臨不小的挑戰。
說了單體應用的諸多缺點,並不是我在找茬,它本身不是缺點,是在於面對型應用和超大型應用的出現(單純應用的龐大,用戶數並不龐大),以及用戶量劇增時體現出來的不適用性,迫切需要新的且適應的架構方式來解決我們的麻煩。
垂直架構
於是,垂直架構出現了,也成為豎井式架構。可能有伙伴沒聽過垂直架構,這也是架構演進的一種必然趨勢。面對單體架構的不足,架構師們很顯然會從單體架構里按照業務做垂直劃分成多個單體應用,此時由原來的單體應用變成了多單體應用部署。所謂的垂直就是在一個應用里,根據業務來劃分獨立的模塊,每個業務模塊做專一的事情並沒有直接的關聯。
將龐大的系統進行劃分多個單體應用,可以很好地實現流量分擔,解決一定程度的併發問題。
可以針對不同模塊進行優化,將減少因為一個改動影響整個系統的麻煩。
更加方便水平擴展,也就是多個單體里每個單體拷貝副本部署到多個伺服器里,更好地實現負載均衡,容錯率也顯著提高。
單體之間相互獨立,互不影響,針對不同模塊進行優化,不會因為一個組件或者一個error導致整個系統崩潰,面對新增業務的迭代更加高效。
然而,雖然是將一個單體拆分為多個單體,但是必然需要服務之間互相調用,如果某個服務的埠或者ip發生改變,調用的系統也需要手動更改,偏向硬編碼。
搭建集群時,我們拆分的多個單體應用並拷貝副本部署多套服務搭建在一起共同工作,集群之後看似一個完整的個體應用實則內部多個節點互相協同負載工作均衡。但是,垂直架構的集群將會面臨內外網負載的問題,遷移機器時影響調用方的路由,導致路徑故障無法正常使用。
服務之間的調用方式存在不統一,基於httpclient,webservice等介面的協議不統一。