【攻城系列】網站架構

第一次系統性的寫一些技術架構上的文章,當給自己日常零碎當中的事情,做一個梳理,就當預編譯一次。

單說,如何架構一個網站?

我該怎麼回答呢?其實這是老生常談的問題,問題問的很大,涉及的範圍非常多,總不能簡單的跟人說,買臺服務器,寫好代碼,解析域名,備案完畢,好了,架構完畢,跟一些外行的客戶,不想與其廢話時,倒是可以這麼打發人家了,不過真要跟行家討論這個問題,還不得被人鄙視,唾棄,於是仔細想想,道個1,2,3,4,5。。。有條有理的說一下,話說,面試來面試去,面別人,被別人面,不就在討論這玩意兒麼。

先說,網站架構的目的是什麼?而不是說,麻木性質的去做這件事。

無非圍繞三個方面,

一、高性能

二、高可用性

三、高拓展性

分述之,

一、高性能,

即站在用戶的角度來說,輸入網址,或者點擊鏈接,頁面,唰一下,展現在眼前,至於說,頁面打開速度要多快,纔算快,這個跟具體的每個用戶的網絡環境,還有操作系統本身的原因也有關係,一般來說,理想的狀態,是頁面在2s以內展現完畢,如果超過6-8s,用戶可能就X掉網頁了,超過12s,那就99%的可能性準備跟該用戶說byebye了。


在提高網頁速度的背後,我們需要去做的事情,就很多了。

現在假設我們要去做一個不久後,將會有大規模用戶和點擊量的網站,就那我之前公司的網站做個例子吧。

一開始,只是個小作坊,弄臺服務器,跑起Redhat或者CentOs,裝個Apache,搭個PHP(FastCgi),走着Mysql,開發好代碼,放上去了,好了,第一版架構完畢,可能有人要問,就這樣,就可以了嗎,不用考慮,負載均衡,CDN,代碼框架,網站性能監控神馬的嗎,是的,一開始小規模小作坊,小打小鬧,沒資金也沒人,用戶基本不知道你的網站,每天PV少的可憐,只有上線後,Money入賬了,才能回過來不斷改善產品,否則根本經不起技術上的投入成本這種折騰,當然了,如果早期你有風投給你投個幾百萬幾千萬美金,那是令談。


好了,一段時間之後,經過你不懈的努力,推廣宣傳,你的網站訪問量噌噌噌的上來了,呀,打開網頁有點卡,好慢,噌~一下504,502,掛了,檢查,Mysql連接太多,無法承受猛增的讀寫併發。此時的PV大概達到1W左右吧,好,怎麼辦呢,重啓服務器,網站又能打開了,不過,這貌似不是解決辦法,還要人守着,掛了,就重啓不成。

於是,又弄了臺機器,把數據庫和代碼物理分離了,現在兩臺機器了,也不會相互影響了,果然好多了。也不需要改動什麼代碼,只是改個Mysql所在的Ip地址,就可以順利運行了。

好景不常在,好事不常留啊,隨着用戶量的增長,此時PV將要接近10W,網站又開始變卡了,又開始經常間斷性的掛掉了,數據庫的讀寫量已經超出了其自身的承受能力。


於是,緩存登場了,Memcached,分佈式緩存,用它來保護數據庫,讓讀寫直接操作內存,減輕數據庫的負擔,另外,一些帖子文章,直接寫入文件緩存,利用磁盤的IO,也來分擔數據庫的一部分壓力,有沒有發現網站的打開速度變快了,現在我們有三臺機器,一臺web,一臺Memcached,一臺Mysql


好了,現在我們要做的事情有很多了,一來是因爲用戶的持續增長,是預料之中的事情,二來,是不斷增加的網站功能,需要我們不斷改善我們現有的架構,第三,應該是最重要的,xx委,xx主任,給我們公司投錢了,至於爲什麼投錢,跟2XBoss的忽悠有關係,打着個拯救全人類,全中國下一代這種旗子,算了,這個就沒什麼好細說的了,咱是P民,無權關心,搞好技術再說。


於是大規模的購買設備,網站呢,要重構,且要增加很多功能模塊,神馬,微博了,動態了,消息了,相冊,網盤了,哎呀,一個不倫不類的產品即將誕生,自稱SNS,卻混着BBS,且,有着兩套關係系統,自稱BBS,卻帶着多許不相關的玩意兒,哎呀,我去!割草!,sorry,說髒話了,我不是產品經理,我沒資格說,那既然做了,那咱就只有保證產品的穩定運行吧,後來事實證明,這頭不倫不類的東西,的確有些失敗,這是後話,當然了,此時,用戶量還在不斷增長當中。



