|
這篇文章是參考李智慧的《大型網(wǎng)站技術(shù)架構(gòu):核心原理與案例分析》和現(xiàn)蘑菇街CTO曽憲杰的《大型網(wǎng)站系統(tǒng)與Java中間件實(shí)踐》寫(xiě)的一篇讀書(shū)筆記。 前言 何謂大型網(wǎng)站?大型網(wǎng)站的特點(diǎn)是什么?大型網(wǎng)站架構(gòu)發(fā)生演變的源動(dòng)力是什么?大型網(wǎng)站的架構(gòu)演變經(jīng)歷了哪些階段?在演變的某個(gè)具體階段使用到常用技術(shù)有哪些,為什么要使用這些技術(shù),同時(shí)這些技術(shù)又解決了什么問(wèn)題?筆者在初次接觸大型網(wǎng)站時(shí)思考了以上幾個(gè)問(wèn)題,本著緣木求魚(yú)的方式,我打算詳細(xì)的扒一扒大型網(wǎng)站的演變史。如果對(duì)以上的幾個(gè)問(wèn)題都理解透徹了,那么可以說(shuō)對(duì)大型網(wǎng)站也有一個(gè)基本的認(rèn)識(shí)和理解了,但是我寫(xiě)這篇文章卻不局限于此,在文章的后面會(huì)從一個(gè)中高級(jí)程序員的角度去思考,從大型網(wǎng)站的演變史可以得到哪些方法論和技術(shù)棧。由于筆者工作時(shí)間不長(zhǎng),所以我覺(jué)得思考這個(gè)問(wèn)題是很有意思的。 下面將分別從以下幾個(gè)方面談?wù)劥笮途W(wǎng)站:
大型網(wǎng)站的特點(diǎn) 從20世紀(jì)90年代第一個(gè)Web服務(wù)的出現(xiàn),現(xiàn)在互聯(lián)網(wǎng)的普及,也就短短20來(lái)年的時(shí)間?;ヂ?lián)網(wǎng)極大的改變了人們的生活、學(xué)習(xí)、生活等方方面面,筆者清晰地記得在2011年剛上大學(xué)那會(huì),用著中國(guó)移動(dòng)龜速的2G怨聲載道,到現(xiàn)在三大運(yùn)營(yíng)商大力推廣并普及4G網(wǎng)絡(luò),再一次掀起了新一輪的互聯(lián)網(wǎng)革命,當(dāng)我們享受著網(wǎng)頁(yè)秒開(kāi),看視頻再也不卡的暢快時(shí),卻不知道背后的技術(shù)人員所付出的巨大努力。舉個(gè)例子,現(xiàn)在大家人手必裝的支付寶、淘寶等軟件無(wú)不從一個(gè)小網(wǎng)站發(fā)展起來(lái)的,然后逐漸成為一個(gè)大型網(wǎng)站。那么大型網(wǎng)站的特點(diǎn)有哪些呢?
主要是指這類(lèi)網(wǎng)站需要面對(duì)高并發(fā)、大流量訪問(wèn)。騰訊QQ的最大在線人數(shù)為1.4億(2011年數(shù)據(jù))。
因?yàn)楦卟l(fā)的訪問(wèn),會(huì)使得服務(wù)器承受巨大的壓力,一旦服務(wù)器出現(xiàn)過(guò)載那么很可能直接掛掉,然后,就沒(méi)有然后了??。因此,高可用就顯得尤為重要,需要保證網(wǎng)站7*24小時(shí)不間斷提供服務(wù)。
主要是指需要存儲(chǔ)、管理海量數(shù)據(jù)。百度收錄的網(wǎng)頁(yè)數(shù)據(jù)有數(shù)百億,Google有將近百萬(wàn)臺(tái)服務(wù)器在提供服務(wù)。 源動(dòng)力 既然大型網(wǎng)站是從小型網(wǎng)站發(fā)展起來(lái)的,那么是什么力量在推動(dòng)著小網(wǎng)站逐漸向大型網(wǎng)站發(fā)展呢? 主要力量是業(yè)務(wù)的發(fā)展。從來(lái)沒(méi)有哪個(gè)網(wǎng)站生來(lái)就是大型網(wǎng)站,業(yè)務(wù)驅(qū)動(dòng)技術(shù)變革,技術(shù)變革反作用于業(yè)務(wù),從而使得網(wǎng)站可以支撐業(yè)務(wù)的快速發(fā)展。所以,從CEO(CTO)的角度看,網(wǎng)站的價(jià)值在于它所為用戶帶來(lái)了什么,而不是網(wǎng)站是怎么形成的。需要為用戶帶來(lái)價(jià)值是因,網(wǎng)站的形成是果,這個(gè)因果關(guān)系是需要認(rèn)清楚的。所以,技術(shù)從來(lái)不是單純的技術(shù)(從價(jià)值的角度看),技術(shù)雖然可以解決大部分問(wèn)題,但卻不一定能夠解決所有的問(wèn)題。就12306網(wǎng)站售票的例子,如果早點(diǎn)使用分時(shí)段售票的做法,就沒(méi)必要投入大量的技術(shù)人員解決這個(gè)問(wèn)題。業(yè)務(wù)設(shè)計(jì)也是關(guān)乎網(wǎng)站價(jià)值的重要方面,所以不要為了技術(shù)而技術(shù)! 演變階段
階段一:?jiǎn)闻_(tái)服務(wù)器搞定一切 由于早期用戶量不多,所以使用一臺(tái)服務(wù)器就可以支撐業(yè)務(wù)。應(yīng)用、數(shù)據(jù)、文件都在一臺(tái)機(jī)器上完成。這個(gè)階段的典型架構(gòu)就是LAMP(Linux + Apache + MySQL + PHP(Java))。搞過(guò)開(kāi)發(fā)的應(yīng)該都經(jīng)歷過(guò)這個(gè)階段。操作系統(tǒng)采用Linux,使用Java或者PHP作為開(kāi)發(fā)語(yǔ)言,使用MySQL作為數(shù)據(jù)庫(kù),開(kāi)發(fā)完后部署在Apache上。淘寶早期的架構(gòu)也是這樣的。
階段二:應(yīng)用服務(wù)與數(shù)據(jù)隔離 隨著業(yè)務(wù)量的增長(zhǎng),存儲(chǔ)的數(shù)據(jù)越來(lái)越多而造成存儲(chǔ)空間的不足。這時(shí)候就把應(yīng)用和數(shù)據(jù)拆分,分別部署在應(yīng)用服務(wù)器、數(shù)據(jù)庫(kù)服務(wù)器和文件服務(wù)器。應(yīng)用服務(wù)器由于需要處理復(fù)雜的業(yè)務(wù)邏輯,因此需要更強(qiáng)大的CPU,數(shù)據(jù)庫(kù)由于需要快速讀寫(xiě)數(shù)據(jù),因此需要更快的磁盤(pán)和更大的內(nèi)存,文件服務(wù)器由于需要存儲(chǔ)大量的數(shù)據(jù),因此需要更大容量的硬盤(pán)。需要注意的是,雖然三臺(tái)服務(wù)器承擔(dān)了不同的角色,同時(shí)也大大改善了網(wǎng)站的性能,但是在整個(gè)應(yīng)用中,需要的服務(wù)都是通過(guò)直連的方式完成的。直連的意思是指,當(dāng)需要讀寫(xiě)數(shù)據(jù)庫(kù)的數(shù)據(jù)時(shí),是直接訪問(wèn)的。雖然有壓測(cè)數(shù)據(jù)表明,在不使用任何第三方組件直接使用MySQL的并發(fā)可以達(dá)到10000多。所以,如果并發(fā)數(shù)小于這個(gè)值,直連的方式也沒(méi)有什么問(wèn)題。所以,如果并發(fā)數(shù)超過(guò)了10k,那么數(shù)據(jù)庫(kù)的壓力就比較大了,造成的問(wèn)題就是訪問(wèn)時(shí)延增大,進(jìn)而影響整個(gè)網(wǎng)站的性能。 階段三:使用緩存改善性能 根據(jù)“二八定律”:80%的業(yè)務(wù)訪問(wèn)集中在20%的數(shù)據(jù)上,也就是說(shuō)這20%的數(shù)據(jù)是熱點(diǎn)數(shù)據(jù),訪問(wèn)頻率相比其他數(shù)據(jù)大數(shù)倍甚至更多。所以,如果把這小部分的數(shù)據(jù)緩存在內(nèi)存中,用戶訪問(wèn)的時(shí)候直接從內(nèi)存中取,就不需要通過(guò)數(shù)據(jù)庫(kù),從而大大降低數(shù)據(jù)庫(kù)的訪問(wèn)壓力。 通常而言,緩存可以分為本地緩存和部署在分布式服務(wù)器上的遠(yuǎn)程緩存。本地緩存存在于應(yīng)用服務(wù)器所在的內(nèi)存中,可能于應(yīng)用數(shù)據(jù)發(fā)生爭(zhēng)用的情況,而遠(yuǎn)程緩存則不會(huì)存在這種情況,因?yàn)樗械臄?shù)據(jù)都是熱點(diǎn)數(shù)據(jù),沒(méi)有干擾。本地緩存又可以分為瀏覽器緩存(Cookie)、操作系統(tǒng)緩存(如CPU的L1、L2和L3)、應(yīng)用服務(wù)器的緩存(本地內(nèi)存中)。通??梢允褂胑hcache作為本地緩存、Redis或者M(jìn)emocached作為分布式緩存 階段四:搭建應(yīng)用服務(wù)器集群改善并發(fā) 截至目前的演變,應(yīng)用服務(wù)器仍然是單兵作戰(zhàn),雖然以上的演變大大改善額網(wǎng)站的性能,但是隨著業(yè)務(wù)量的進(jìn)一步上升,單臺(tái)服務(wù)器的瓶頸就顯現(xiàn)出來(lái)了,因?yàn)楹芸赡芤驗(yàn)樨?fù)載過(guò)高導(dǎo)致應(yīng)用服務(wù)器直接掛掉。這種情況下,更好的做法是使用增加服務(wù)器的方式水平擴(kuò)展,這樣就可以實(shí)現(xiàn)彈性伸縮,當(dāng)負(fù)載過(guò)高的時(shí)候增加服務(wù)器,當(dāng)負(fù)載降下來(lái)的時(shí)候,減少服務(wù)器。是不是很優(yōu)雅?阿里在2012年提出的去“IOE”的原因之一就與這點(diǎn)有關(guān)。
雖然很優(yōu)雅,但是應(yīng)用服務(wù)器采用集群部署后,原來(lái)的請(qǐng)求過(guò)來(lái)的時(shí)候,如何知道調(diào)用哪臺(tái)服務(wù)器完成請(qǐng)求呢?這就需要使用到負(fù)載均衡服務(wù)器了,干嘛的呢?就是負(fù)責(zé)將請(qǐng)求轉(zhuǎn)發(fā)給某臺(tái)服務(wù)器。負(fù)載均衡又包括硬負(fù)載和軟負(fù)載。硬負(fù)載是硬件解決方案,比如F5,但是通常成本比較高,更常用的解決方案是軟負(fù)載,就是通常軟件實(shí)現(xiàn)負(fù)載均衡,比如LVS。 階段五:數(shù)據(jù)庫(kù)讀寫(xiě)分離減輕數(shù)據(jù)讀寫(xiě)壓力 雖然之前使用緩存將熱點(diǎn)數(shù)據(jù)緩存起來(lái)了,但是也存在緩存不命中的情況,這個(gè)時(shí)候又會(huì)直接訪問(wèn)數(shù)據(jù)庫(kù)了,當(dāng)緩存不命中的情況增大到一定規(guī)模的時(shí)候數(shù)據(jù)庫(kù)的壓力就又是一個(gè)問(wèn)題了。我們知道都數(shù)據(jù)庫(kù)進(jìn)行的操作無(wú)非兩種:讀和寫(xiě)。由于數(shù)據(jù)庫(kù)(比如MySQL)存在事務(wù)隔離級(jí)別和鎖的機(jī)制,可能會(huì)導(dǎo)致讀和寫(xiě)互相阻塞,那么如何實(shí)現(xiàn)數(shù)據(jù)庫(kù)的讀寫(xiě)分離呢?目前的思路將數(shù)據(jù)庫(kù)進(jìn)行主從拆分,所有的寫(xiě)操作操作主庫(kù),所有的讀操作操作從庫(kù),對(duì)主庫(kù)的更新操作會(huì)通過(guò)binlog同步到從庫(kù)上,從而在從庫(kù)也可以拿到最新的數(shù)據(jù)。如此一來(lái),讀寫(xiě)不再互相阻塞,性能至少提升1倍以上。就MySQL而言,主從熱備的功能可以通過(guò)cobar、mycat之類(lèi)的框架來(lái)完成。 階段六:使用CDN和反向代理改善網(wǎng)站響應(yīng) 網(wǎng)站的響應(yīng)又一個(gè)直觀的指標(biāo)(從用戶的角度)—— 訪問(wèn)的快慢。這點(diǎn)直接關(guān)系到用戶體驗(yàn),因?yàn)槿绻脩魣?zhí)行一個(gè)請(qǐng)求老半天都沒(méi)有響應(yīng),很可能就直接失去了這個(gè)用戶,然后通過(guò)口啤效應(yīng),后果很?chē)?yán)重。CDN和反向代理一種提高網(wǎng)站響應(yīng)的手段。其基本原理都是緩存。CDN是部署再網(wǎng)絡(luò)提供商所在的機(jī)房,當(dāng)用戶發(fā)起一個(gè)請(qǐng)求的時(shí)候,優(yōu)先從距離其較近的網(wǎng)絡(luò)提供商完成請(qǐng)求,而反向代理則是部署再網(wǎng)站的中心機(jī)房,當(dāng)請(qǐng)求到達(dá)中心機(jī)房時(shí),會(huì)首先由反向代理服務(wù)器完成請(qǐng)求,如果反向代理服務(wù)器存在請(qǐng)求的數(shù)據(jù),那么直接返回?cái)?shù)據(jù)給用戶。 階段七:使用分布式文件系統(tǒng)和分布式數(shù)據(jù)庫(kù)進(jìn)一步改善讀寫(xiě)壓力 當(dāng)單表的數(shù)據(jù)量達(dá)到一定規(guī)模的時(shí)候,比如過(guò)千萬(wàn),即使使用數(shù)據(jù)庫(kù)索引進(jìn)行優(yōu)化,完成的性能提升也是有限的。因?yàn)楫?dāng)單表的數(shù)據(jù)量達(dá)到千萬(wàn)的時(shí)候受限于執(zhí)行SQL的數(shù)據(jù)庫(kù)引擎(比如MySQL的InnoDB),所以需要進(jìn)行分庫(kù)分表。通常的做法時(shí)根據(jù)業(yè)務(wù)進(jìn)行分庫(kù)(垂直拆分),根據(jù)單表的數(shù)據(jù)量限制做分表(水平拆分)。業(yè)務(wù)分庫(kù)需要根據(jù)具體的業(yè)務(wù)場(chǎng)景進(jìn)行確定,相對(duì)來(lái)說(shuō)比較好完成,分表就不是這樣了。因?yàn)樵诖a中寫(xiě)的SQL就是一張表,現(xiàn)在要分表,那原來(lái)的SQL肯定有問(wèn)題。這個(gè)可以通過(guò)merge引擎來(lái)完成。 階段八:使用NoSQL和搜索引擎優(yōu)化檢索性能 使用NoSQL和搜索引擎時(shí)為了解決數(shù)據(jù)查詢的需求,比如在淘寶搜索一件商品的時(shí)候,總不能使用SQL的like進(jìn)行匹配吧,效率太低!而搜索引擎可以利用倒排索引這種數(shù)據(jù)結(jié)構(gòu)很好支持?jǐn)?shù)據(jù)查詢。常用的解決方案時(shí)Lucene/Solr。 階段九:業(yè)務(wù)拆分讓網(wǎng)站維護(hù)更簡(jiǎn)單 隨著業(yè)務(wù)場(chǎng)景的復(fù)雜化,將不同的業(yè)務(wù)分成不同的產(chǎn)品,就是把一個(gè)網(wǎng)站原來(lái)一個(gè)項(xiàng)目的情況拆分為根據(jù)不同的業(yè)務(wù)拆分為不同的項(xiàng)目。如果在項(xiàng)目中需要依賴其他項(xiàng)目的服務(wù),比如在Maven工程中可以通過(guò)添加依賴的方式獲取。 階段十:抽取公共服務(wù) 這點(diǎn)很好理解,比如在不同的業(yè)務(wù)(項(xiàng)目)中都需要使用用戶管理這個(gè)業(yè)務(wù),那么可以把這個(gè)業(yè)務(wù)抽取出來(lái)作為公共服務(wù),需要的時(shí)候直接添加依賴即可。 技術(shù)點(diǎn)整理 雖然大型網(wǎng)站演變到現(xiàn)在,架構(gòu)已經(jīng)非常復(fù)雜,但是仍然可以歸為以下的架構(gòu)模型: 前端 ——> 應(yīng)用層 ——> 服務(wù)層 ——> 存儲(chǔ)層 ——> 后臺(tái)架構(gòu) 大型網(wǎng)站架構(gòu)要素可以總結(jié)為5點(diǎn):高性能、高可用、伸縮性、可擴(kuò)展性、安全性。 高性能 主要關(guān)注以下幾個(gè)指標(biāo):響應(yīng)時(shí)間(一個(gè)請(qǐng)求從發(fā)出請(qǐng)求到接收到響應(yīng)數(shù)據(jù)需要的時(shí)間,是網(wǎng)站最重要的性能指標(biāo))、并發(fā)數(shù)(網(wǎng)站能夠同時(shí)處理請(qǐng)求的請(qǐng)求數(shù))、吞吐量(單位時(shí)間內(nèi)系統(tǒng)處理的請(qǐng)求數(shù),反映了網(wǎng)站的整體性能)。比如TPS是指每秒的事務(wù)數(shù)、QPS是指每秒的查詢數(shù)。并發(fā)數(shù)在逐漸增大的過(guò)程中,系統(tǒng)的吞吐量會(huì)先逐漸增加,到達(dá)一個(gè)極限后,隨著并發(fā)數(shù)的繼續(xù)增大反而下降,直至系統(tǒng)資源后耗盡,吞吐量為0。這是因?yàn)椴l(fā)數(shù)增大的過(guò)程實(shí)際上系統(tǒng)資源消耗增大的過(guò)程。而在這個(gè)過(guò)程中,響應(yīng)時(shí)間會(huì)先保持小幅的上升,到達(dá)吞吐量極限后,快速上升,資源耗盡后,系統(tǒng)失去響應(yīng)。 高可用 高可用就是在網(wǎng)站發(fā)生故障的時(shí)候能夠迅速處理,保證網(wǎng)站服務(wù)依然可用、數(shù)據(jù)依然能夠被訪問(wèn)。這里包括兩點(diǎn):服務(wù)的高可用和數(shù)據(jù)的高可用。服務(wù)的高可用的通常處理策略是分級(jí)管理(核心業(yè)務(wù)使用更好的硬件資源)、超時(shí)設(shè)置(服務(wù)調(diào)用超時(shí)使用服務(wù)超時(shí)策略,比如繼續(xù)重試和服務(wù)調(diào)用轉(zhuǎn)移,由其他可用的服務(wù)提供服務(wù))、異步調(diào)用(能晚則晚)、服務(wù)降級(jí)(在性能下降或者服務(wù)宕機(jī)的時(shí)候,使用拒絕服務(wù)以及關(guān)閉服務(wù)的策略,即使是失敗也要迅速返回,而不要讓請(qǐng)求一直hung著)、冪等性(保證在重復(fù)調(diào)用的情況下返回和調(diào)用一次的結(jié)果相同)。數(shù)據(jù)的高可用包括數(shù)據(jù)備份和失效轉(zhuǎn)移(某臺(tái)服務(wù)器宕機(jī),能夠路由到其他機(jī)器繼續(xù)提供服務(wù)),在分布式環(huán)境,數(shù)據(jù)會(huì)被多個(gè)節(jié)點(diǎn)操作,如何保證數(shù)據(jù)的一致性是數(shù)據(jù)高可用的前提,這里涉及的核心技術(shù)點(diǎn)是CAP、BASE理論。 伸縮性 在不改變現(xiàn)有系統(tǒng)架構(gòu)的前提下,僅僅通過(guò)增加或者減少機(jī)器就可以改變網(wǎng)站的處理能力。 可擴(kuò)展性 指的是在對(duì)現(xiàn)有系統(tǒng)影響最小的情況下,系統(tǒng)功能的可持續(xù)擴(kuò)展或者提升的能力。通常表現(xiàn)在應(yīng)用之間較少的耦合、對(duì)需求變更敏捷響應(yīng),符合開(kāi)閉原則。 安全性 保護(hù)網(wǎng)站不受惡意訪問(wèn)和攻擊,保護(hù)網(wǎng)站的數(shù)據(jù)不被竊取和篡改。 技術(shù)點(diǎn) 下面是我整理的各個(gè)要素的核心技能點(diǎn),更詳細(xì)的技能圖譜將在下篇博客中給出(思維導(dǎo)圖)。 高性能:分布式緩存(Redis)、異步調(diào)用(NIO/AIO + MQ(消息隊(duì)列) + JVM + 代碼優(yōu)化)、HDFS 高可用:分布式Session、異步調(diào)用 + 服務(wù)降級(jí) + 冪等性保證、數(shù)據(jù)備份 + 失效轉(zhuǎn)移 伸縮性:負(fù)載均衡算法、一致性hash、cobar集群、Hbase 可擴(kuò)展性:分布式消息隊(duì)列(RabbitMQ、ActiveMQ、ZeroMQ、Kafka)、分布式服務(wù)(dubbo、gRPC) 安全性:MD5,SHA(單項(xiàng)散列加密)、DES(對(duì)稱加密)、RSA,HTTPS(非對(duì)稱加密) 程序員價(jià)值觀 可以發(fā)現(xiàn)在大型網(wǎng)站的演變中每個(gè)階段需要解決的問(wèn)題都是圍繞業(yè)務(wù)進(jìn)行,而這點(diǎn)是直接與產(chǎn)生的價(jià)值掛鉤的。不過(guò)這都是大的方面了,因?yàn)樽鳛橐粋€(gè)程序員,我們更關(guān)心的技術(shù)本身以及技術(shù)所帶給我們的成長(zhǎng)與增值空間。雖然我還不是一個(gè)有豐富經(jīng)驗(yàn)的程序員,但是作為程序員很重要的一點(diǎn)就是保持學(xué)習(xí)、保持進(jìn)步。我對(duì)自己的目標(biāo)是三到五年內(nèi)能夠具有獨(dú)立架構(gòu)設(shè)計(jì)能力,具有獨(dú)當(dāng)一面的能力(包括人脈和自身能力(技能和知識(shí)儲(chǔ)備))。而我對(duì)自己設(shè)定的目標(biāo)是在每天的上班之余堅(jiān)持看書(shū),不在于能看多少,重要的是有收獲,得到了成長(zhǎng)。說(shuō)來(lái)懺愧,這點(diǎn)并沒(méi)有很好的貫徹下去,但是自己以后會(huì)慢慢適應(yīng)這種節(jié)奏的。 也許每天上班本來(lái)就很累,晚上下班回來(lái)還要抽空看書(shū)是痛苦的,但如果沒(méi)有這種毅力如何實(shí)現(xiàn)三年目標(biāo)、五年目標(biāo)呢?至少現(xiàn)在自己還年輕,有拼搏的本錢(qián),所以就更應(yīng)該好好珍惜時(shí)間,不斷地提升自我,爭(zhēng)取早日實(shí)現(xiàn)目標(biāo)。 回到主題,首先需要認(rèn)識(shí)到,掌握上述的技能點(diǎn)不是一朝一夕的,這就需要不斷在空閑時(shí)間升華自己,一點(diǎn)一滴積累。而且,掌握技能僅僅是第一步,真正牛逼的程序員是能夠把上述相關(guān)知識(shí)與技能進(jìn)行重組,并且很好的解決業(yè)務(wù)問(wèn)題,謂之“最佳實(shí)踐”。而且對(duì)每個(gè)技能點(diǎn)與知識(shí)一定要進(jìn)行體系化學(xué)習(xí),因?yàn)轶w系化的學(xué)習(xí)可以了解到技術(shù)的全貌,而不是僅僅在工作需要時(shí)Google就可以的。謂之技術(shù)的深度。牛逼的程序員的牛逼之處在于能夠?qū)夹g(shù)的實(shí)現(xiàn)細(xì)節(jié)了然于胸,這樣當(dāng)系統(tǒng)出問(wèn)題時(shí)才能迅速定位問(wèn)題所在,并快速解決問(wèn)題。而體系化的學(xué)習(xí)公認(rèn)的最佳實(shí)踐就是看書(shū)了,所以千萬(wàn)不要吝嗇買(mǎi)書(shū)的錢(qián),因?yàn)橘I(mǎi)了,書(shū)的價(jià)值就在那,一切就等你去挖掘了! 我覺(jué)得可以先設(shè)立一個(gè)小目標(biāo),比如每個(gè)月至少4篇博客。道阻且長(zhǎng),我心向往之?。?/p> |
|
|
來(lái)自: WindySky > 《架構(gòu)師知識(shí)體系》