歡迎光臨
每天分享高質量文章

從技術演變的角度看互聯網後臺架構

 

本文是騰訊IEG內部做的一個面向後臺開發新同學的課程。
其實內容都是些常見開源組件的high level描述,比如Flask,Express框架,中間件的演化,Microservices的概念,一些對NoSQL/Column based DB的概念介紹,Docker的一些簡單概念等等。從單個概念來說,這隻是一些科普。
但是為什麼當時要開這門課呢?重點是我發現很多新入職的後臺開發同學並不太清楚自己做的東西在現代互聯網整體架構中處於一個什麼樣的角色,而在IEG內部則因為游戲開發和互聯網開發的一些歷史性差異,有些概念並不清晰。
拿中間件來說,很多Web application不用啥中間件一樣可以跑很好,那麼是不是都要上Redis?到底解決什麼問題?中間件又存在什麼問題?中台和中間件又是個什麼關係?如果開個MQ就是中間件,微服務又是要做啥?
如果能從這十多年來互聯網應用的整個Tech stack變化去看待backend architecture的一些改變,應該是一件有趣也有意思的事情。這是當時寫這個PPT開課的初衷。
我不敢說我在這個PPT裡面的一些私貨概念就是對的,但是也算是個人這麼多年的一些認知理解,拋磚引玉吧。
強調一點,這個PPT的初衷是希望從近十多年來不同時代不同熱點下技術棧的變化來看看我們是如何從最早的PHP/ASP/JSP<=>MySQL這樣的兩層架構,一個階段一個階段演變到現在繁複的大資料、機器學習、訊息驅動、微服務架構這樣的體系,然後在針對其中比較重要的幾個方面來給新入門後臺開發的同學起個“提綱目錄”的作用。如果要對每個方面都深入去談,那肯定不是一兩頁PPT就能做到的事情。
下麵我們開始。首先看第一頁如下圖:什麼是System Design?什麼是架構設計?為什麼要談架構設計?

之所以丟擲這個問題,是因為平時常常聽到兩個互相矛盾的說法:一方面很多人愛說“架構師都是不幹活誇誇其談”,另一方面又有很多人苦惱限於日常業務需求開發,無法或者沒有機會去從整體架構思考,不知道怎麼成長為架構師。
上面PPT中很有趣的是第一句英文,翻譯過來恰好可以反映了論壇上經常有人問的“如何學習架構”的問題:很多leader一來就是扔幾本書(書名)給新同學,期望他們讀完書就馬上升級……這種一般都只會帶來失望。
何為架構師?不寫代碼只畫PPT?
不是的,架構師的基本職責是要在專案早期就能設計好基本的框架,這個框架能夠確保團隊成員順利coding滿足近期內業務需求的變化,又能為進一步的發展留出空間(所謂scalability),這即是所謂技術選型。如何確保選型正確?對於簡單的應用,或者沒有新意完全是實踐過多次的相同方案,確實靠幾頁PPT足矣。但是對於新的領域新的複雜需求,這個需求未必都是業務需求,也包括根據團隊自身特點(人員太多、太少、某些環節成員不熟悉需要剝離開)來進行新的設計,對現有技術重新分解組合,這時候就需要架構師自己編碼實現原型並驗證思路正確性。
要達到這樣的標的難不難?難!但是現在不是2000年了,是2019年了,大量的框架(framework)、開源工具和各種best practice,其實都是在幫我們解決這件事情。而這些框架並不是憑空而來,而是在這十多年互聯網的演化中因為要解決各種具體業務難點而一點一點積累進化而來。無論是從MySQL到MongoDB到Cassandra到Time Series DB,或者從Memcached到Redis,從Lucene到Solr到Elasticsearch,從離線批處理到Hadoop到Storm到Spark到Flink,技術不是突然出現的,總是站在前人的肩膀上不斷演變的。而要能在浩如煙海的現代互聯網技術棧中選擇合適的來組裝自己的方案,則需要對技術的來源和歷史有一定的瞭解。否則就會出現一些新人張口ELK,閉口TensorFlow,然後一個簡單的異步訊息處理就會讓他們張口結舌的現象。
20多年前的經典著作DesignPatterns中講過學習設計樣式的意義,放在這裡非常經典:學習設計樣式並不是要你學習一種新的技術或者編程語言,而是建立一種交流的共同語言和詞彙,在方案設計時方便溝通,同時也幫助人們從更抽象的層次去分析問題本質,而不被一些實現的細枝末節所困擾。同時,當我們能把很多問題抽象出來之後,也能幫我們更深入更好地去瞭解現有系統——-這些意義,對於今天的後端系統設計來說,也仍然是正確的。
下圖是我們要談的幾個主要方面。