二、高可用性

站在用戶角度來說,就是隨時隨地,訪問你的網站,都可以正常打開,就是說,不宕機,雖說,不能保證一年365天,隨時都能做到,但這種概率至少要大於99.9%。


數據庫切片(水平拆分,垂直拆分)

垂直拆分,針對產品線來拆分,把原有的表,比如用戶表,博客表,相冊表,論壇表等,分別創建用戶數據庫,博客數據庫,相冊數據庫,論壇數據庫等(基於不同的數據庫機器上)

水平拆分,針對某個表進行一定算法的分庫分表,比如取模拆分或者根據用戶id拆分,地域拆分等



服務器健康檢查,對於Web,和DB,主備冗餘,及時有效的監控和報警,常用的如Cacti+Rrdtool+nagios,去查看服務器,網絡所處的狀態



三、高拓展性

一般,面對公司內部開發架構來說的,

我們計劃增加客戶端,支持移動設備的訪問,而且,我們要有自己的開放平臺,可以讓其他單位或者公司吧,可以訪問我們的數據,好的,這個有意思,那網站就徹底重構一次吧。


我看之前的代碼已經很不爽了,經過反覆的產品開發疊加,代碼已經極度冗餘了,也不知道有多少文件是還在使用當中的,關鍵是,可拓展性,可維護性,已經幾近讓我抓狂,說幹咱就幹哪,話說,對於代碼框架,我經常會去想,怎麼樣,纔算一個高效,高可拓展性的,高可維護性的代碼,而且,對於每個開發人員都在這套框架體系下,如何協調好,充分利用每個開發人員的能力,纔是這個框架該做的。

要知道,起初,針對網站,可以出一套框架,之後,客戶端出來了,爲了調用用戶數據,必須再重寫一套,之後,開放平臺又出來了,還得整一套?我的天哪,真想摔桌子,然後自己滾蛋,你們自己去玩吧,給點時間,咱好好整整,行不,別一天到晚,拿着個連KPI,全拼都拼不出來的玩意兒,整我,行不?你才幾個人哪,有的沒的。


PS:如果一個網站是傳統的MVC,那最初的開發,和維護都還是不錯的,但是這種框架,恐怕不能滿足後期的拓展,要知道Amazon,在早期可是已經完全接口化開發了,隨着公司的發展,內部外部的接口化,是不可避免的,比如說,有個同事在開發一個新產品,問道,用戶的基本信息在那張表,哪幾個字段,用戶的博客數據在哪張表,好的,那你告訴它,在某某表,執行哪條Sql,或者讓他去看,其他模塊產品中類似的邏輯,問一次,二次,三次,還行,但是員工越來越多,一天問你三十次,你的感覺會怎麼樣,有沒有拿起桌子上的電腦,砸他的衝動~

於是,面向MVC的接口化,開發,在所難免,且,好處多多,解決了這種繁瑣的溝通以及,其他你想到的沒想到的很多問題。

傳統的,Model,View,Controller,當用戶發Request到你的網站的某一個頁面來的時候,Index做爲入口,根據來源鏈接,匹配頁面路由,映射到Controller,根據Model中的數據,反饋給View,然後生成html,通過瀏覽器呈現給用戶,做到這一點,說明也算是一個網站的mvc框架了,且不說,其他的,緩存處理,模版引擎,內置常用方法等。

說到接口化,那麼外網和內網的接口,是要區分出來的(私有接口,和開放接口),比如說,內網,一般在跨產品線開發時,內部調用,通過http,restful的訪問,即可完成想要的數據,不用考慮安全性,雖說,它比https的性能高,但是終究是處在應用層,要調用傳輸層的Tcp,對於內網調用,性能還是偏低,可以增加一些緩存來提高性能,如果覺得不夠,可以使用Facebook的Thift和Google的Protocol Buffers。對數據結構做了壓縮,大大降低了數據文件的大小,可以很大的提高一部分性能。

外網,例如第三方公司,在調用你的接口時,你就必須加密ssl通道,且,增加一系列的加密驗證算法,或者使用OAuth,可以直接使用2.0,做好接口的管理,比如接口的調用次數,調用頻率,防止別人去反覆惡意調用。


在網站的發展當中,遇到了問題,衡量一下,如果可以重構,就馬上徹底重構,如果產品線太多,那就一步一步的來替換重構,否則,整個團隊,恐怕就要陷到改Bug的泥潭當中了,而且,重構的越早越徹底,將有利於網站的擴展,發展,這個很重要,我是深受其害。








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章