[轉(zhuǎn)]我做系統(tǒng)架構(gòu)的一些原則

[轉(zhuǎn)]我做系統(tǒng)架構(gòu)的一些原則

工作 20 多年了氏仗,這 20 來年看到了很多公司系統(tǒng)架構(gòu)胸墙,也看到了很多問題何乎,在跟這些公司進(jìn)行交流和討論的時(shí)候蚜印,包括進(jìn)行實(shí)施和方案比較的時(shí)候担猛,都有很多各種方案的比較和妥協(xié)松蒜,因?yàn)橄嚓P(guān)的經(jīng)歷越來越多擂涛,所以读串,逐漸形成了自己的邏輯和方法論。今天歼指,想寫下這篇文章爹土,把我的這些個(gè)人的經(jīng)驗(yàn)和想法總結(jié)下來,希望能夠讓更多的人可以參考和借鑒踩身,并能夠做出更好的架構(gòu)來胀茵。另外,我的這些思維方式和原則都針對(duì)于現(xiàn)有市面上眾多不合理的架構(gòu)和方案挟阻,所以琼娘,也算是一種“糾正”……(注意峭弟,這篇文章所說的這些架構(gòu)上的原則,一般適用于相對(duì)比較復(fù)雜的業(yè)務(wù)脱拼,如果只是一些簡(jiǎn)單和訪問量不大的應(yīng)用瞒瘸,那么你可能會(huì)得出相反的結(jié)論)

原則一:關(guān)注于真正的收益而不是技術(shù)本身

對(duì)于軟件架構(gòu)來說,我覺得第一重要的是架構(gòu)的收益熄浓,如果不說收益情臭,只是為了技術(shù)而技術(shù),而沒有任何意義赌蔑。對(duì)于技術(shù)收益來說俯在,我覺得下面這幾個(gè)收益是非常重要的:

  • 是否可以降低技術(shù)門檻加快整個(gè)團(tuán)隊(duì)的開發(fā)流程。能夠加快整個(gè)團(tuán)隊(duì)的工程流程娃惯,快速發(fā)布跷乐,是軟件工程一直在解決的問題,所以趾浅,系統(tǒng)架構(gòu)需要能夠進(jìn)行并行開發(fā)愕提,并行上線和并行運(yùn)維,而不會(huì)讓某個(gè)團(tuán)隊(duì)成為瓶頸點(diǎn)皿哨。(注:就算拖累團(tuán)隊(duì)的原因是組織構(gòu)架浅侨,也不妨礙我們做出并行的系統(tǒng)架構(gòu)設(shè)計(jì))
  • 是否可以讓整個(gè)系統(tǒng)可以運(yùn)行的更穩(wěn)定。要讓整個(gè)系統(tǒng)可以運(yùn)行的更為的穩(wěn)定往史,提升整個(gè)系統(tǒng)的 SLA仗颈,就需要對(duì)有計(jì)劃和無計(jì)劃的停機(jī)做相應(yīng)的解決方案(參看《關(guān)于高可用的架構(gòu)》)
  • 是否可以通過簡(jiǎn)化和自動(dòng)化降低成本。最高優(yōu)化的成本是人力成本椎例,人的成本除了慢和貴挨决,還有經(jīng)常不斷的 human error。如果不能降低人力成本订歪,反而需要更多的人脖祈,那么這個(gè)架構(gòu)設(shè)計(jì)一定是失敗的。除此之外刷晋,是時(shí)間成本盖高,資金成本。

如果一個(gè)系統(tǒng)架構(gòu)不能在上面三個(gè)事上起到作用眼虱,那就沒有意義了喻奥。

原則二:以應(yīng)用服務(wù)和 API 為視角,而不是以資源和技術(shù)為視角

國(guó)內(nèi)很多公司都會(huì)有很多分工捏悬,基本上都會(huì)分成運(yùn)維和開發(fā)撞蚕,運(yùn)維又會(huì)分成基礎(chǔ)運(yùn)維和應(yīng)用運(yùn)維,開發(fā)則會(huì)分成基礎(chǔ)核心開發(fā)和業(yè)務(wù)開發(fā)过牙。不同的分工會(huì)導(dǎo)致完全不同的視角和出發(fā)點(diǎn)甥厦。比如纺铭,基礎(chǔ)運(yùn)維和開發(fā)的同學(xué)更多的只是關(guān)注資源的利用率和性能,而應(yīng)用運(yùn)維和業(yè)務(wù)開發(fā)則更多關(guān)注的是應(yīng)用和服務(wù)上的東西刀疙。這兩者本來相關(guān)無事舶赔,但是因?yàn)榉植际郊軜?gòu)的演進(jìn),導(dǎo)致有一些系統(tǒng)已經(jīng)說不清楚是基礎(chǔ)層的還是應(yīng)用層的了谦秧,比如像服務(wù)治理上的東西竟纳,里面即有底層基礎(chǔ)技術(shù),也需要業(yè)務(wù)的同學(xué)來配合油够,包括 k8s 也樣蚁袭,里面即有底層的如網(wǎng)絡(luò)這樣的技術(shù),也有需要業(yè)務(wù)配合的 readniess和 liveness 這樣的健康檢查石咬,以及業(yè)務(wù)應(yīng)用需要 configMap 等等 ……

