自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

為什么要重構(gòu)到微服務(wù)架構(gòu)

開發(fā) 開發(fā)工具
本文是描述使用微服務(wù)架構(gòu)來重構(gòu)現(xiàn)有系統(tǒng)的過程中我們做的選擇、取得的成果、走過的彎路,以及經(jīng)驗教訓(xùn)。

公司決定將支付業(yè)務(wù)從原來所在部門剝離出來,成為一個獨立的團隊,以應(yīng)付迅速發(fā)展的業(yè)務(wù)需求。原團隊負責支付系統(tǒng)開發(fā)的幾位同學(xué)轉(zhuǎn)到現(xiàn)團隊,形成開發(fā)班底。此后開始招聘,三個月團隊擴充到10多個人。與此同時,公司業(yè)務(wù)也在快速發(fā)展,6月份宣布會員突破2千萬。一些熱片上映往往也會引發(fā)會員注冊繳費的小高峰。其他業(yè)務(wù),包括直播,閱讀,動漫等,也都進入了發(fā)展的快車道。每天訂單量早已經(jīng)超過百萬,比去年某片上映時把系統(tǒng)打垮時還早高。移動端每個月發(fā)布一個版本,桌面則是半個月。產(chǎn)品經(jīng)理們夜以繼日地規(guī)劃各種功能,待開發(fā)功能都排到好幾個月之后。而隨著項目團隊的日益擴大,卻出現(xiàn)一些奇怪的事情:

  1. 開發(fā)效率和以前沒有太大區(qū)別,盡管隊伍擴大了4倍多,人員素質(zhì)則有所提升。
  2. 大部分開發(fā)工作還是幾位老員工在忙,新員工還比較難介入核心開發(fā)工作。

除了管理因素,作為工程師,我們還是期待從技術(shù)上找到根源所在,解決問題,提高效率。最終的決策,是使用微服務(wù)架構(gòu)來重構(gòu)現(xiàn)有系統(tǒng)。這一系列博文,描述在這過程中我們做的選擇、取得的成果、走過的彎路,以及經(jīng)驗教訓(xùn)。

一、原有架構(gòu)

從技術(shù)角度看,原有系統(tǒng)是一個基于SSH架構(gòu)的傳統(tǒng)實現(xiàn),軟件架構(gòu)整體上是大家所熟知的多層Java軟件架構(gòu):

軟件架構(gòu)整體上是大家所熟知的多層Java軟件架構(gòu)

代碼讓人看的非常懷舊,雖然開發(fā)人員和我說是4年前開發(fā)的,但這熟悉的SSH架構(gòu),可是妥妥10年前的東西。使用Apache Struts做展示層,對數(shù)據(jù)訪問層做個簡單封裝實現(xiàn)業(yè)務(wù)邏輯層,基于Spring 的AOP以及Hibernate實現(xiàn)數(shù)據(jù)訪問。 數(shù)據(jù)保存在MySQL中,單庫多表的結(jié)構(gòu)。

二、架構(gòu)問題

1. DAO層

使用Hibernate來封裝數(shù)據(jù)庫訪問操作。其優(yōu)勢是在面向?qū)ο箢I(lǐng)域,通過系統(tǒng)自動生成數(shù)據(jù)庫訪問語句的方式,使得開發(fā)者無需考慮數(shù)據(jù)庫的實現(xiàn)細節(jié),專注于對象的設(shè)計和使用,簡化了開發(fā)工作。另外,使用Hibernate還支持系統(tǒng)可以在不同類型的對象數(shù)據(jù)庫間無縫遷移。在業(yè)務(wù)對象關(guān)系復(fù)雜的管理系統(tǒng)開發(fā)中廣泛使用。存在的問題是,它隱藏了數(shù)據(jù)庫的實現(xiàn)細節(jié),這導(dǎo)致在大數(shù)據(jù)場景下開發(fā)人員很難對數(shù)據(jù)庫訪問進行優(yōu)化,而這卻是互聯(lián)網(wǎng)應(yīng)用開發(fā)的重點。

2. Service層

