這個系列是坑
系列,會說一些在系統設計,系統架構上的坑
,這些都是我想到哪說到哪,有像這篇同樣比較宏觀的坑
,後面的文章也會有到具體技術細節的(好比某個函數,某個系統調用)坑
,總之,處處都是坑,這些坑有些是我經歷過的,有些是據說的,你也能夠留言說說你遇到的坑
。前端
這一篇,咱們從重構
這個場景來看看系統架構的設計中過分設計
這個坑。程序員
首先,咱們這裏說的重構,和《重構:改善既有代碼的設計》這本書中的重構不太同樣,這是本好書,他主要說的是代碼級別的重構,這種重構是須要在編碼的時候時時刻刻進行的,更多的是一種編程思想的訓練,而咱們這篇的重構
主要是說系統設計的重構
。docker
在說以前先聊聊架構師這個職位吧,這個職位最近兩年特別特別火,哪一個公司沒個架構師好像都很差意思跟人打招呼,各位架構師打上這個標籤後頭上就頂了一個光環了,本人也認識各個公司的一些架構師,我認識的架構師分紅幾種:數據庫
系統架構師,這種技術能力是最強的,這也是通常人眼中的架構師了,這種架構師通常屬於領域架構師,對某個領域的技術有比較深刻的瞭解編程
業務架構師,我只是用了這個名字而已啊,有些地方的業務架構師其實和上面的系統架構師沒什麼兩樣,但有些業務架構師有些脫離了技術了,基本上變成了一個項目經理的角色,各類溝通,我以爲不該該算架構師了。後端
PPT架構師,這個顧名思義,這是"最高級"的架構師了,只要PPT作得酷炫就OK了,這是我等達不到的程度,呵呵呵呵。
最近還有一種說法就是架構師到底要不要會寫代碼?個人理解是沒什麼可說的,必需要會寫啊
,你一個架構師,代碼都不會寫還架構個屁啊,就算你是PPT架構師,沒時間寫代碼,但出問題了掄起袖子來解BUG的能力得有吧,並且很關鍵的一點,架構師面對的都是一羣技術宅,你連個代碼都不會寫,你以爲下面的技術宅會看得起你麼?至少你得顯得很會寫吧。安全
爲何說架構師呢?由於大部分架構上的坑都是從一個很差的設計開始的,而如今的各個系統的設計都是由架構師來操刀的。微信
技術人員最喜歡作的一件事就是重構
,由於技術宅們都看不上別人的代碼,特別是須要在別人代碼上加新功能的工做更是看不上,架構師們是技術宅的升級版,因此更加看不上別人的架構設計,因此重構
是常常作的事情,小的是功能模塊的重構,大的是整個系統的重構,總之,都是不重構不舒服斯基
。網絡
重構自己並無問題,可是須要看的是重構的時機,是否是應該重構了?架構
咱們以一個例子來詳細說說重構
中的過分設計
吧,你也能夠想一想要是遇到這樣的系統,你是架構師,你怎麼作?歡迎留言討論。
假若有個初創公司,是幫企業作OA系統的,最開始的時候是由三個程序員小哥開發出來的,系統架構很簡單,是個AllInOne
的設計,開發語言PHP,就像下圖同樣。

每當客戶有新需求,基本的操做就是加個表 --- 加個邏輯模塊 --- 修改一下界面 --- 上線
,並且通常OA系統是部署在客戶內部的,因此每次修改都是針對單獨客戶進行開發。
公司發展的愈來愈好,有了一些大公司買了他們的OA,有錢了,請了個架構師過來優化優化技術架構,架構師叫小明(每次都黑小明),小明來了一看現有設計,我去,這怎麼行?三天後,給出了他的建議
首先,數據層都在一個庫裏面,之後數據量大的話數據庫效率過低了,首先要分庫分表,把用戶數據表和事件表橫向和縱向的拆分一下,哈希到不一樣的機器上去,減輕單臺機器的壓力。
其次,AllInOne
的設計太臃腫了,要把各個模塊微服務
化,把權限
模塊,附件管理
模塊拆分出去成爲一個微服務,提供API給其餘模塊使用,方便維護,後續添加新功能作一個微服務
就好了,和其餘模塊的耦合性急劇下降。
在數據層和業務層之間加一個代理層,用個開源的中間件,之後數據端再有分庫分表操做,對上層屏蔽細節,業務人員不用關心底層數據庫細節,專心寫業務邏輯就好了。
PHP性能不太行,而且界面作出來很差看,前端分離還不完全,改爲Nodejs+Angularjs來進行先後端分離,前端人員專一頁面,作出更絢麗的頁面來,後端人員專一業務邏輯,使用RESTAPI
進行數據交互。
docker部署,每一個服務啓一個docker,對運維人員友好,並且有不少工具能夠看各個docker的健康情況。
因而,整個系統變成下面這個樣子了。