這些東西都讓我感覺到所謂 DevOps,其實(shí)就是因?yàn)楹芏嗉夹g(shù)和組件已經(jīng)分不清是 Dev 還是 Ops 的了卖哎,所以鬼悠,需要合并 Dev和 Ops。而且亏娜,整個(gè)組織和架構(gòu)的優(yōu)化焕窝,已經(jīng)不能通過調(diào)優(yōu)單一分工或是單一組件能夠有很大提升的了。其需要有一種自頂向下的维贺,整體規(guī)劃它掂,統(tǒng)一設(shè)計(jì)的方式,才能做到整體的提升(可以試想一下城市交通的優(yōu)化溯泣,當(dāng)城市規(guī)模到一定程度的時(shí)候虐秋,整體的性能你是無法通過優(yōu)化幾條路或是幾條街區(qū)來完成的,你需要對(duì)整個(gè)城市做整體的功能體的規(guī)劃才可能達(dá)到整體效率的提升)垃沦。而為了做到整體的提升客给,需要所有的人都要有一個(gè)統(tǒng)一的視角和目標(biāo),這幾年來肢簿,我覺得這個(gè)目標(biāo)就是——要站在服務(wù)和 對(duì)外API的視角來看問題靶剑,而不是技術(shù)和底層的角度。

原則三:選擇最主流和成熟的技術(shù)

技術(shù)選型是一件很重要的事池充,技術(shù)一旦選錯(cuò)桩引,那會(huì)導(dǎo)致整個(gè)架構(gòu)需要做調(diào)整,而對(duì)架構(gòu)的調(diào)整重來都不是一件簡(jiǎn)單的事收夸,我在過去幾年內(nèi)坑匠,當(dāng)系統(tǒng)越來越復(fù)雜的時(shí)候,用戶把他們的 PHP咱圆,Python, .NET笛辟,或 Node.js 的架構(gòu)完全都遷移到 Java + Go 的架構(gòu)上來的案例不斷的發(fā)生功氨。這個(gè)過程還是非常痛苦的,但是你沒有辦法手幢,當(dāng)你的系統(tǒng)越來越復(fù)雜捷凄,越來越大時(shí),你就再也不能在一些玩具技術(shù)上玩了围来,你需要的更為工業(yè)化的技術(shù)跺涤。

  • 盡可能的使用更為成熟更為工業(yè)化的技術(shù)棧,而不是自己熟悉的技術(shù)棧监透。 所謂工業(yè)化的技術(shù)棧桶错,你可以看看大多數(shù)公司使用的技術(shù)棧,比如:互聯(lián)網(wǎng)胀蛮,金融院刁,電信……等等 ,大公司會(huì)有更多的技術(shù)投入粪狼,也需要更大規(guī)模的生產(chǎn)退腥,所以,他們使用的技術(shù)通常來說都是比較工業(yè)化的再榄。在技術(shù)選型上狡刘,千萬不要被——“你看某個(gè)視頻公司也在用這個(gè)技術(shù)”,或是一些在論壇上看到的一些程序員吐槽技術(shù)的觀點(diǎn)(沒有任何的數(shù)據(jù)困鸥,只有自己的喜好)來決定自己的技術(shù)嗅蔬,還是看看主流大多數(shù)公司實(shí)際在用的技術(shù)棧,會(huì)更靠譜一些疾就。

  • 選擇全球流行的技術(shù)澜术,而不是中國(guó)流行的技術(shù)。技術(shù)這個(gè)東西一定是一個(gè)全球化的東西虐译,不是一個(gè)局域化的事瘪板。所以,一定要選國(guó)際化的會(huì)更好漆诽。另外侮攀,千萬不要被某些公司的“特別案例”騙過去了,那怕這個(gè)案例很性感厢拭,關(guān)鍵還是要看解決問題的思路和采用的技術(shù)是否具有普世性兰英。只有普世性的技術(shù)有更強(qiáng)的生命力。

  • 盡可能的使用紅利大的主流技術(shù)供鸠,而不要自己發(fā)明輪子畦贸,更不要魔改。我見過好些個(gè)公司魔改開源軟件,比如有個(gè)公司同魔改mesos,最后改著改著發(fā)現(xiàn)自己發(fā)明另一個(gè) kubernetes。我還見過很多公司或技術(shù)團(tuán)隊(duì)喜歡自己發(fā)明自己的專用輪子旺韭,最后都會(huì)被主流開源軟件所取代。完全沒有必要君账。不重新發(fā)明輪子,不魔改沈善,不是因?yàn)樽约杭夹g(shù)不能乡数,而是因?yàn)椋@個(gè)世界早已不是自己干所有事的年代了闻牡,這個(gè)時(shí)代是要想盡方法跟整個(gè)產(chǎn)業(yè)净赴,整個(gè)技術(shù)社區(qū)融合和合作,這樣才會(huì)有最大的收益罩润。那些試圖因?yàn)槟硞€(gè)特例需要自成一套的玩法玖翅,短期沒問題,但長(zhǎng)期來說割以,我都不看好烧栋。

  • 絕大多數(shù)情況下,如無非常特殊要求拳球,選 Java基本是不會(huì)錯(cuò)的。一方面珍特,這是因?yàn)?Java 的業(yè)務(wù)開發(fā)的生產(chǎn)力是非常好的祝峻,而且有 Spring 框架保障,代碼很難寫爛扎筒,另外莱找,Java 的社區(qū)太成熟了,你需要的各種架構(gòu)和技術(shù)都可以很容易獲得嗜桌,技術(shù)紅利實(shí)在是太大奥溺。這種運(yùn)行在JVM上的語(yǔ)言有太多太多的好處了。在 Java 的技術(shù)棧上骨宠,你的架構(gòu)風(fēng)險(xiǎn)和架構(gòu)的成本(無論是人力成本浮定,時(shí)間成本和資金成本)從長(zhǎng)期來說都是最優(yōu)的