上面的幾個主題中,第一個後臺架構的演化是自己從業十多年來,體會到的互聯網技術架構的整體變遷。然後分成後臺前端應用框架、Middleware和儲存三大塊談一下,最後兩節微服務和Docker則是給剛進入後臺開發的同學做一些概念普及。其中個人覺得最有趣的,是第一部分後臺架構的演化和第三部分的中間件,因為這兩者是很好地反映了過去十多年互聯網發展期間技術棧的變化,從LAMP到MEAN Stack,從各種繁複的中間層到漸漸統一的訊息驅動+流處理,每個階段的業界熱點都相當有代表性。
當然,不是說Web框架、資料儲存就不是熱點了,姑且不說這幾年Web前端的複雜化,光後端應用框架,Node的Express,Python的Django/Flask,Go在國內的盛行,都是相當有趣的。在資料儲存領域,列儲存和時序資料隨著物聯網的發展也是備受重視。但是篇幅所限,在這個課程中這些話題也就只能一帶而過,因為這些與其說是技術的演變過程,不如說是不同的技術選型和方向了,比如說MySQL適合OLTP(Online Transaction Processing),而Cassandra/HBase等則適合OLAP(Online Analyical Processing),並不能說後者就優於前者。
下麵我們先來看後臺架構的演化。

嚴格說這是個很大的標題,從2000年到現在的故事太多了,我這裡只能儘力而為從個人體驗來分析。
首先是2008年以前,我把它稱為網站時代。為什麼這麼說?因為那時候的後臺開發就是寫網站,而且通常是頁面代碼和後臺資料邏輯一起寫。你只要能寫JSP/PHP/ASP來讀寫MySQL或者SQL Server,基本就能保證一份不錯的工作了。

要強調一下,這種簡單的兩層結構並不能說就是落後。在現在各個企業、公司以及小團隊的大量Web應用包括移動App的後端服務中,採用這種架構的不在少數,尤其是很多公司、學校、企業的內部服務,用這種架構已經足夠了。
註意一個時間節點:2008。
當然,這個節點是我YY的。這個節點可以是2007,或者2006。這個時間段發生了兩個影響到現在的事情:Google上市,Facebook開始推開。
我個人相信前者上市加上它發表的那三篇大資料paper影響了後來業界的技術方向,後者的火熱則造成了社交成為業務熱點。偏偏社交網站對大資料處理有著天然的需求,技術的積累和業務的需求就這麼陰差陽錯完美結合了起來,直接影響了大海那邊後面的科技發展。
同時在中國,那個時候卻是網絡游戲MMO的黃金年代,對單機單服高併發實時交互的需求,遠遠壓過了對海量資料Data mining的需要,在這個時間點,中美兩邊的互聯網科技樹發生了比較大的分叉。這倒是並沒有優劣之說,只是業務場景的重要性導致了技能樹的側重。直到今天,單機(包括簡單的多服務器方案)高併發、高QPS仍然也是國內業界所追求的標的,而在美國那邊,這隻是一個業務指標而已,更看重的是如何進行水平擴展(horizontal scaling)和分散壓力。
國內和美國的科技樹回到一條線上,大資料的業務需求和相關技術發展緊密結合起來,可能要到2014年左右,隨著互聯網創業的盛行,O2O業務對大資料實時處理、機器學習推薦提出了真正的需求時,才是國內業界首次出現技術驅動業務,演算法驅動產品的現象,重新和美國灣區那邊站在了一條線上,而這則是後話了。
到了2010年前後,Facebook在全球已經是現象級產品,當時微軟直接放棄了Windows Live,就是為了避免在社交領域硬懟Facebook。八卦一下當時在美國灣區那邊聚餐的時候,如果誰說他是Facebook的,那基本就是全場羡慕的焦點。
Facebook的崛起也帶動了其他大量的社交網站開始出現,社交網站最大的特點就是頻繁的用戶搜索、推薦,當用戶上億的時候,這就是前面傳統的兩層架構無法處理的問題了。因此這就帶動了中間件的發展。實際上在國外很少有人用中間件或者Middelware這個詞,更多是探討如何把各種Service集成在一起,像國內這樣強行分成Frontend/Middleware/Storage的概念是沒聽人這麼談過的,後面中間件再說這問題。當時的一個慣例是用PHP做所謂的膠水語言(glue language),然後通過Hessian這些協議工具來把其他Java服務連接到一起。與此同時,為了提高訪問速度,降低後端查詢壓力,Memcached/Redis也開始大量使用。基於Lucene的搜索(2010左右很多是自行開發)或者Solr也被用在用戶搜索、推薦以及Typeahead這些場景中。
我記憶中在2012年之前訊息佇列的使用還不是太頻繁,不像後來這麼重要。當時常見的應該就是Beanstalkd/RabbitMQ,ZeroMQ其實我在灣區那邊很少聽人用,倒是後來回國後看到國內用的人還不少。Kafka在2011年已經出現了,有少部分公司開始用,不過還不是主流。

