開發

互聯網是如何把“原始人”逼成“機器人”

廣告
廣告

導讀】互聯網快速發展的這十多年,我們見證了企業軟件架構的多次迭代和演變。初期階段都使用JSP+Servlet,工程師感覺代碼直接寫在jsp頁面上不優雅,也不方便調試。后續發展為JSP+Javabean,把業務代碼封裝到JavaBean里面,頁面之間的跳轉通過JSP來完成,有了真正意義上的代碼邏輯封裝。雖然架構簡單,但是技術棧簡單上手非常容易,雖原始但是很快樂,不脫發,也沒有996。Struts的出現解決了所有的邏輯都在代碼中跳轉的弊端,通過配置化來解決跳轉和代碼的耦合。但人都是惰性動物,配置的地方太多了也感覺太麻煩,Spring提倡減少配置或者不配置來讓代碼更快捷的運行,最終Spring接管了軟件開發工程師的技術棧,同時單體應用的時代也有了一個飛躍的進步,我們進入了現代人的社會。

我們也是一個創業型公司,在創業階段快樂的使用著Spring所提供的全家桶和便利性,隨著業務規模和需求迭代頻率的增加,單體應用也從原來的“美男子”變成“中年油膩大叔”反應遲鈍了,也抗不住壓力了,快也快不了,各種問題隨之而來。

一、業務規模以及面臨問題

流量為王、用戶為王的互聯網時代,隨著投放廣告力度的增大,以及私域流量的爆發,用戶量也帶來了爆炸式的增長。整個結束團隊在“痛”并“快樂”的環境下一次又一次的交付著迭代。痛是因為現有的架構模式滿足不了業務的需求,快樂是因為業務發展的好,大家的收益會更好。 

隨著研發隊伍的壯大,項目以及迭代需求的增加,技術架構出現多種問題,這些問題極大的影響了交付速度和交付質量。主要包括如下:

代碼沖突加劇:多個人或者一個團隊一起維護一個模塊,共同開發。當提交代碼的時候發現大量沖突,每次提測或者發版的時候需要花大量的時間來解決沖突。隨著團隊規模的增大以及項目復雜程度增加,代碼沖突的現象越嚴重;

模塊耦合嚴重:模塊之間通過接口或者DB相互依賴,耦合越來越嚴重。而且不同的人,寫代碼的風格不一樣,代碼質量也不一樣,上線前需要協調多個團隊,任何小模塊的異常都會導致整個項目發布失敗;

項目質量下降:由于所有的代碼都是在一個服務里面,做一次改動,可能會牽一發而動全身,代碼沖突以及耦合嚴重,導致測試覆蓋范圍不充分,經常會出現沒有更改的模塊在線上突然出現問題,查詢后發現是由于工程師不小心做了某種改動,但是測試用例并沒有覆蓋;

團隊效率下降:由于大量時間在處理代碼沖突,消耗了研發人員大量的時間;而測試人員為了提高項目質量,不得不在每次發版之前做全方位的回歸測試,本身一次小的迭代結果項目時間卻很長;

性能達到瓶頸:QPS以及達到天花板,增加硬件配置都沒有辦法來提升性能,導致運營同學不敢大規模的做活動,因為一旦用戶量上升就會導致接口訪問超時或者數據庫CPU飆升到100%;

運維手段乏力:當線上出現問題的時候,只能通過重啟的方式來暫時緩解問題。

所以我們意識到系統架構必須要改變了,單體應用肯定不能滿足當前以及后續業務的發展了,否則會被認定技術阻礙業務的發展,這種情況是大忌,有可能會被抓出去“祭天”的。但是在技術部門上方懸浮的標語“架構方案千萬條,按時上線第一條”也提示著大家業務在發展,不會因為技術架構的變動而暫停前進。

二、平臺架構演變過程

微服務的首要階段是框架選型,在Spring Cloud和Dubbo的選型上團隊中間出現了很多爭論,經過多維度的考核最終選定Dubbo做微服務的框架。由于時間緊迫,團隊一邊做著需求迭代以及新功能上線,一邊還得做新架構開發。然而,在大家辛苦半個月后第一個版本交付測試的時候卻出現了問題,每個人負責的模塊的代碼風格不統一,框架結構不統一,其他人如果想參與到對應的模塊卻不清楚從哪里入手,培訓成本過高,所以我們必須得造輪子,讓車子跑到更快,更穩。

討論最后一致認定,如果依賴制度和文檔是不可能約束研發人員的,必須提供工具來快速的生成框架結構以及代碼邏輯,完成常用的數據庫以及緩存操作,程序員只需要往對應的偽代碼中加入業務代碼即可。本地測試通過提交Jenkins后自動編譯,服務自動注冊、自動發布Dubbo服務。同時,團隊內部約定了新框架的調用流程,避免不規范的行為再次發生。

生成代碼后的框架結構以及調用關系如下,以產品服務為例。