在我見過的公司中,好些公司的架構(gòu)都被技術(shù)負(fù)責(zé)人個(gè)人的喜好层亿、擅長(zhǎng)和個(gè)人經(jīng)驗(yàn)給綁架了桦卒,完全不是從一個(gè)客觀的角度來進(jìn)行技術(shù)選型。其實(shí)匿又,從 0 到 1 的階段方灾,你用什么樣的技術(shù)都行,如果你做一個(gè)簡(jiǎn)單的應(yīng)用,沒有事務(wù)處理沒有復(fù)雜的交易流程裕偿,比如一些論壇洞慎、社交之類的應(yīng)用,你用任何語(yǔ)言都行嘿棘。但是如果有一天你的系統(tǒng)變復(fù)雜了劲腿,需要處理交易了,量也上來了蔫巩,從 1 到 10谆棱,甚至從 10 到 100,你的開發(fā)團(tuán)隊(duì)也變大了圆仔,需要構(gòu)建的系統(tǒng)越來越大垃瞧,你可能會(huì)發(fā)現(xiàn)你只有一個(gè)選擇,就是 Java坪郭。想想京東從.NET 到 Java个从,淘寶從 PHP 到 Java……

注,一些有主觀喜好的人一定會(huì)對(duì)我上述對(duì) Java 的描述感到不適歪沃,我還用一些證據(jù)說明一下——全中國(guó)所有的電商平臺(tái)嗦锐,幾百家銀行,三大電信運(yùn)營(yíng)商沪曙,所有的保險(xiǎn)公司奕污,劵商的系統(tǒng),醫(yī)院里的系統(tǒng)液走,電子政府系統(tǒng)碳默,等等,基本都是用 Java 開發(fā)的缘眶,包括 AWS 的主流語(yǔ)言也是 Java嘱根,阿里云一開始用 C++/Python 寫控制系統(tǒng),后面也開始用 Java ……你可能會(huì)說 B站是用 go語(yǔ)言巷懈,但是你可能不知道 B 站的電商和大數(shù)據(jù)是用 Java……懂著數(shù)據(jù)分析的同學(xué)该抒,建議上各大招聘網(wǎng)站上搜一下 Java 的職位數(shù)量,你就知道某個(gè)技術(shù)是否主流和熱門……

原則四:完備性會(huì)比性能更重要

我發(fā)現(xiàn)好些公司的架構(gòu)師做架構(gòu)的時(shí)候顶燕,首要考慮的是架構(gòu)的性能是否能夠撐得住多大多大的流量凑保,而不是考慮系統(tǒng)的完備性和擴(kuò)展性。所以割岛,我已經(jīng)多次見過這樣的案例了愉适,一開始直接使用 MongoDB 這樣的非關(guān)系型數(shù)據(jù)庫(kù),或是把數(shù)據(jù)直接放在 Redis 里癣漆,而直接放棄關(guān)系型數(shù)據(jù)庫(kù)的數(shù)據(jù)完備性的模型维咸,而在后來需要在數(shù)據(jù)上進(jìn)行關(guān)系查詢的時(shí)候,發(fā)現(xiàn) NoSQL 的數(shù)據(jù)庫(kù)在 Join 上都表現(xiàn)的太差,然后就開始各種飛線癌蓖,為了不做 Join 就開始冗余數(shù)據(jù)瞬哼,然而自己又維護(hù)不好冗余數(shù)據(jù)后帶來的數(shù)據(jù)一致性的問題,導(dǎo)致數(shù)據(jù)上的各種錯(cuò)亂丟失租副。

所以坐慰,我給如下的一些如下的架構(gòu)原則:

  • 使用最科學(xué)嚴(yán)謹(jǐn)?shù)募夹g(shù)模型為主,并以不嚴(yán)謹(jǐn)?shù)哪P妥鳛檠a(bǔ)充用僧。對(duì)于上面那個(gè)案例來說结胀,就是——永遠(yuǎn)使用完備支持 ACID 的關(guān)系型數(shù)據(jù)庫(kù),然后用 NoSQL 作補(bǔ)充责循,而不是完全放棄關(guān)系型數(shù)據(jù)庫(kù)糟港。這里的原則就是所謂的“先緊后松”,一開始緊了院仿,你可以慢慢松秸抚,但是開始松了,以后你想緊再也緊不過來了歹垫。

  • 性能上的東西剥汤,總是有很多解的。我這么多年的經(jīng)歷告訴我排惨,性能上的事吭敢,總是有解的,手段也是最多的暮芭,這個(gè)比起架構(gòu)的完備性和擴(kuò)展性來說真的不必太過擔(dān)心省有。
    為了追求所謂的性能,把整個(gè)系統(tǒng)的完備性丟失掉谴麦,相當(dāng)?shù)氐貌粌斒А?/p>