臥槽,好高大上,乍一看,這就是一個目前比較流行的架構圖了,有數據層,有中間件層,有業務層,有前端展現層,數據層支持分庫分表,能夠無限擴展,業務層微服務化,也能夠無限擴展,docker部署,一個image搞定部署,簡直了!除了消息隊列沒有用上之外,其餘的流行東西用了個遍啊。
那麼,開始幹吧,把人員分紅兩撥,一撥繼續維護現有系統,接客戶新需求,一撥開始重構,一個月時間,把數據和功能模塊梳理了一遍,而後開始定各個服務中的接口,又用了小一個月,而後所有人員投入進去開始編碼,又忙活了三個月,終於重構完成了,再花一個月時間追上這4個月新來的需求,牛逼的架構上線了!
若是小明夠厲害而且開發人員也給力的話,最好的狀況就是上線後一切正常,你不是重構麼?客戶徹底感受不到有變化,繼續使用得很high。但這種機率幾乎爲零,最有可能的狀況是什麼呢?
客戶說,臥槽,少了個功能了,臥槽,數不對了,這都是小事,新系統嘛,總歸有一些問題,解決這些bug就行了。
某天發現登陸不上了,若是在以前,跟蹤一下代碼就知道哪裏有問題了,馬上解決了,如今已經微服務了,你說是網絡問題仍是權限服務問題仍是邏輯問題呢?要跟蹤可沒那麼容易。
某天發現數據寫入和讀取都有問題,最後查問題發現是開源的中間件偶爾抽風了,要修改的話,得看中間件的源碼了,跪了吧。。。。
最關鍵的是,你會發現,上了這個新的架構之後,是耦合性下降了,但開發一個新功能的工做量比之前多了,效率反而下降了。
這就是一個典型的過分設計
,過分設計
特色:
徹底脫離了業務場景來進行技術架構的設計就是過分設計
。
這個例子中的業務場景是一個OA系統,OA系統的主要數據是企業的人和人的數據,一個企業能有多少人?一個初創公司,能接入10萬人的大公司作OA已經很是不錯了吧?即使是10萬人的大公司,人的數據也就10萬條,咱們在成100,算單個表1000萬條數據吧,單臺MySql徹底能夠hold得住,因此第一條分庫分表的設計在這個場景下就徹底沒有必要,企業主最關心的是什麼?是數據的安全可靠,因此你在這裏把MySql換成Orecle,企業主以爲安全也會買單,而且你收入還能更多,並且換成Orecle的話,單個表上億問題也不大,何須分庫分表?
好,就算你數據量巨大,須要分庫分表,那你整個中間件幹嗎?中間件的做用是屏蔽底層數據沒錯,但還有個場景是數據讀寫分離,通常是在大數據量而且有高併發需求的系統使用,你一OA系統,能有多高的併發?須要用中間件這麼高端的東西麼?
再看看微服務
,爲了下降系統的耦合度使用了微服務
,一樣場景也不對,何時須要把服務拆分出來呢?只有在當前服務已經耗費了單臺機器太多的資源了,單機扛不住了,纔會把功能比較獨立的模塊拆分紅微服務出去,由於微服務
雖然下降了系統的耦合度,可是須要更多的考慮到系統的可用性和網絡因素形成的問題,對開發人員的要求更高,一個OA系統,能有多大的計算量?
後面的先後端分離啊,docker部署啊,你想一想各自的必要程度如何?一個OA是否須要絢麗的界面?一個OA系統的更新頻率有多高?是否須要docker這樣的東西來幫助部署?成本如何?再看看是不是過分設計
?
最後,我以爲上面這個系統,比較合理的修改設計是:
把數據庫加上一個主從同步,保證數據的可靠性,別數據庫掛了,那客戶可會跟你拼命,這是最重要的。
把系統的SQL語句梳理一遍,看看有沒有什麼慢SQL,而後作針對性的優化,好比加索引,改SQL之類的。
把後端的服務加上詳細的Log信息,這樣出了問題也好查問題,而且能夠把Log收集起來作分析,看看系統的瓶頸在什麼地方,而後再在局部作優化也好重構也好,這樣對系統的侵入性最小。
這樣下來,系統的性能應該有提高,數據可靠性也加強了,而且也耗費不了多少資源,經過Log分析,一個局部一個局部的優化,直到發現了一個大坑須要拆分服務了,再進行服務的拆分,若是你有更好的建議,歡迎留言討論啊。
我以爲重構得知足如下幾個條件的大部分,纔有重構的必要,第一個條件是必須知足的。
現有系統的全部功能模塊和對外接口都瞭解得很是清楚了。若是你沒把對外接口瞭解得很是清楚,重構完了之後外部的依賴系統必然要跟着改,那就是個無底洞了。
現有系統有明顯的重大BUG,而且在現有條件下沒法解決或者很難解決。若是僅僅是系統有BUG,那麼解決BUG就行了,徹底沒有必要爲了BUG來重構,只有當確實BUG已經沒法解決或者解決的成本實在過高了,纔有重構的必要。
文檔缺失或者維護人員大量離職致使目前系統的可維護性下降,很難添加新功能。若是你們都很熟悉現有系統,能夠很快的在上面迭代新功能,你從新來一個系統幹什麼呢?
現有系統在可預見的將來沒法支撐業務的發展了。只有當業務部門已經跑到了技術部門前面了,能夠預見獲得業務發展的方向了,再來審視目前的系統,發現已經沒法繼續支撐了,這時候才須要重構現有系統。
而重構最忌諱的用如下理由來重構系統
現有代碼太臃腫,實現不完美。難道你從新實現一個就完美了?
這個系統的技術棧太陳舊,沒有使用最新的技術流,之後確定會落伍。難道用了新技術就不會落伍?
現有系統沒有考慮高可用的狀況,要是出問題了就是大問題。
這個語言就不適合作這個系統,得用XXX語言來實現。雖說每一個語言都有他擅長的場景,可是一個既有系統更換實現語言,是一件成本很是高的事情。
總而言之,重構一個系統最須要考慮的就一個詞:成本
,須要衡量各方面的成本後,再考慮是否須要重構,這樣的重構纔是有意義的重構。
OK,這一篇簡單的說了一下重構場景下的過分設計的問題,後面還會有和過分設計相關的,你也能夠說說你遇到的過分設計,歡迎留言給我哈。
若是你以爲不錯,歡迎轉發給更多人看到,也歡迎關注個人公衆號,主要聊聊搜索,推薦,廣告技術,還有瞎扯。。文章會在這裏首先發出來:)掃描或者搜索微信號XJJ267或者搜索西加加語言就行