業(yè)務(wù)邏輯層為Controller層提供具體業(yè)務(wù)的實現(xiàn)。但在實現(xiàn)上,問題還不少。如果是嚴格按照分層架構(gòu)來實現(xiàn),對業(yè)務(wù)邏輯層進行拆分,將本地調(diào)用變成遠程調(diào)用,即可比較容易實現(xiàn)拆分。但實際中往往會碰到如下問題:

  • 這個層往往并未實現(xiàn)單向依賴,部分業(yè)務(wù)邏輯層實現(xiàn)被注入了接口層的參數(shù)(request,response),使其耦合到接口層。
  • 為了應(yīng)對不斷變更的需求,不少接口會使用map作為輸入輸出參數(shù),此類接口在維護時無法約束其參數(shù)。
  • Service層絕大部分實現(xiàn)是使用工廠模式來管理數(shù)據(jù)對象。僅對工廠類建模,未對業(yè)務(wù)實體建模。這個層的實現(xiàn)是不完整的。 這使得對業(yè)務(wù)實體的操作需要推遲到Controller層來實現(xiàn),導(dǎo)致Controller臃腫。
  • 當服務(wù)之間存在大量依賴關(guān)系時,開發(fā)人員往往會直接將Spring BeanFactory注入到各個服務(wù)中,或者簡單封裝一個FacadeService,通過這個Service可以訪問到所有的業(yè)務(wù)邏輯對象。這個類的使用導(dǎo)致無法評估Controller層對Service業(yè)務(wù)對象的具體依賴。

3. Controller層

基于Apache Struts來實現(xiàn), Apache Struts 漏洞頻繁爆發(fā),修復(fù)慢。當前已經(jīng)很少在對外的應(yīng)用中使用了。由于Service層實現(xiàn)上的問題,Controller層承擔了部分業(yè)務(wù)邏輯實現(xiàn),使其臃腫,難以測試。

三、功能問題

從功能模塊上來看,并沒有區(qū)分對端的服務(wù)以及對運營管理系統(tǒng)的服務(wù),僅實現(xiàn)了支付系統(tǒng)的基本功能:

支付系統(tǒng)的基本功能

四、實施問題

1. 可擴展性差,性能提升困難

web應(yīng)用性能瓶頸基本都在數(shù)據(jù)庫上。這個系統(tǒng)使用mysql作為數(shù)據(jù)庫。三個應(yīng)用對應(yīng)三個數(shù)據(jù)庫。沒有讀寫分離。讀寫都在一個庫上操作。數(shù)據(jù)量***的表當時在5000萬條數(shù)據(jù)。高峰期數(shù)據(jù)庫操作的QPS在1000左右,壓測結(jié)果是可以支撐2000的QPS。這個指標令我詫異。為什么能有這么好的性能?首先是,沒有復(fù)雜的查詢邏輯,所有查詢都在一個表里操作,沒有跨表事務(wù)處理,復(fù)雜的處理,分解為多個語句來執(zhí)行。最復(fù)雜的一個action中,執(zhí)行了將近20次數(shù)據(jù)查詢。其次,也是最重要的因素,這里用的是SSD磁盤。從目前情況看,撐到年底應(yīng)該是可以的,這也為我們技改爭取了足夠的時間。盡管這樣,對mysql還是沒有把握。每次運營部門搞活動,我們都玩膽戰(zhàn)心驚地盯著,祈禱活動不要太有效果。

從應(yīng)用層來看,目前讀寫比在10:1,接口日訪問量10億。高峰期訪問量在300QPS。公司業(yè)務(wù)增長迅猛,數(shù)據(jù)量半年翻一番,訪問量預(yù)估10倍增長。還有一個嚴峻的挑戰(zhàn),產(chǎn)品同學(xué)揚言要搞秒殺,秒殺…每秒十萬的量必須支持到。這就超過MYSQL能承受的壓力范圍,需要把讀操作切到內(nèi)存數(shù)據(jù)庫上,但是在SSH架構(gòu)下,讀寫分離實現(xiàn)就得傷筋動骨了。另外由于Hibernate封裝了對數(shù)據(jù)庫的操作,不用寫SQL了,精細優(yōu)化也搞不定了。每次系統(tǒng)變慢,就得求DBA,幫看看有那些SQL被卡住了。每隔一段時間,還得請DBA導(dǎo)出SQL語句,研究怎么建索引。

2. 系統(tǒng)臃腫,學(xué)習周期長

100多個接口,分為三個大項目。***項目有1300多個類,其次是600多個和300多個類。SSH架構(gòu),SVN版本控制,resin作為容器,Nginx前置路由。路由這個讓人欣慰,它是整個重構(gòu)工作的有力支撐。純后端的項目,為移動端app,PCWEB應(yīng)用提供接口。這也使得重構(gòu)工作難度大大降低。如果把前端也耦合進來,那就更酸爽了。

龐大的系統(tǒng)規(guī)模為團隊成員接手帶來困難。 支付業(yè)務(wù)獨立出來后,開發(fā)人員從原來的5人,在2個月內(nèi)擴充到10人。與此同時,興奮的產(chǎn)品同學(xué)也都跟打雞血一樣,各種想法紛紛變?yōu)楫a(chǎn)品,開發(fā)壓力驟增。但是新增的同學(xué),看著幾百個類,往往一片茫然,無法下手。不知道哪些功能實現(xiàn)了,哪些功能是待改進的。一直到3個月后,新員工才逐步進入角色。盡管如此,還是有不少恐龍級代碼,無人敢挑戰(zhàn)。***的一個類的規(guī)模是2000多行, 核心方法超過500行,大量重復(fù)代碼, 每次調(diào)整都以失敗告終。