原則五:制定并遵循服從標(biāo)準(zhǔn)、規(guī)范和最佳實(shí)踐

這個(gè)原則是非常重要的伸头,因?yàn)橹挥蟹牧藰?biāo)準(zhǔn)匾效,你的架構(gòu)才能夠有更好的擴(kuò)展性。比如:我經(jīng)常性的見到很多公司的系統(tǒng)既沒有服從業(yè)界標(biāo)準(zhǔn)恤磷,也沒有形成自己公司的標(biāo)準(zhǔn)面哼,感覺就像一群烏合之眾一樣。最典型的例子就是 HTTP 調(diào)用的狀態(tài)返回碼扫步。業(yè)內(nèi)給你的標(biāo)準(zhǔn)是 200表示成功魔策,3xx 跳轉(zhuǎn),4xx 表示調(diào)用端出錯(cuò)河胎,5xx 表示服務(wù)端出錯(cuò)闯袒,我實(shí)在是不明白為什么無論成功和失敗大家都喜歡返回 200,然后在 body 里指出是否error(前兩年我在微信公眾號(hào)里看到一個(gè)有一定名氣的互聯(lián)網(wǎng)老兵推薦使用無論正確還是出錯(cuò)都返回 200 的做法,我在后臺(tái)再三確認(rèn)后政敢,我發(fā)現(xiàn)這樣的架構(gòu)師真是害人不淺)其徙。這樣做最大的問題是——監(jiān)控系統(tǒng)將在一種低效的狀態(tài)下工作。監(jiān)控系統(tǒng)需要把所有的網(wǎng)絡(luò)請(qǐng)求包打開后才知道是否是錯(cuò)誤喷户,而且完全不知道是調(diào)用端出錯(cuò)還是服務(wù)端出錯(cuò)唾那,于是一些像重試或熔斷這樣的控制系統(tǒng)完全不知道怎么搞(如果是 4xx錯(cuò),那么重試或熔斷是沒有意義的褪尝,只有 5xx 才有意義)闹获。有時(shí)候,我會(huì)有種越活越退步的感覺河哑,錯(cuò)誤碼設(shè)計(jì)這種最基本最基礎(chǔ)的東西為什么會(huì)沒有避诽?并且一個(gè)公司會(huì)任由著大家亂來?這些基礎(chǔ)技能怎么就這樣丟掉了灾馒?

還有茎用,我還見過一些公司,他們整個(gè)組織沒有一個(gè)統(tǒng)一的用戶 ID 的設(shè)計(jì)睬罗,各個(gè)系統(tǒng)之間同步用戶的數(shù)據(jù)是通過用戶的身份證 ID轨功,是的,就是現(xiàn)實(shí)世界的身份證 ID容达,包括在網(wǎng)關(guān)上設(shè)置的用戶白名單居然也是用身份證 ID古涧。我對(duì)這個(gè)公司的內(nèi)的用戶隱私管理有很大的擔(dān)憂。一個(gè)企業(yè)花盐,一個(gè)組織羡滑,如果沒有標(biāo)準(zhǔn)和規(guī)范,也就會(huì)有抽象算芯,這一定是要出各種亂子的柒昏。

下面,我羅列一些你需要注意的標(biāo)準(zhǔn)和規(guī)范(包括但不限于):

  • 服務(wù)間調(diào)用的協(xié)議標(biāo)準(zhǔn)和規(guī)范熙揍。 這其中包括 Restful API路徑, HTTP 方法职祷、狀態(tài)碼、標(biāo)準(zhǔn)頭届囚、自定義頭等有梆,返回?cái)?shù)據(jù) JSon Scheme……等。
  • 一些命名的標(biāo)準(zhǔn)和規(guī)范意系。這其中包括如:用戶 ID泥耀,服務(wù)名、標(biāo)簽名蛔添、狀態(tài)名痰催、錯(cuò)誤碼兜辞、消息、數(shù)據(jù)庫(kù)……等等
  • 日志和監(jiān)控的規(guī)范陨囊。這其中包括:日志格式弦疮,監(jiān)控?cái)?shù)據(jù),采樣要求蜘醋,報(bào)警……等等
  • 配置上的規(guī)范胁塞。這其中包括:操作系統(tǒng)配置、中間件配置压语,軟件包……等等
  • 中間件使用的規(guī)范啸罢。數(shù)據(jù)庫(kù),緩存胎食、消息隊(duì)列……等等
  • 軟件和開發(fā)庫(kù)版本統(tǒng)一扰才。整個(gè)組織架構(gòu)內(nèi),軟件或開發(fā)庫(kù)的版本最好每年都升一次級(jí)厕怜,然后在各團(tuán)隊(duì)內(nèi)統(tǒng)一衩匣。

