一般來說,技術人員(程式設計師)創業都是根據自己技術背景選擇自己最熟悉的語言,不過考慮到不可能永遠是您一個人寫程式,這點還得仔細想想。無論用什麼語言,最終程式碼質量是看管理,所以我們還是從純語言層面來說實際一點。現在流行的java、php、.net、python、ruby都 有自己的優劣,python和ruby,現在人員還是相對難招一些,效能優化也會費些力氣,.net平臺買不起windows server。java、php用的還是最多。對於初期,應用幾乎都是靠前端支撐的網站來說,php的優勢稍大一些,入門簡單、設計模式簡單、寫起來快、 效能足夠等,不過不注重設計模式也是它的劣勢,容易變得鬆散,隱藏bug稍多、難以維護。java的優勢在於整套管理流程已經有很多成熟工具來輔助,強類 型也能避免一些弱智BUG,大多數JAVA程式設計師比較注重設計模式,別管實不實際,程式碼格式看起來還是不錯的。這也是個劣勢,初學者可能太注重模式而很難 解決實際需求。
前端不只是html、css這類。整個負責跟使用者互動的部分都是前端,包括處理程式。這類程式還是建議用php、java,主要原因就是開發迅速、從業人員廣泛。至於後端例如行為分析、銀行介面、非同步訊息處理等,隨便用什麼程式,那個只能是根據不同業務需求來選擇不同語言了。
二、程式碼版本管理
假設選了svn,那麼有幾點考慮。一是採用什麼樹結構。初期可能只有一條主幹,往後就需要建立分支,例如一條開發分支,一條上線分支,再往後,可能 要每個小組一個分支。建議一開始人少時選擇兩條分支,開發和線上,每個功能本地測試無誤後提交到開發分支,最後統一測試,可以上線時合併到上線分支。如果 喜歡把svn當做行動硬碟用,寫一點就commit一次也無所謂,就是合併的時候頭大一些,這些人可以自己建個分支甚至建立個原生程式碼倉庫,隨便往自己的 分支提交,測試完畢後再提交到開發分支上。
部署,可以手工部署也可以自動部署。手工部署相對簡單,一般是直接在伺服器上svn update,或者找個新目錄svn checkout,再把web root給ln -s過去。應用越複雜,部署越複雜,沒有什麼統一標準,只要別再用ftp上傳那種形式就好,一是上傳時檔案引用不一致錯誤率增加,二是很容易出現開發人員 的版本跟線上版本不一致,導致本來想改個錯字結果變成回滾的杯具。如果有多臺伺服器還是建議自動部署,更換程式碼的機器從當前服務池中臨時撤出,更新完畢後 再重新加入。
不管專案多小,養成使用版本管理的好習慣,最起碼還可以當做你的備份,我的 http://zhiyi.us 雖然就是一個wordpress,可還是svn了,只改動一兩句css那也是勞動成果。
三、伺服器硬體
別羨慕大客戶和有錢人,看看機房散戶區,一臺伺服器孤獨的支撐的網站數不清。如果資金稍微充足,建議至少三臺的標準配置,分別用作web處理、資料 庫、備份。web伺服器至少要8G記憶體,雙sata raid1,如果經濟稍微寬鬆,或靜態檔案或圖片多,則15k sas raid1+0。資料庫至少16G記憶體,15k sas raid 1+0。備份伺服器最好跟資料庫伺服器同等配置。硬體可以自己買品牌的底板,也就是機箱配主機板和硬碟盒,CPU記憶體硬碟都自己配,也可以上整套品牌,也可 以相容機。三臺機器,市場行情6、7萬也就配齊了。
web伺服器可以既跑程式又當記憶體快取,資料庫伺服器則只跑主資料庫(假如是MySQL的話),備份伺服器乾的活就相對多一些,web配置、快取配置、資料庫配置都要跟前兩臺一致,這樣WEB和資料庫任意一臺出問題,把備份伺服器換個ip就切換上去了。備份策略,可以drbd,可以rsync,或者其他的很多很多的開源備份方案可選擇。rsync最簡單,放cron裡自己跑就行。備份和切換,建議多做測試,選最安全最適合業務的,並且儘可能異地備份。
四、機房
三種機房儘量不要選:聯通訪問特別慢的電信機房、電信訪問特別慢的聯通機房、電信聯通訪問特別慢的移動或鐵通機房。那網通機房呢?親,網通聯通N久 以前合併改叫聯通了。多多尋找,實地參觀,多多測試,多方打探,北京、上海、廣州等各個主節點城市,還是有很多優質機房的,找個網路質量好,管理嚴格的機 房,特別是管理要嚴格,千萬別網站無法訪問了,打個電話過去才知道別人維護時把你網線碰掉了,這比DOS都頭疼。自己扯了幾根光纖就稱為機房的,看您抗風 險程度和心理素質了。機房可以說是非常重要,直接關係到網站訪問速度,網站訪問速度直接關係到使用者體驗,我可以F牆看風景,但買個網遊vpn才能開啟你這 個還不怎麼知名的網站就有難度了。或許您網站的ajax很出色,可是document怎麼也不ready,一些程式碼永遠絕緣於使用者。
五、架構
初期架構一般比較簡單,web負載均衡+資料庫主從+快取+分散式儲存+佇列。大方向上也確實就這幾樣東西,細節上也無數文章都重複過了,按照將來 會有N多WEB,N多主從關係,N多快取,N多xxx設計就行,基本方案都是現成的,只是您比其他人厲害之處就在於設計上考慮到快取失效時的雪崩效應、主 從同步的資料一致性和時間差、佇列的穩定性和失敗後的重試策略、檔案儲存的效率和備份方式等等意外情況。快取總有一天會失效,資料庫複製總有一天會斷掉, 佇列總有一天會寫不進去,電源總有一天會燒壞。根據墨菲定律,如果不考慮這些,網站早晚會成為茶几。
六、伺服器軟體
Linux、nginx、php、mysql,幾乎是標配,我們除了看名字,還得選版本。Linux發行版眾多,只要沒特殊要求,就選個用的人最多的,社群最活躍的,配置最方便的,軟體包最全最新的,例如debian、ubuntu。 至於RHEL之類的嘛,你用只能在RHEL上才能執行的軟體麼?剩下的nginx、php、mysql、activemq、其他的等等,除非你改過這些軟 件或你的程式真的不相容新版本,否則儘量版本越新越好,版本新,意味著新特性增多、BUG減少、效能增加。總有些道聽途說的人跟你說老的版本穩定。所謂穩 定,是相對於特殊業務來說的,而就一個php寫的網站,大多數人都沒改過任何伺服器軟體原始碼,絕大多數情況是能平穩的升級到新版本的。類似於jdk5到 jdk6,python2到python3這類變動比較大的升級還是比較少見的。看看ChangeLog,看看升級說明,結合自己情況評估一下,越早升級 越好,別人家都用php6寫程式了這邊還php4的逛遊呢。優秀的開源程式升級還是很負責任的,看好文件,別怕。
以上這六點準備完畢,現在我們有了執行環境,有了基本架構骨架,有了備份和切換方案,應該開始著手設計開發方面的事情了。開發方面的事情無數,下一篇會先說一些重點。
七、資料庫
幾乎所有操作最後都要落到資料庫身上,它又最難擴充套件(儲存也挺難)。對於mysql,什麼樣的表用myisam,什麼樣的表用innodb,在開發 之前要確定。
複製策略、分片策略,也要確定。表引擎方面,一般,更新不多、不需要事務的表可以用myisam,需要行鎖定、事務支援的,用innodb。
myisam的鎖表不一定是效能低下的根源,innodb也不一定全是行鎖,具體細節要多看相關的文件,熟悉了引擎特性才能用的更好。
現代WEB應用越來 越複雜了,我們設計表結構時常常設計很多冗餘,雖然不符合傳統正規化,但為了速度考慮還是值得的,要求高的情況下甚至要杜絕聯合查詢。
程式設計時得多注意資料一 致性。
複製策略方面,多主多從結構也最好一開始就設計好,程式碼直接按照多主多從來編寫,用一些小技巧來避免複製延時問題,
並且還要解決多資料庫資料是否一致,可以自己寫或者找現成的運維工具。
分片策略。總會有那麼幾個表資料量超大,這時分片必不可免。分片有很多策略,從簡單的分割槽到根據熱度自動調整,依照具體業務選擇一個適合自己的。
避免自增ID作為主鍵,不利於分片。
用儲存過程是比較難擴充套件的,這種情形多發生於傳統C/S,特別是OA系統轉換過來的開發人員。
低成本網站不是一兩臺小型機跑一個資料庫處理所有業務的模式,是機海作戰。方便水平擴充套件比那點預分析時間和網路傳輸流量要重要的多的多。
NoSQL。這只是一個概念。實際應用中,網站有著越來越多的密集寫操作、上億的簡單關係資料讀取、熱備等,這都不是傳統關聯式資料庫所擅長的,
於是 就產生了很多非關係型資料庫,比如Redis/TC&TT/MongoDB/Memcachedb等,在測試中,這些幾乎都達到了每秒至少一萬次 的寫操作,
記憶體型的甚至5萬以上。例如MongoDB,幾句配置就可以組建一個複製+自動分片+failover的環境,文件化的儲存也簡化了傳統設計庫 結構再開發的模式。
很多業務是可以用這類資料庫來替代mysql的。
八、快取。
資料庫很脆弱,一定要有快取在前面擋著,其實我們優化速度,幾乎就是優化快取,能用快取的地方,就不要再跑到後端資料庫那折騰。
快取有持久化快取、 記憶體快取,生成靜態頁面是最容易理解的持久化快取了,還有很多比如varnish的分塊快取、前面提到的memcachedb等,
記憶體緩 存,memcached、redis首當其衝。快取更新可用被動更新和主動更新。被動更新的好處是設計簡單,快取空了就自動去資料庫取資料再把快取填上,
但容易引發雪崩效應,一旦快取大面積失效,資料庫的壓力直線上升很可能掛掉。主動快取可避免這點但是可能引發程式取不到資料的問題。
這兩者之間如何配合,程式設計要多 動腦筋。
九、佇列。
使用者一個操作很可能引發一系列資源和功能的調動,這些調動如果同時發生,壓力無法控制,使用者體驗也不好,可以把這樣一些操作放入佇列,
由另幾個模組 去非同步執行,例如傳送郵件,傳送手機簡訊。開源佇列伺服器很多,效能要求不高用資料庫當做佇列也可以,
只要保證程式讀寫佇列的介面不變,底層佇列服務可隨 時更換就可以,類似Zend Framework裡的Zend_Queue類,java.util.Queue介面等。
十、檔案儲存。
除了結構化資料,我們經常要存放其他的資料,像圖片之類的。這類資料數量繁多、訪問量大。
典型的就是圖片,從使用者頭像到使用者上傳的照片,還要生成不 同的縮圖尺寸。儲存的分佈幾乎跟資料庫擴充套件一樣艱難。
不使用專業儲存的情況下,基本都是靠自己的NAS。這就涉及到結構。拿圖片儲存舉例,圖片是非常容 易產生熱點的,
有些圖片上傳後就不再有人看,有些可能每天被訪問數十萬次,而且大量小檔案的非同步備份也很耗費時間。
為了將來圖片走cdn做準備,一開始最好就將圖片的域名分開,且不用主域名。很多網站都將cookie設定到了.domain.ltd,
如果圖片也在這個域名下,很可能因為cookie而造成快取失效,並且佔多餘流量,還可能因為瀏覽器併發執行緒限制造成訪問緩慢。
如果用普通的檔案系統儲存圖片,有一個簡單的方法。計算檔案的hash值,比如md5,以結果第一位作為第一級目錄,這樣第一級有16個目錄。
從0 到F,可以把這個字母作為域名,0.yourimg.com到f.yourimg.com(客戶端dns壓力會增大),還可以擴充套件到最多16個NAS叢集 上。
第二級可用年月例如,201011,第三級用日,第四級可選,根據上傳量,比如am/pm,甚至小時。最終的目錄結構可能會是 e/201008/25/am/e43ae391c839d82801920cf.jpg。rsync備份時可以用指令碼只同步某年某日某時的檔案,避免計 算大量檔案帶來的開銷。
當然最好是能用專門的分散式檔案系統或更專業點的儲存解決方案。