3. 合作成本高

隨著項目組人員增加,每次新版本開發(fā)都需要多人一起合作,修改同一個項目代碼。 雖然使用版本控制工具來對分支進行管理,但是不可避免的,大量的時間花費在代碼沖突處理上。新增功能,增強功能,bug修復(fù),支持各種客戶端,都在一個項目上進行,需要建立不同的分支,高峰期五六個分支同時進行都是常見的。這種情況下,代碼沖突的頻率非常高。一個周的小版本開發(fā),1天時間在解決沖突都是很正常的。

4. 測試難度大

測試工作也逐步的惡化了。

  • 測試環(huán)境構(gòu)建難度高。隨著分支的增加,每個進入測試的分支,都需要準備獨立的測試環(huán)境。環(huán)境構(gòu)建成本高。
  • 剛測試完的功能,由于分支合并沖突處理,又得重新跑一遍。嚴重影響項目進度。

5. 上線風險高

隨著系統(tǒng)復(fù)雜度的增加,上線風險也越來也大。一個小功能的修改,打印一個日志,修復(fù)一個bug,都需要整體上線。一旦有一個地方修改錯了,這個系統(tǒng)就崩潰了。上線時間長,一次上線,半個小時是必須的。

6. 引入新技術(shù)困難

互聯(lián)網(wǎng)公司對新技術(shù)的追求和使用顯得特別饑渴,SSH框架降低開發(fā)難度和成本同時,也屏蔽了其他技術(shù)的導(dǎo)入。緩存機制,數(shù)據(jù)庫優(yōu)化,讀寫分離等,SSH有自己的一套邏輯體系,要調(diào)整姿勢,成本相對高,技術(shù)難度也大,需要對實現(xiàn)底層有深入了解。

CONWAY’S LAW

很長一段時間,這個系統(tǒng)是2-3位開發(fā)人員在維護,對外接口、運營系統(tǒng),都混雜在一起實現(xiàn),訪問量也不算大。3個獨立系統(tǒng),對應(yīng)3個版本庫,每個人負責1-2個系統(tǒng)。當有新功能添加到系統(tǒng)中的時候,大家優(yōu)先考慮的是如何對現(xiàn)有系統(tǒng)進行改進,而不會考慮是否需要建立新系統(tǒng)。而當公司做業(yè)務(wù)調(diào)整,人員迅速增加后,原有的合作方式,就需要變更了。這就應(yīng)了所謂的康威定律:

Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization’s communication structure.

我們需要一套新的機制來應(yīng)對新形式下的系統(tǒng)演化的需求。

五、分層與共享庫

避免對原有系統(tǒng)作大規(guī)模調(diào)整,我們首先考慮的是利用原系統(tǒng)分層實現(xiàn)的特點,實現(xiàn)基于層的分工。在實踐方面,以前負責的管理系統(tǒng)的開發(fā)項目,使用SSH架構(gòu)的,大部分是采用基于分層的分工:

  1. 將業(yè)務(wù)邏輯層、數(shù)據(jù)訪問層、數(shù)據(jù)表示層封裝為可以獨立維護的庫;
  2. 將接口層按照業(yè)務(wù)來拆分,將代碼依賴調(diào)整為庫依賴。
  3. 為各個獨立的庫和項目建立各自的代碼庫。
  4. 層之間通過接口來交互,基礎(chǔ)層通過單元測試來保證質(zhì)量,

這種分層的優(yōu)勢在于能夠很好地解決學(xué)習周期的問題。每個層的技術(shù)相對獨立,開發(fā)人員可以快速上手。

  1. DAO層相對簡單,因而對于團隊中的新手,可以從這個層入手,熟悉系統(tǒng)架構(gòu)和軟件過程;
  2. 業(yè)務(wù)邏輯層是整個系統(tǒng)的核心,由老員工來負責,對上可以協(xié)助顯示層的開發(fā),對下可以指導(dǎo)DAO層的新同學(xué)。
  3. 顯示層需要對HTML,CSS等技術(shù)要有所了解。