這里重要說一下兩個(gè)事:

  • Restful API 的規(guī)范。我覺得是非常重要的粥航,這里給兩個(gè)我覺得寫得最好的參考:PaypalMicrosoft 琅捏。Restful API 有一個(gè)標(biāo)準(zhǔn)和規(guī)范最大的好處就是監(jiān)視可以很容易地做各種統(tǒng)計(jì)分析,控制系統(tǒng)可以很容易的做流量編排和調(diào)度递雀。
  • 另一個(gè)是服務(wù)調(diào)用鏈追蹤柄延。對(duì)于服務(wù)調(diào)用鏈追蹤來說,基本上都是參考于 Google Dapper 這篇論文缀程,目前有很多的實(shí)現(xiàn)搜吧,最嚴(yán)格的實(shí)現(xiàn)是 Zipkin,這也是 Spring Cloud Sleuth 的底層實(shí)現(xiàn)杨凑。Zipkin 貼近 Google Dapper 論文的好處在于——無狀態(tài)滤奈,快速地把 Span 發(fā)出來,不消耗服務(wù)應(yīng)用側(cè)的內(nèi)存和 CPU撩满。這意味著僵刮,監(jiān)控系統(tǒng)寧可自己死了也不能干擾實(shí)際應(yīng)用。
  • 軟件升級(jí)鹦牛。我發(fā)現(xiàn)很多公司包括 BAT,他們完全沒有軟件升級(jí)的活動(dòng)勇吊,全靠開發(fā)人員自發(fā)曼追。然而,這種成體系的活動(dòng)汉规,是永遠(yuǎn)不可能靠大眾的自發(fā)形成的礼殊。一個(gè)公司至少一年要有一次軟件版本升級(jí)的review驹吮,然后形成軟件版本的統(tǒng)一和一致,這樣會(huì)極太簡(jiǎn)化系統(tǒng)架構(gòu)的復(fù)雜度晶伦。

原則六:重視架構(gòu)擴(kuò)展性和可運(yùn)維性

在我見過很多架構(gòu)里碟狞,技術(shù)人員只考慮當(dāng)下,但從來不考慮系統(tǒng)的未來擴(kuò)展性和可運(yùn)維性婚陪。所謂的管生不管養(yǎng)族沃。如果你生下來的孩子胳膊少腿,嚴(yán)重畸形泌参,那么未來是很難玩的脆淹。因?yàn)榧軜?gòu)和軟件不是寫好就完的,是需要不斷修改不斷維護(hù)的沽一,80%的軟件成本都是在維護(hù)上盖溺。所以,如何讓你的架構(gòu)有更好的擴(kuò)展性铣缠,可以更容易地運(yùn)維烘嘱,這個(gè)是比較重要的。所謂的擴(kuò)展性蝗蛙,意味著蝇庭,我可以很容易地加更多的功能,或是加入更多的系統(tǒng)歼郭,而所謂可運(yùn)維遗契,就是說我可以對(duì)線上的系統(tǒng)做任意的變更。擴(kuò)展性要求的是有標(biāo)準(zhǔn)規(guī)范且不耦合的業(yè)務(wù)架構(gòu)病曾,可運(yùn)維性要求的則是可控的能力牍蜂,也就是一組各式各樣的控制系統(tǒng)。

  • 通過服務(wù)編排架構(gòu)來降低服務(wù)間的耦合泰涂。比如:通過一個(gè)業(yè)務(wù)流程的專用服務(wù)鲫竞,或是像 Workflow,Event Driven Architecture 逼蒙, Broker从绘,Gateway,Service Discovery 等這類的的中間件來降低服務(wù)間的依賴關(guān)系是牢。
  • 通過服務(wù)發(fā)現(xiàn)或服務(wù)網(wǎng)關(guān)來降低服務(wù)依賴所帶來的運(yùn)維復(fù)雜度僵井。服務(wù)發(fā)現(xiàn)可以很好的降低相關(guān)依賴服務(wù)的運(yùn)維復(fù)雜度,讓你可以很輕松的上線或下線服務(wù)驳棱,或是進(jìn)行服務(wù)伸縮批什。
  • 一定要使用各種軟件設(shè)計(jì)的原則。比如:像SOLID這樣的原則(參看《一些軟件設(shè)計(jì)的原則》)社搅,IoC/DIP驻债,SOA 或 Spring Cloud 等 架構(gòu)的最佳實(shí)踐(參看《SteveY對(duì)Amazon和Google平臺(tái)的吐槽》中的 Service Interface 的那幾條軍規(guī))乳规,分布式系統(tǒng)架構(gòu)的相關(guān)實(shí)踐(參看:《分布式系統(tǒng)的事務(wù)處理》,或微軟件的 《Cloud Design Patterns》)……等等

原則七:對(duì)控制邏輯進(jìn)行全面收口