2013年之後就是大資料+雲的時代了,如果大家回想一下,基本上國內也是差不多在2014年左右開始叫出了雲+大資料的口號(2013年國內還在手游狂潮中……)。不談國外,在中國那段時間就是互聯網創業的時代,從千團大戰到手游爆發到15年開始的O2O,業務的發展也帶動了技術棧的飛速進步。左上角大致上也寫了這個時代互聯網業界的主要技術熱點,實際上這也就是現在的熱點。無論國內國外,絕大部分公司還並沒有離開雲+大資料這個時代。無論是大資料的實時處理、資料挖掘、推薦系統、Docker化,包括A/B測試,這些都是很多企業還正在努力全面解決的問題。
但是在少數站在業界技術頂端或者沒有歷史技術包袱的新興公司,從某個角度上來說,他們已經開始在往下一個時代前進:機器學習AI驅動的時代。

2018年開始,實際上可能是2017年中開始,AI驅動成了各大公司口號。上圖是Facebook和Uber的機器學習平臺使用情況,基本上已經全部進入業務核心。當然並不是說所有公司企業都要AI驅動,顯然最近發生的波音737事件就說明該用傳統的就該傳統,別啥都往並不成熟的AI上堆。但另一方面,很多新興公司的業務本身就是基於大資料或者演算法的,因此他們在這個領域也往往走得比較激進。由於這個AI驅動還並沒有一個很明確的定義和概念,還處於一種早期萌芽的階段,在這裡也就不多YY了。
互聯網後臺架構發展的簡單過程就在這裡講得差不多了,然後我們快速談一下Web開發框架。

首先在前面我提到,在後端架構中其實也有所謂的Frontend(前臺)開發存在,一般來說這是指響應用戶請求,實現具體業務邏輯的業務邏輯層。當然這麼定義略微粗糙了些,很多中間儲存、訊息服務也會封裝一些業務相關邏輯。總之Web開發框架往往就是為了更方便地實現這些業務邏輯而存在的。
前文提到在一段較長時間內,國內的技術熱點是單機高併發高QPS,因此很多那個時代走過來的人會本能地質疑Web框架的性能,而更偏好TCP長鏈接甚至UDP協議。然而這往往是自尋煩惱,因為除開特別的強實時系統,無論是休閑手游、視頻點播還是信息流,都已經是基於HTTP的了。

上圖所提到的兩個問題中,我想強調的是第一點:所有的業務,在能滿足需求的情況下,首選HTTP協議進行資料交互。準確點說,首選JSON,使用Web API。
Why?這就是上圖第一個問題所回答的:無狀態、易除錯易修改、一般沒有80端口限制。
最為詬病的無非是性能,然而實際上對非實時應用,晚個半秒一秒不應該是大問題,要考慮的是水平擴展scalability,不是實時響應(因為前提就是非實時應用);其次實在不行你還有WebSocket可以用。