這種分工,適合10人以內(nèi)的、一同辦公的團隊。團隊之間是緊耦合的合作關(guān)系。對于大型項目,首先需要對項目按照業(yè)務(wù)進行切分,每個子項目分配到10人以內(nèi)的團隊來完成,之后對每個團隊,采用分層的分工。但采用這種合作方式,存在的問題是:

  1. 要求有很好的系統(tǒng)架構(gòu)設(shè)計。需要在編碼啟動前,將各層的接口、數(shù)據(jù)庫結(jié)構(gòu)確定下來。而這對輕架構(gòu)的互聯(lián)網(wǎng)應(yīng)用開發(fā)來說幾乎是不現(xiàn)實的。不少互聯(lián)網(wǎng)公司甚至都沒有架構(gòu)師的角色,有架構(gòu)師的公司,還有不少是形同虛設(shè)的。
  2. 團隊內(nèi)部溝通成本高。層與層之間是緊耦合的關(guān)系,對接口的修改必須通知到所有使用方。這要求開發(fā)人員之間建立穩(wěn)定的合作關(guān)系,通過約定俗成的規(guī)則,降低溝通成本。
  3. 上述各種問題仍然存在?;A(chǔ)庫的變更,都需要對線上的系統(tǒng)更新庫之后重新上線。

六、微服務(wù)

在開始支付項目改造之前,我們剛剛完成了公司數(shù)據(jù)倉庫項目的微服務(wù)架構(gòu)改進。這個項目實施詳細過程,在dockone社區(qū)做了分享,詳情參見這里。 我們認為調(diào)整為微服務(wù)架構(gòu)可以解決上述問題。

1. 性能問題

對于性能要求高的接口,可以通過建立數(shù)據(jù)緩存的方式進行優(yōu)化。

2. 學(xué)習周期

一個項目僅包含少數(shù)緊耦合的接口,接口的業(yè)務(wù)邏輯單一,開發(fā)人員1-2小時通讀代碼,即可快速上手。

3. 合作成本

每個項目相對獨立,項目之間僅通過接口來交互。確定完接口后,開發(fā)、測試、上線,都是獨立進行的,從而降低了溝通成本。

4. 版本控制

由于項目之間是接口依賴而不是代碼依賴,每個項目都可以建立獨立的代碼庫。同時項目切分的比較細,每個項目開發(fā)時,僅會有一個開發(fā)人員對其做修改。這基本就不存在代碼合并工作,也避免了代碼合并過程中的各種問題。實際上,基于微服務(wù)架構(gòu)的開發(fā),我們并沒有采用分支策略,而是直接用主干開發(fā)。

5. 測試難度

每個項目獨立部署、獨立測試。由于消除了代碼分支,沒有代碼合并的隱患,重復(fù)測試的工作量減少了。

6. 上線風險

每個項目獨立上線,就算出現(xiàn)問題了,也僅影響到少數(shù)接口。

7. 新技術(shù)

在微服務(wù)改造進行一個季度后,各種新技術(shù)被引入到系統(tǒng)中,開發(fā)不再局限于SSH架構(gòu)。Spark, Hadoop, Hbase等大數(shù)據(jù)處理相關(guān)的技術(shù),Couchbase, Redis等緩存系統(tǒng),都開始在項目中使用,并有效地解決的業(yè)務(wù)上存在的問題。

當然,有利必有弊,微服務(wù)帶來的問題,也不少,包括項目多、出問題時排查難等,在實施過程中,也積累了不少的經(jīng)驗。這些問題,將在后續(xù)的分享中逐步做介紹。

【本文為51CTO專欄作者“鳳凰牌老熊”的原創(chuàng)稿件,轉(zhuǎn)載請通過微信公眾號“鳳凰牌老熊”聯(lián)系作者本人】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關(guān)推薦

2024-09-04 17:49:27

2019-09-19 10:49:52

微服務(wù)架構(gòu)SOA

2016-09-22 16:06:21

微服務(wù)架構(gòu)RPC框架

2016-01-20 09:54:51

微服務(wù)架構(gòu)設(shè)計SOA

2020-01-18 09:35:03

微服務(wù)團隊架構(gòu)

2017-03-09 19:39:54

微服務(wù)架構(gòu)重構(gòu)

2020-07-10 08:27:55

王者榮耀微服務(wù)架構(gòu)

2023-09-15 12:30:06

微服務(wù)架構(gòu)管理

2020-09-01 10:46:55

微服務(wù)架構(gòu)服務(wù)器

2024-12-31 11:05:07

2015-02-03 09:36:45

微服務(wù)2015元年

2021-08-03 07:21:14

架構(gòu)微服務(wù)開發(fā)

2020-08-05 08:23:19

架構(gòu)Java微服務(wù)

2025-04-10 08:00:00

服務(wù)限流開發(fā)高并發(fā)

2019-05-28 10:30:16

Java架構(gòu)微服務(wù)

2017-07-25 09:55:13

微服務(wù)架構(gòu)種類

2020-04-21 11:03:34

微服務(wù)數(shù)據(jù)工具

2019-08-30 10:27:37

數(shù)據(jù)庫通信技術(shù)

2024-10-29 08:44:18

2021-06-29 06:42:54

單體架構(gòu)微服務(wù)
點贊
收藏

51CTO技術(shù)棧公眾號