所有的程序都會(huì)有兩種邏輯合呐,一種是業(yè)務(wù)邏輯暮的,一種是控制邏輯,業(yè)務(wù)邏輯就是完成業(yè)務(wù)的邏輯淌实,控制邏輯是輔助冻辩,比如你用多線程,還是用分布式翩伪,是用數(shù)據(jù)庫(kù)還是用文件微猖,如何配置、部署缘屹,運(yùn)維凛剥、監(jiān)控,事務(wù)控制轻姿,服務(wù)發(fā)現(xiàn)犁珠,彈性伸縮,灰度發(fā)布互亮,高并發(fā)犁享,等等,等等 ……這些都是控制邏輯豹休,跟業(yè)務(wù)邏輯沒有一毛錢關(guān)系炊昆。控制邏輯的技術(shù)深度會(huì)通常會(huì)比業(yè)務(wù)邏輯要深一些威根,門檻也會(huì)要高一些凤巨,所以,最好要專業(yè)的程序員來負(fù)責(zé)控制邏輯的開發(fā)洛搀,統(tǒng)一規(guī)劃統(tǒng)一管理敢茁,進(jìn)行收口。這其中包括:

  • 流量收口留美。包括南北向和東西向的流量的調(diào)度彰檬,主要通過流量網(wǎng)關(guān),開發(fā)框架 SDK或 Service Mesh 這樣的技術(shù)谎砾。
  • 服務(wù)治理收口逢倍。包括:服務(wù)發(fā)現(xiàn)、健康檢查景图,配置管理较雕、事務(wù)、事件症歇、重試郎笆、熔斷、限流……主要通過開發(fā)框架 SDK – 如:Spring Cloud忘晤,或服務(wù)網(wǎng)格Service Mesh等技術(shù)宛蚓。
  • 監(jiān)控?cái)?shù)據(jù)收口。包括:日志设塔、指標(biāo)凄吏、調(diào)用鏈……主要通過一些標(biāo)準(zhǔn)主流的探針,再加上后臺(tái)的數(shù)據(jù)清洗和數(shù)據(jù)存儲(chǔ)來完成闰蛔,最好是使用無侵入式的技術(shù)痕钢。監(jiān)控的數(shù)據(jù)必須統(tǒng)一在一個(gè)地方進(jìn)行關(guān)聯(lián),這樣才會(huì)產(chǎn)生信息序六。
  • 資源調(diào)度有應(yīng)用部署的收口任连。包括:計(jì)算、網(wǎng)絡(luò)和存儲(chǔ)的收口例诀,主要是通過容器化的方案随抠,如k8s來完成。
  • 中間件的收口繁涂。包括:數(shù)據(jù)庫(kù)拱她,消息,緩存扔罪,服務(wù)發(fā)現(xiàn)秉沼,網(wǎng)關(guān)……等等。這類的收口方式一般要在企業(yè)內(nèi)部統(tǒng)一建立一個(gè)共享的云化的中間件資源池矿酵。

對(duì)此唬复,這里的原則是:

  • 你要選擇容易進(jìn)行業(yè)務(wù)邏輯和控制邏輯分離的技術(shù)。這里坏瘩,Java 的 JVM+字節(jié)碼注入+AOP 式的Spring 開發(fā)框架盅抚,會(huì)帶給你太多的優(yōu)勢(shì)。
  • 你要選擇可以享受“前人種樹倔矾,后人乘涼”的有技術(shù)紅利的技術(shù)妄均。如:有龐大社區(qū)而且相互兼容的技術(shù),如:Java, Docker, Ansible哪自,HTTP丰包,Telegraf/Collectd……
  • 中間件你要使用可以 支持HA集群和多租戶的技術(shù)。 這里基本上所有的主流中間件都會(huì)支持 HA 集群方式的壤巷。

原則八:不要遷就老舊系統(tǒng)的技術(shù)債務(wù)

我發(fā)現(xiàn)很多公司都很非常大的技術(shù)債務(wù)邑彪,這些債務(wù)具體表現(xiàn)如下:

  • 使用老舊的技術(shù)。 比如胧华,使用HTTP1.0寄症, Java 1.6宙彪,Websphere,ESB有巧,基于 socket的通訊協(xié)議释漆,過時(shí)的模型……等等
  • 不合理的設(shè)計(jì)。 比如篮迎,在 gateway 中寫大量的業(yè)務(wù)邏輯男图,單體架構(gòu),數(shù)據(jù)和業(yè)務(wù)邏輯深度耦合甜橱,錯(cuò)誤的系統(tǒng)架構(gòu)(把緩存當(dāng)數(shù)據(jù)庫(kù)逊笆,用消息隊(duì)列同步數(shù)據(jù))……等等
  • 缺少配套設(shè)施。比如岂傲,沒有自動(dòng)化測(cè)試难裆,沒有好的軟件文檔,沒有質(zhì)量好的代碼譬胎,沒有標(biāo)準(zhǔn)和規(guī)范……等等

來找我尋求技術(shù)幫助的人都有各種各樣的問題差牛。我都會(huì)對(duì)他們苦口婆心地說同樣的一句話——“如果你是來找我 case-by-case 解決問題,我興趣不大堰乔,因?yàn)槠銈兦f不要寄希望能夠很簡(jiǎn)單的把一輛夏利車改成一輛法拉利跑車,或是把一棟地基沒打好的歪樓搞正镐侯。以前欠下的技術(shù)債侦讨,都得要還,沒打好的地基要重新打苟翻,沒建配套設(shè)施都要建韵卤。這些基礎(chǔ)設(shè)施如果不按照正確科學(xué)的方式建立的話,你是不可能有一個(gè)好的的系統(tǒng)崇猫,我也沒辦法幫你 case-by-case 的解決問題……”沈条,一開始,他們都會(huì)對(duì)我說诅炉,沒問題蜡歹,我們就是要還債,但是涕烧,最后發(fā)現(xiàn)要還的債真多月而,有點(diǎn)承受不了,就開始現(xiàn)原形了议纯。