這一部分是簡單列舉了一下不同框架的使用,可以看出不同框架的概念其實差不多。重點是要註意到Middleware這個說法在Web Framework和後端架構中的意義不同。在Web Framework中是指具體處理GET/POST這些請求之前的一個通用處理(往往是鏈式呼叫),比如可以把鑒權、一些日誌處理和請求記錄放在這裡。但在後端架構設計中的Middleware則是指類似訊息佇列、快取這些在最終資料庫之前的中間服務組件。

最後這裡是想說Web Framework並不是包治百病,實際上那隻是提供了基礎功能的一個library,作為開發者則更多需要考慮如何定義配置檔案,一些敏感引數如token、密碼怎麼傳進來,開發環境和生產環境的配置如何自動切換,單元測試怎麼搞,代碼目錄怎麼組織。有時候我們可以用一些比如Yeoman之類的Scaffold工具來自動生成專案代碼框架,或者類似Django這種也可能自動生成基本目錄結構。
下麵進入Middleware環節。Again,強調一下這裡只是根據個人經驗和感受談談演化過程。

這一頁只是大致講一下怎麼定義中間件Middleware。說句題外話,在美國灣區那邊提這個概念的很少,而阿裡又特別喜歡說中間件,兩者相互的交流非常頭痛。灣區那邊不少Google、Facebook還有Pinterest/Uber這些的朋友好幾次都在群里問說啥叫中間件。
中間件這個概念很含糊,應該是阿裡提出來的,對應於Middleware(不過似乎也不是完全對應),可能是因為早期Java的EJB那些概念裡面比較強調Middleware這一點吧(個人猜的)。大致上,如果我們把Web後端分為直接處理用戶請求的Frontend,最後對資料進行持久儲存(persistant storage)這兩塊,那麼中間對資料的所有處理環節都可以視為Middleware。

和中間件對應的另一個阿裡發明的概念是中台。近一年多阿裡的中台概念都相當引人註意,這裡對中台不做太多描述。總體來說中台更多是偏向業務和組織架構劃分,不能說是一個技術概念,也不是面向開發人員的。而中間件Middleware是標準的技術組件服務。
那麼我們自然會有一個問題:為什麼要用中間件?

談到為什麼要用Middlware,這裡用推薦系統舉例。
推薦系統,對資料少用戶少的情況下,簡單的MySQL即可,比如早期論壇的什麼top 10熱門話題啊,最多回覆的話題啊,都可以視為簡單的推薦,資料量又不大的情況下,直接select就可以了。
如果是用戶推薦的話,用戶量不大的情況下,也可以如法炮製,選擇同一區域(城市)年齡相當的異性,最後隨機挑幾個給你,相信世紀佳緣之類的交友網站早期實現也就是類似的樣式。

那麼,如果用戶量多了呢?每次都去搜資料庫,同時在線用戶又多,那對資料庫的壓力就巨大了。這時候就是引入快取,Memcached、Redis就出現了。
簡單的做法就是把搜索條件作為key,把結果作為value存入快取。打個比方你可以把key存為 20:40:beijing:male(20到40歲之間北京的男性),然後把第一次搜索的結果全部打亂shuffle後,存前1000個,10分鐘過期,再有人用類似條件搜索,就直接把快取資料隨機挑幾個傳回。放心,一般來說不會有人10分鐘就把1000個用戶的資料都看完了,中間偶有重覆也沒人在意(用世紀佳緣、百合網啥的時候看到過重覆的吧)。
不過話又說回來,現代資料庫,尤其是類似MongoDB/ES這些大量占用記憶體的NoSQL,已經對經常查詢的資料做了快取,在這之上再加cache,未必真的很有效,這需要case by case去分析了,總之盲目加cache也並不推薦。
加快取是為瞭解決訪問速度,減輕資料庫壓力,但是並不提高推薦精準度。如果我們要提高推薦效果呢?在2015年之前機器學習還沒那麼普及成熟的時候,我們怎麼搞呢?