同時約定了系統的訪問流程和服務之間的調用原則,由于服務之間通過接口調用,原則只要上發布出來的服務都可以被調用,會形成A調用B,B也有可能調用A的循環依賴調用。所以團隊的約定如下:基礎服務(basic)層主要做數據庫的操作和一些簡單的業務邏輯,不允許調用其他任何服務;聚合服務(back)層,允許調用基礎服務層,完成復雜的業務邏輯聚合操作;不允許調用其他back層。

老系統逐步的往新架構來遷移,新平臺的TPS有非常大的提升,平臺運行的穩定性也有較大程度的提升。工程師的“痛”也逐步減輕,加班頻率也降低了很多,驚喜的發現部分人員的發量竟然增加了不少。然而,平臺是在一直演變的,沒有哪一種架構能永遠保持不變,隨著時間的推薦,用戶量還在不斷的增加,同時新項目數量也逐步增加,新架構也逐步暴露出很多問題。

微服務架構提倡將單一應用程序劃分成一組小的服務,服務之間通過RPC方式互相協調、互相配合,形成分布式調用,橫向擴充服務的數量來提高整體的QPS量。然而在簡單業務場景下并沒有任何問題,當業務場景復雜的時候就會出現A->B->C->D->E->F->G->H->I->J…N,會導致服務整體不穩定,稍微修改下業務邏輯影響一整條鏈路。或者上游需要同時通知多個下游的時候微服務的架構就會顯得單薄乏力,所以需要使用MQ來縮短整個調用鏈或者解耦同步通知多個下游的場景。例如用戶注冊流程,在未使用MQ的時候,下游需要關注用戶注冊信息的時候,只有通知上游去調用接口。但是使用MQ后,上游只需要發送MQ即可,下游訂閱MQ消費消息并處理,同時上游并不會關注下游的個數,最終整體的調用鏈縮短了,性能也有較大的提升。

每逢大促活動的時候,如何快速觸達用戶?之前的做法是先查詢用戶注冊表,然后批量寫入待發消息中心,消息中心收到請求后快速寫入DB中,然后通過定時任務來掃描并調用短信、PUSH接口。但是通過MQ可以大大提高系統的QPS。

三、MQ的選型

目前業內比較主流的 MQ 包括 RocketMQ、ActiveMQ、RabbitMQ、Kafka等,關于性能、存儲、社區活躍度等各方面的技術對比都相差不大,但我們發現通過簡單的選型對比,很難抉擇到底選擇哪款MQ產品。因為金融行業對于數據一致性以及服務可用性的要求非常高,所以任何關于技術的選項都顯得尤為重要。在做技術選型的時候,我們重點關注如下:

另外,在微服務中分布式事務是一個經典話題,如何簡單、高效的完成分布式事務對于架構者來說非常重要,在眾多的MQ中我們最終選定了商用版的RocketMQ,對于分布式事務也能非常好的支持。

經過幾次的重構后微服務中存在的問題也逐步消除,隨著MQ的加入系統的TPS又有了較大的提升,同時通過本地緩存和遠程緩存相結合的方式來高效實用緩存。對于非核心流程的RPC接口也梳理了降級和熔斷的流程,目前穩定性提升的非常多。新版的微服務架構如下:

平臺架構沒有終點、優化沒有終點,單體應用有單體應用的優勢和亮點,分布式系統有分布式系統的不足,每一家互聯網企業所面臨的階段不一樣,所以做法也不一樣。但是不要為了追求技術而使用技術,夠用就好、解決問題就好。

四、總結

構建復雜的應用真的是非常困難,單體式的架構更適合輕量級的簡單應用。如果你用它來開發復雜應用,那真的會很糟糕。微服務架構模式可以用來構建復雜應用,當然,這種架構模型也有自己的缺點和挑戰。微服務實施過程中由于會引入各種中間件,所以會出現各種各樣異常信息,對于開發人員和架構師來說都是一種挑戰。目前“云”是趨勢所在,如果條件允許的話,建議所有的中間件全部使用“云”上的產品,穩定性有保障、降低了維護成本。最后如果能真正成功實施微服務,無非是合理的組織架構、對于項目的認可、工具的合理化、持續集成過程。

原文鏈接:https://mp.weixin.qq.com/s/nVqpG9c3OW0DtGQb61mHnw

最干貨的java+分布式技術公眾號,兼及研發管理。本號專家陣容:螞蟻金服右軍、易寶CTO陳斌、米么金服總監李偉山、奧琪金科首席架構曲健、螞蟻金服高級技術專家張翔、美團高級技術專家楊彪等。

Go內存分配跟蹤調優

上一篇

56歲潘石屹下決心學Python,60歲程序語言之父們還在敲代碼,你呢

下一篇

你也可能喜歡

互聯網是如何把“原始人”逼成“機器人”

長按儲存圖像,分享給朋友

ITPUB 每周精要將以郵件的形式發放至您的郵箱


微信掃一掃

微信掃一掃
双色球常规走势图 黑龙江十一选五 四川时时彩 二分彩 配股神配资 pc蛋蛋 体彩p5 pc蛋蛋 大商道日本女优剧全集 电竞比分网实时 富盈投资 申万宏源配资 好易配资