他們開始為自己的“欠的技術(shù)債”找各種合理化的理由——給你解釋各種各樣的歷史原因和不得以而為之的理由父款。談著談著,讓我有一種感覺——他們希望得到一種什么都不改什么都不付出的方式就可以進(jìn)步的心態(tài),他們寧可讓新的技術(shù) low 下來遷就于這些技術(shù)債憨攒,把新的技術(shù)濫用地亂七八糟的世杀。有一個(gè)公司,他們的系統(tǒng)架構(gòu)和技術(shù)選型基本都搞錯(cuò)了肝集,使用錯(cuò)誤的模型構(gòu)建系統(tǒng)玫坛,導(dǎo)致整個(gè)系統(tǒng)的性能非常之差,也才幾千萬條數(shù)據(jù)包晰,但他們想的不是還債,不是把地基和配套設(shè)施建好炕吸,而且要把樓修的更高伐憾,上更多的系統(tǒng)——他們覺得現(xiàn)有的系統(tǒng)挺好,性能問題的原因是他們沒一個(gè)大數(shù)據(jù)平臺(tái)赫模,所以要建大數(shù)據(jù)平臺(tái)……

我見過很多很多公司树肃,包括大如 BAT 這樣的公司,都會(huì)在原來的技術(shù)債上進(jìn)行更多的建設(shè)瀑罗,然后胸嘴,技術(shù)債越來越大,利息越來越大斩祭,最終成為一個(gè)高利貸劣像,再也還不了(我在《開發(fā)團(tuán)隊(duì)的效率》一文中講過一個(gè) WatchDog 的架構(gòu)模式,一個(gè)系統(tǒng)爛了摧玫,不是去改這個(gè)系統(tǒng)耳奕,而是在旁邊建一個(gè)系統(tǒng)來看著它,我很難理解為什么會(huì)有這樣的邏輯诬像,也許是為了要解決更多的就業(yè)……)

這里有幾個(gè)原則和方法我是非常堅(jiān)持的屋群,分享給大家:

  • 與其花大力氣遷就技術(shù)債務(wù),不如直接還技術(shù)債坏挠。是所謂的長(zhǎng)痛不如短痛芍躏。
  • 建設(shè)沒有技術(shù)債的“新城區(qū)”,并通過“防腐層 ”的架構(gòu)模型降狠,不要讓技術(shù)債侵入“新城區(qū)”对竣。

原則九:不要依賴自己的經(jīng)驗(yàn),要依賴于數(shù)據(jù)和學(xué)習(xí)

有好些人來找我跟我說他們的技術(shù)問題喊熟,然后希望我能夠給他們一個(gè)答案柏肪。我說,我需要了解一下你現(xiàn)有系統(tǒng)的情況芥牌,也就是需要先做個(gè)診斷烦味,我只有得到這些數(shù)據(jù)后,我才可能明白真正的原因是什么 ,我才可能給你做出一個(gè)比較好的技術(shù)方案谬俄。我個(gè)人覺得這是一種對(duì)對(duì)方負(fù)責(zé)的方法柏靶,因?yàn)榧夹g(shù)手段太多了,所有的技術(shù)手段都有適應(yīng)的場(chǎng)景溃论,并且有各種 trade-off屎蜓,所以,只有調(diào)研完后才能做出決定钥勋。這跟醫(yī)生看病是一樣的炬转,確診病因不能靠經(jīng)驗(yàn),還是要靠診斷數(shù)據(jù)算灸。在科學(xué)面前扼劈,所有的經(jīng)驗(yàn)都是靠不住的……

另外,如果有一天你在做技術(shù)決定的時(shí)候菲驴,開始憑自己以往的經(jīng)驗(yàn)荐吵,那么你就已經(jīng)不可能再成長(zhǎng)了。人都是不可能通過不斷重復(fù)過去而進(jìn)步的赊瞬,人的進(jìn)步從來都是通過學(xué)習(xí)自己不知道的東西先煎。所以,千萬不要依賴于自己的經(jīng)驗(yàn)做決定巧涧。做任何決定之前薯蝎,最好花上一點(diǎn)時(shí)間,上網(wǎng)查一下相關(guān)的資料谤绳,技術(shù)博客良风,文章,論文等 闷供,同時(shí)烟央,也看看各個(gè)公司,或是各個(gè)開源軟件他們是怎么做的歪脏?然后疑俭,比較多種方案的 Pros/Cons,最終形成自己的決定婿失,這樣钞艇,才可能做出一個(gè)更好的決定。

原則十:千萬要小心 X – Y 問題豪硅,要追問原始需求

對(duì)于 X-Y 問題哩照,也就是說,用戶為了解決 X問題懒浮,他覺得用 Y 可以解飘弧,于是問我 Y 怎么搞识藤,結(jié)果搞到最后,發(fā)現(xiàn)原來要解決的 X 問題次伶,這個(gè)時(shí)候最好的解決方案不是 Y痴昧,而是 Z。 這種 X-Y 問題真是相當(dāng)之多冠王,見的太多太多了赶撰。所以,每次用戶來找我的時(shí)候柱彻,我都要不斷地追問什么是 X 問題豪娜。

比如,好些用戶都會(huì)來問我他們要一個(gè)大數(shù)據(jù)流式處理哟楷,結(jié)果追問具體要解決什么樣的問題時(shí)侵歇,才發(fā)現(xiàn)他們的問題是因?yàn)榉?wù)中有大量的狀態(tài),需要把相同用戶的數(shù)據(jù)請(qǐng)求放在同一個(gè)服務(wù)上處理吓蘑,而且設(shè)計(jì)上導(dǎo)致一個(gè)慢函數(shù)拖慢整個(gè)應(yīng)用服務(wù)。最終就是做一下性能調(diào)優(yōu)就好了坟冲,根本沒有必要上什么大數(shù)據(jù)的流式處理磨镶。