提高推薦效果,在機器學習之前有兩種做法:
  • 引入基於Lucene的搜索引擎,在搜索的同時通過定製方案實現scoring,比如我可以利用Lucene對用戶的年齡、性別、地址等進行indexing,但是再傳回結果時我再根據用戶和查詢者兩人的具體信息進行關聯,自定義傳回的score(可以視為推薦相關係數)

  • 採用離線批處理。固然可以用Hadoop,但是就太殺雞用牛刀了。常見的是定時批處理任務,按某種規則劃分用戶群體,對每個群體再做全量計算後把推薦結果寫入快取。這種可以做很繁複準確的計算,雖然慢,但效果往往不錯。這種做法也常用在手機游戲的PvP對戰串列裡面。

這些處理方法對社交網絡/手游這型別的其實已經足夠了,但是新的業務是不斷出現的。隨著Uber/滴滴/餓了麽/美團這些需要實時處理資料的App崛起,作為一個司機,並不想你上線後過幾分鐘才有客人來吧,你希望你開到一個熱點區域,一開機就馬上接單。

所以這種對資料進行實時(近實時)處理的需求也帶動了後端體系的大發展,Kafka/Spark等等流處理大行其道。這時候的後端體系就漸漸引入了訊息驅動的樣式,所謂訊息驅動,就是對新的生產資料會有多個消費者,有的是滿足實時計算的需求(比如司機信息需要立刻能夠被快速檢索到,又不能每次都做全量indexing,就需要用到Spark),有的只是為了資料分析,寫入類似Cassandra這些資料庫里,還有的可能是為了生成定時報表,寫入到MySQL。
大資料的處理一直是業界熱點領域。記得2015年硅谷一個朋友就是從一家小公司做PHP跳去另一家物聯網公司做Spark相關的工作,之前還很擔心玩不轉,搞了兩年就儼然業界大佬被Oracle挖去負責雲平臺。
Anyway,這時候對後端體系的要求是一方面能快速滿足實時需求,另一方面又能滿足各種耗時長的資料分析、Data lake儲存等等,以及當時漸漸普及的機器學習模型(當時2015年初和幾個朋友搞Startup,其中一個是Walmart Lab的機器學習專家,上來就一堆模型,啥資料和用戶都還沒有就把模型擺上來了,後來搞得非常頭痛。當時沒有Keras/PyTorch/tf這些,那堆模型是真心搞不太懂,但是又不敢扔,要靠那東西去包裝拿投資的。)
但是我們再看上面的圖,是不是感覺比較亂呢?各種系統的資料寫來寫去,是不是有點messy?當公司團隊增多,系統複雜度越來越高的時候,我們該怎麼梳理?

到了2017之後,前面千奇百怪的後端體系基本上都趨同了。Kafka的實時訊息佇列,Spark的流處理(當然現在也可以換成Flink,不過大部分應該還是Spark),然後後端的儲存,基於Hive的資料分析查詢,然後根據業務的模型訓練平臺。各個公司反正都差不多這一套,在具體細節上根據業務有所差異,或者有些實力強大的公司會把中間一些環節替換成自己的實現,不過不管怎麼千變萬化,整體思路基本都一致了。
這裡可以看到機器學習和AI模型的引入。個人認為,Machine Learning的很大一個好處,是簡化業務邏輯,簡化後臺流程,不然一套業務一套實現,各種資料和業務規則很難用一個整體的技術平臺來完成。相比前面一頁的後臺架構,這一頁要清晰許多,而且是一個DAG有向無環圖的形式,資料流向很明確。我們在下麵再來說這個機器學習對業務資料流程的簡化。

