近幾年的互聯(lián)網(wǎng)創(chuàng)業(yè)風(fēng)潮持續(xù)在高漲中,所涉及的行業(yè)從涵蓋了社交、資訊、電商、生活服務(wù)等方方面面。其中也涌現(xiàn)不少優(yōu)秀的APP,而這些產(chǎn)品或平臺(tái)的特點(diǎn)都包含了"快速",即更新快,迭代快的特性。
然而作為一名軟件工程師的角度,按以前軟件工程的理論來說,系統(tǒng)在設(shè)計(jì)初期應(yīng)考慮更多的復(fù)雜度、良好的擴(kuò)展性,盡可能達(dá)到以不變應(yīng)萬變的結(jié)果,而這些快速變更的新秀產(chǎn)品,在系統(tǒng)架構(gòu)上如何做到靈活擴(kuò)展、快速演進(jìn)的呢? 這便是以下要開始探討的內(nèi)容。
在最開始的時(shí)候,產(chǎn)品經(jīng)理(或項(xiàng)目經(jīng)理)找到你,在嘮嘮叨叨敘述完整個(gè)系統(tǒng)的功能需求后,要求你一個(gè)月內(nèi)就開發(fā)出來。
當(dāng)然,以上的場(chǎng)景稍顯夸張,但在互聯(lián)網(wǎng)思維方式的APP開發(fā)場(chǎng)景下,這樣的節(jié)奏其實(shí)很常見。
架構(gòu)特點(diǎn)
單點(diǎn),以滿足功能為主,簡(jiǎn)單、輕量級(jí)架構(gòu)。
數(shù)據(jù)流
來自多種場(chǎng)景的的http請(qǐng)求直接由單個(gè)server接入、完成業(yè)務(wù)邏輯處理、輸出計(jì)算結(jié)果。
組件介紹
1 App Server,應(yīng)用系統(tǒng)的服務(wù)端節(jié)點(diǎn),可以有很多種選擇,以Java系列為例:
tomcat
最流行不過的j2ee容器,官網(wǎng)http://tomcat.apache.org/
jetty
一款更為輕量級(jí)的servlet容器,輕量小巧,提供可編程server的實(shí)現(xiàn)(容易嵌入),在continuation機(jī)制也有比較良好的表現(xiàn)。
詳細(xì)參見http://www.eclipse.org/jetty/
playframework
此前最為喜愛的一款非主流應(yīng)用服務(wù)器,應(yīng)該是首個(gè)java版本的"ruby on rails"的實(shí)現(xiàn)。其摒棄了j2ee繁重的各種理念枷鎖,讓編程變得更加簡(jiǎn)單、可依賴。
playframework框架目前已經(jīng)主推2.x (同時(shí)支持java和scala)版本,然而學(xué)習(xí)曲線相較1.2.x版本更加陡峭,建議可從1.2.5版本開始入門使用。
值得一提的是該框架內(nèi)置了netty以支持http請(qǐng)求的接入及處理。
netty是一款基于NIO實(shí)現(xiàn)的輕量級(jí)http服務(wù)器,
關(guān)于netty的實(shí)現(xiàn)原理可參考:http://stonexmx.blog.163.com/blog/static/122158587201061331614536/
play框架的官網(wǎng):https://www.playframework.com/
2 mysql,流行的開源數(shù)據(jù)庫(kù),應(yīng)用基于JPA/JDBC進(jìn)行訪問,以實(shí)現(xiàn)數(shù)據(jù)持久化
3 memcached, 高速的內(nèi)存服務(wù)器系統(tǒng),支持KV數(shù)據(jù)流的快速讀寫,用作數(shù)據(jù)緩存及加速訪問
官網(wǎng)地址:http://memcached.org/
二、演變的開始
好的,經(jīng)過一個(gè)月的努力,系統(tǒng)上線了。
運(yùn)營(yíng)也開始干活,緊接著是對(duì)線上各種問題的緊急修復(fù)。
系統(tǒng)漸漸有了一些活躍度,在幾個(gè)月內(nèi),產(chǎn)品經(jīng)理和研發(fā)經(jīng)理開始聽到了一些抱怨:
"系統(tǒng)怎么老掛啊,動(dòng)不動(dòng)就訪問不了,這什么破玩意啊" "我這都已經(jīng)換成wifi了,圖片怎么還是一直加載不了呢?"
.....
所謂積少成怨,團(tuán)隊(duì)終于頂不住壓力,下決心開始優(yōu)化系統(tǒng)。針對(duì)上述的問題,分析如下:
1 可用性;單點(diǎn)發(fā)生崩潰,整個(gè)系統(tǒng)直接不可用,所有用戶將受到影響;
JVM的內(nèi)存溢出,系統(tǒng)進(jìn)程意外終止都可能導(dǎo)致這樣的問題。
2 帶寬;
應(yīng)用系統(tǒng)在初期設(shè)計(jì)時(shí)更多的考慮了網(wǎng)絡(luò)調(diào)用、html動(dòng)態(tài)頁(yè)面的輸出,而針對(duì)圖片的訪問并未做過多考慮,因此文件資源訪問很快出現(xiàn)了瓶頸。
研發(fā)經(jīng)理決定將架構(gòu)優(yōu)化如下:
負(fù)載均衡
使用nginx提供應(yīng)用服務(wù)器的負(fù)載均衡,提供兩個(gè)應(yīng)用服務(wù)器節(jié)點(diǎn),保證單點(diǎn)崩潰時(shí)而系統(tǒng)仍然可用。
文件訪問分離
使用單獨(dú)的web服務(wù)器(nginx)用作文件訪問服務(wù)器,所有的靜態(tài)圖片地址將指向獨(dú)立域名。
三、加速進(jìn)化
繼上一次優(yōu)化之后,用戶的抱怨已經(jīng)明顯減少,產(chǎn)品經(jīng)理和領(lǐng)導(dǎo)都對(duì)此次工作表示滿意。
研發(fā)經(jīng)理開始感受到了前所未有的成就感。
然而好景不長(zhǎng),在幾個(gè)月后公司重點(diǎn)引入了營(yíng)銷團(tuán)隊(duì)。這是相當(dāng)給力的團(tuán)隊(duì),在短短的時(shí)間內(nèi),在各大網(wǎng)絡(luò)平臺(tái)布置了多個(gè)入口。
各種推廣活動(dòng)、事件營(yíng)銷接踵而來。最可觀的如在微信朋友圈的一次事件營(yíng)銷直接引入了好幾倍的用戶量。
這樣的情況在互聯(lián)網(wǎng)產(chǎn)品的發(fā)展軌跡上至少也可以稱得上一次小小的爆發(fā)式增長(zhǎng)了。
當(dāng)然,領(lǐng)導(dǎo)、產(chǎn)品經(jīng)理都開心和興奮起來了。但這次,研發(fā)經(jīng)理內(nèi)心開始發(fā)愁了:
1 訪問壓力;
一個(gè)server的并發(fā)處理能力很容易達(dá)到上限,一旦超過負(fù)載閾值,將直接導(dǎo)致訪問時(shí)長(zhǎng)加大,甚至系統(tǒng)崩潰、無法訪問等情形;
2 數(shù)據(jù)存??;數(shù)據(jù)量的擴(kuò)充,單個(gè)數(shù)據(jù)庫(kù)表不斷增大,查詢速度將產(chǎn)生下降;
此外數(shù)據(jù)庫(kù)的單點(diǎn)也成為隱患
3 緩存空間;
與數(shù)據(jù)庫(kù)同理,為加速更多數(shù)據(jù)的訪問,需要提供更大容量緩存空間;
這次,研發(fā)經(jīng)理將系統(tǒng)架構(gòu)做了一次較為徹底的改進(jìn):
負(fù)載均衡
增加負(fù)載均衡的服務(wù)器節(jié)點(diǎn),提高整體處理能力;
數(shù)據(jù)庫(kù)擴(kuò)展
采取水平切分的方式,實(shí)現(xiàn)基于Shard的分布式數(shù)據(jù)庫(kù)集群;
memcached集群
開啟多個(gè)memcached節(jié)點(diǎn),組成高可用的緩存集群,同時(shí)可支持更大的緩存空間
其中對(duì)于服務(wù)端程序改造的在于分布式Shard數(shù)據(jù)的實(shí)現(xiàn),一般可從數(shù)據(jù)量較大的局部表開始切分,在數(shù)據(jù)存取上加入水平分庫(kù)的機(jī)制;
當(dāng)然此時(shí)的數(shù)據(jù)遷移工作也是一個(gè)重點(diǎn)。
四、未來的展望
至此,系統(tǒng)優(yōu)化已經(jīng)告一段落。當(dāng)前的后臺(tái)架構(gòu)已經(jīng)處在一個(gè)表現(xiàn)穩(wěn)定,容易擴(kuò)展的一個(gè)狀態(tài)。
性能指標(biāo)方面大致已經(jīng)可以達(dá)到百萬級(jí)用戶量,日PV過百萬,甚至還可能更好。
然而這還僅僅是一個(gè)雛形,應(yīng)用系統(tǒng)的場(chǎng)景是多種多樣的,在未來需要解決的問題往往不僅僅這些,比如:
1 系統(tǒng)存在全文搜索、或是標(biāo)簽式搜索的場(chǎng)景,為了提高搜索性能,你可能會(huì)引入sphinx中間件;
sphinx的中文版本為coreseek(可支持中文全文搜索),。
詳見官網(wǎng):http://www.coreseek.cn/
2 為了提高事務(wù)處理的效率,你需要隊(duì)列服務(wù)器來解決,這個(gè)可以是ttserver + worker的模式;
3 頻繁的處理緩存數(shù)據(jù)的解析在開發(fā)上會(huì)比較麻煩,你還可以更換redis來直接支持?jǐn)?shù)據(jù)結(jié)構(gòu)式的緩存...
redis為一款支持?jǐn)?shù)據(jù)結(jié)構(gòu)緩存及數(shù)據(jù)持久化的優(yōu)秀的nosql中間件,
官網(wǎng)地址:http://redis.io/