我很喜歡追問為什么 ,這種追問健提,會(huì)讓客戶也跟著來一起重新思考琳猫。比如,有個(gè)客戶來找我評(píng)估的一個(gè)技術(shù)架構(gòu)的決定私痹,從理論上來說脐嫂,好像這個(gè)架構(gòu)在用戶的這個(gè)場(chǎng)景下非常不錯(cuò)。但是紊遵,這個(gè)場(chǎng)景和這個(gè)架構(gòu)是我職業(yè)生涯從來沒有見過的账千。于是,我開始追問這個(gè)為什么會(huì)是這么一個(gè)場(chǎng)景暗膜?當(dāng)我追問的時(shí)候匀奏,我發(fā)現(xiàn)用戶都感到這個(gè)場(chǎng)景的各種不合理。最后引起了大家非常深刻的研討学搜,最終用戶把那個(gè)場(chǎng)景修正后娃善,而架構(gòu)就突然就變成了一個(gè)常見且成熟的的模型……

原則十一:激進(jìn)勝于保守,創(chuàng)新與實(shí)用并不沖突

我對(duì)技術(shù)的態(tài)度是比較激進(jìn)的瑞佩,但是聚磺,所謂的激進(jìn)并不是瞎搞,也不是見新技術(shù)就上炬丸,而是積極擁抱會(huì)改變未來的新技術(shù)瘫寝,如:Docker/Go,我就非常快地跟進(jìn)矢沿,但是像區(qū)塊鏈或是 Rust 這樣的滥搭,我就不是很積極。因?yàn)榈肪ǎ洳]有命中我認(rèn)為的技術(shù)趨勢(shì)的幾個(gè)特征(參看《Go,Docker 和新技術(shù) 》)瑟匆。當(dāng)然,我也不是不喜歡的就不學(xué)了栽惶,我對(duì)區(qū)塊鏈和 Rust 我一樣學(xué)習(xí)愁溜,我也知道這些技術(shù)的優(yōu)勢(shì),但我不會(huì)大規(guī)模使用它們外厂。另外冕象,我也尊重保守的決定,這里面沒有對(duì)和錯(cuò)汁蝶。但是渐扮,我個(gè)人覺得對(duì)技術(shù)激進(jìn)的態(tài)度比起保守來說有太多的好處了。一方面來說掖棉,對(duì)于用戶來說墓律,很大程度上來說,新技術(shù)通常都表面有很好的競(jìng)爭(zhēng)力幔亥,而且我見太多這樣成功的公司都在積極擁抱新的技術(shù)的耻讽,而保守的通常來說都越來越不好。

有一些人會(huì)跟我說帕棉,我們是實(shí)用主義针肥,我們不需要?jiǎng)?chuàng)新,能解決當(dāng)下的問題就好香伴,所以慰枕,我們不需要新技術(shù),現(xiàn)有的技術(shù)用好就行了即纲。這類的公司捺僻,他們的技術(shù)設(shè)計(jì)第一天就在負(fù)債,雖然可以解決當(dāng)下問題崇裁,但是馬上就會(huì)出現(xiàn)新的問題匕坯,然后他們會(huì)疲于解決各種問題。最后呢拔稳,最后還是會(huì)走到新的技術(shù)上葛峻。

這里的邏輯很簡(jiǎn)單 —— 進(jìn)步永遠(yuǎn)來自于探索,探索是要付出代價(jià)的巴比,但是收益更大术奖。對(duì)我而言礁遵,不敢冒險(xiǎn)才是最大的冒險(xiǎn),不敢犯錯(cuò)才是最大的錯(cuò)誤采记,害怕失去會(huì)讓你失去的更多……

(全文完)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末佣耐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子唧龄,更是在濱河造成了極大的恐慌兼砖,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件既棺,死亡現(xiàn)場(chǎng)離奇詭異讽挟,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)丸冕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門耽梅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人胖烛,你說我怎么就攤上這事眼姐。” “怎么了佩番?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵众旗,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我答捕,道長(zhǎng),這世上最難降的妖魔是什么屑那? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任拱镐,我火速辦了婚禮,結(jié)果婚禮上持际,老公的妹妹穿的比我還像新娘沃琅。我一直安慰自己,他們只是感情好蜘欲,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布益眉。 她就那樣靜靜地躺著,像睡著了一般姥份。 火紅的嫁衣襯著肌膚如雪郭脂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天澈歉,我揣著相機(jī)與錄音展鸡,去河邊找鬼。 笑死埃难,一個(gè)胖子當(dāng)著我的面吹牛莹弊,可吹牛的內(nèi)容都是我干的涤久。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼忍弛,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼响迂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起细疚,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤蔗彤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后惠昔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體幕与,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年镇防,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了啦鸣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡来氧,死狀恐怖诫给,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情啦扬,我是刑警寧澤中狂,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站扑毡,受9級(jí)特大地震影響胃榕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瞄摊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一勋又、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧换帜,春花似錦楔壤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至祟牲,卻和暖如春隙畜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背说贝。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工禾蚕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人狂丝。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓换淆,卻偏偏與公主長(zhǎng)得像哗总,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子倍试,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容