在傳統後端系統中,業務邏輯其實和資料是客觀分離的,邏輯規則和資料之間並不存在客觀聯繫,而是人為主觀加入,並沒形成閉環,如上圖左上所示。而基於機器學習的平臺,這個閉環就形成了,從業務資料->AI模型->業務邏輯->影響用戶行為->新的業務資料這個流程是自給自足的。這在很多推薦系統中表現得很明顯,通過用戶行為資料訓練模型,模型對頁面信息流進行調整,從而影響用戶行為,然後用新的用戶行為資料再次調整模型。而在機器學習之前,這些觀察工作是交給運營人員去手工猜測調整。
上圖右邊談的是機器學習相關後臺架構和傳統Web後臺的一些差別,重點是耗時太長,必須異步處理。因此訊息驅動機制對機器學習後臺是一個必須的設計。

這頁是一些個人的感受,現代的後端資料處理越來越偏向於DAG的形態,Spark不說了,DAG是最大特色;神經網絡本身也可以看作是一個DAG(RNN其實也可以看作無數個單向DNN的組合);TensorFlow也是強調其Graph是DAG,另外編程樣式上,Reactive編程也很受追捧。
其實DAG的形態重點強調的就是資料本身是immutable(不可修改),只能transform後成為新的資料進入下一環。這個思維其實可以貫穿到現代後臺系統設計的每個環節,比如Trakcing、Analytics、資料表設計、Microservice等等,但具體實施還是要case by case了。
無論如何,資料,資料的跟蹤Tracking,資料的流向,是現代後臺系統的核心問題,只有Dataflow和Data Pipeline清晰了,整個後臺架構才會清楚。
資料庫是個非常複雜的領域,在下麵對幾個基本常用的概念做一些介紹。註意一點是Graph database在這裡沒有提到,因為日常使用較少,相對來說Facebook提出的GraphQL倒是個有趣的概念,但也只是在傳統DB上的一個概念封裝。

上圖是2018年12月初熱門資料庫的排名,我們可以看到關係資料庫RDBMS和NOSQL資料庫基本上平分秋色。而NoSQL中實際上又可以分為key-value storage(包括文件型)及Column based DB。

MySQL這個沒啥好講,大概提一下就是。有趣的是曾經看到一篇文章是AWS CTO談的一些內容,其中印象深刻是:如果你的用戶還不到100萬,就別折騰了,無腦使用MySQL吧。
在2015年之前的一個趨勢是不少公司使用MySQL作為資料儲存,但是把indexing放在外部去做。這個思路最早似乎是Friendster提出的,後來Uber也模仿這種做法設計了自己的資料庫Schemaless。然而隨著PostgreSQL的普及(PostgreSQL支持對json的索引),這種做法是否還有意義就值得商榷了。

NoSQL最早的使用就是key-value的查找,典型的就是Redis。實際上後來的像MongoDB這些Documentbased DB也是類似的key value,只是它對Document中的內容又做了一次index(b-tree),用空間換時間來提供查找資料,這也是CS不變的思維。
MongoDB/Elasticsearch收到熱捧主要是因為它們的Schemaless屬性,也就是不需要提前定義資料格式,只要是json就存,還都能根據每個field搜索,這非常方便程式員快速出demo。但是實際上資料量大之後還是要規範資料結構,定義需要indexing的field的。

這裡提一個比較好玩的開源Project NodeBB,這是個Node.js開發的論壇系統。在我前幾年看到這個的時候它其實只支持Redis,然後當時因為一個專案把它改造了讓他支持MySQL。去年再看的時候發現它同時支持了Redis/Postres/MongoDB,如果對比一下同樣的功能他如何在這三種DB實現的,相信會很有幫助。
稍微談談列儲存。常見MySQL你在select的時候其實往往會把整行都讀出來,再在其中挑那麼一兩個你需要的屬性,非常浪費。而MongoDB這些檔案型DB,又不支持常見SQL。而列儲存DB的好處就是快,不用把一行所有信息讀出來,只是按列讀取你需要的,對現在的大資料分析特別是OLAP(Online Analytical Processing)來說特別重要。然而據另外的說法,實際上像Casssandra/HBase這些並不是真正的列儲存,而只是借用了一些概念。這個我也沒深入去瞭解,有興趣的同學可以自己研究研究。

列儲存的一個重要領域是時序資料庫,物聯網用得多。其特色是大量寫入,只增不改(不修改資料),但是讀的次數相對於很少(想想物聯網的特點,隨時有資料寫入,但是你不會隨時都在看你家小米電器的狀態。)
註意說Write/Read是正交的。這意思是每次寫入是一次一行,而讀是按列,加上又不會修改資料,因此各自都能保持極快的速度。
下麵簡單談一下微服務,大部分直接看PPT就可以了,有幾頁略微談一下個人思考。

上面這頁說說,其實微服務所謂的服務發現/name service不要被忽悠覺得是多神奇的東西。最簡單的Nginx/Apache這些都能做(域名轉向,Proxy),或者你要寫個name : address的對應關係到DB裡面也完全可以,再配一個定時HealthCheck的服務,最簡單的服務發現也就行了。
高級點用到ZooKeeper/etcd等等,或者Spring Cloud全家桶,那隻是簡化配置,原理都一樣。從開發角度來看,微服務的開發並不是難點,難點是微服務的配置和部署。最近一段時間微服務部署也是業界熱點,除了全家桶形態的Spring Cloud,也可以看看Istio這些開源工具。

上圖主要大致對比一下,看看從早期的Spring到現在Spring Cloud的變化。想來用過Java Tomcat的朋友都能體會Java這一套Config based development的繁瑣,開發的精力很多不是在業務代碼上,往往會化不少精力去折騰配置檔案。當然,Spring Cloud在這方面簡化了不少,不過個人還是不太喜歡Java,搞很多複雜的設計樣式,封裝了又封裝。

這裡要說並不是微服務解決一切,熱門的Python Django儘管有REST Framework,但是它實際上是一個典型的Monolithic體系。對很多核心業務,其實未必要拆開成微服務。
這兩者是互補關係,不是替代關係。
下麵的Docker我就不仔細談了,PPT基本表達了我想表述的概念,主要意思是:
  • Docker能夠簡化部署,簡化開發,能夠在某種程度上讓開發環境和產品環境儘量接近。

  • 不要擔心Docker的性能,它不是虛擬機,可以看作在Server上運行的一個Process。

上圖是描述Docker之前開發人員的常見開發環境,首先在自己機器上裝一大堆服務,像MySQL,Redis,Tomcat啥的。也有直接在遠程服務器安裝環境後,多人共同登錄遠端開發,各自使用一個端口避免衝突……實際上這種土法煉鋼的形態,在2019年的今天仍然在國內非常普及。
這種形態的後果就是在最後發佈到生產環境時,不同開發人員會經歷長時間的“聯調”,各種端口、權限、腳本、環境設置在生產環境再來一遍…這也是過去運維人員的主要工作。

上一頁提到的問題,並不是一定要Docker來解決。在這之前,虛擬機VM的出現,以及Vagrant這樣的工具,都讓開發環境的搭建多少輕鬆了一些。不過思路仍然是把VM作為一個獨立服務器使用,只是因為快照、鏡像和輔助工具,讓環境的配置、統一和遷移更加簡單快捷。

上圖是對比程式運行在物理服務器、VM及Docker時的資源共享情況,可以看到運行在Docker的應用,並沒有比併發運行在物理服務器上占用更多資源。
下圖是簡單的Docker使用,不做贅述。
這一頁主要是強調Docker並不等同於虛擬機。虛擬機所占資源是獨享的,比如你啟動一個VM,分配2G記憶體,那麼這個VM里不管是否運行程式都會占用2G記憶體。然而如果你啟動一個Docker,裡面運行一個簡單Web服務,在不強制指定記憶體占用情況下,如果沒有請求進入,沒有額外占用記憶體,那麼這個Docker服務對整機的記憶體占用幾乎為0(當然仍然存在一些開銷,但主要是根據該程式自身的運行狀況而定)。
最後是Kubernetes,這裡大概說說Host-Pod-Container的關係,一個Host可以是物理機或者VM,Pod不是一個Docker,而是可以看作有一個IP的……(不知道怎麼形容),總之一個Pod可以包括多個Container(Docker),Pod之中的Container可以共享該Pod的資源(IP,storage等)。不過現實中似乎大多是一個Pod對一個Container。
對互聯網一些熱門概念和演變過程的一個很簡略的描述就到這裡。

赞(0)

分享創造快樂