服務端開發,特別是Web開發,基本上全是處理HTTP請求的處理。根據具體用途分爲兩種:Web頁面開發和API接口開發。Web頁面開發也徹底能夠當作是API接口開發,只是它的兩個主要部分,頁面和ajax請求,一個是返回html,另一個能夠返回html,也能夠返回其餘格式的而已。API接口開發是針對有客戶端產品而言的。多是移動設備,多是PC應用等。html
應用框架
應用框架通常使用的是LNMP或者LAMP,基本的框架就是前端N臺Web服務機 + cgi訪問PHP + php訪問mysql。前端
PHP能夠當作是C寫的一個大型的Web框架,它的優點在於解釋型,即時修改即時更新。因此線上代碼更新維護成本極低,加之其爲web開發幾乎是專門定製的一些函數,因此適合用於web開發。相較於java開發web服務,動不動就須要從新編譯的痛苦就很滿足了。java
web服務器如今nginx是愈來愈多使用,nginx比較apache的優點就在於輕便和靜態頁面的高併發性能。通常拿到設備先須要考慮下單機可承受的qps大概多少,方法大體就是先只考慮內存,計算同時能開啓多少個php-cgi,好比一個4G內存的機器,每一個php-fpm大概佔用20M內存,因此差很少能開啓200個php-cgi進程(通常會留些空餘的),每一個進程同一個時間只能跑一個php程序,因此假設每一個php程序跑0.1s,1s就能處理10個請求,因此單機qps大概會是2000。固然,通常不會開啓到這麼極致的程度,有幾個緣由:mysql
1 須要考慮到其餘進程使用內存的狀況nginx
2 考慮到若是一旦所有內存都使用完了,是否啓用swap,若是沒有的話,那機器是否就當即當機web
3 還須要考慮到CPU和帶寬的使用狀況。CPU對一些好比加解密,視頻轉碼等操做比較耗時,這個時候若是沒有使用隊列,那麼每一個請求的時間就會加長。ajax
文件服務器
通常會要求文件服務器和web服務器分開,分開的意思就是使用不一樣的域名進行拆分。固然web服務器也是能夠當作文件服務器的,可是因爲文件服務器須要上傳文件,而上傳文件是一個很是耗時的工做,即php的一個程序須要停留的時間很長,因此須要將它們分開。一則能夠爲之後擴展文件服務器提供便利,二則不會致使文件服務影響了正常的web服務。redis
從文件服務器拆分的理由上看,在運營過程當中一些比較佔用資源或者特別頻繁調用的接口是能夠或者應該考慮拆分到不一樣機器上的。算法
Web前端機始終要訪問持久化的數據的,mysql的使用是最爲頻繁的。其實全部的web服務說到底都是對數據庫進行增刪改查的操做。說到性能,數據庫的增刪改查操做的性能其實就決定了一切。因此對數據庫的建表,索引的使用對一個網站來講尤其重要。以爲最有用的幾個mysql的技巧有:
1 覆蓋索引。就是想辦法讓查詢操做只查索引而不去查表的索引創建方法。創建合適的索引和能只在索引就能找到數據的查詢能提升效率。
2 InnoDB表最好能使用自增鍵,提升插入操做的效率。
3 string類型的變量的存儲格式,是使用varchar仍是char比較好,曾經有個項目表設計從char到varchar以後的數據庫大小差異達到70G和20G的大小…
4 建表的時候須要考慮下之後的分庫分表,若是是使用分表,什麼是分表鍵?是否須要反向查詢表?
5 甚至當考慮到數據庫和Web機器的機房分佈,這個設計就更麻煩了...
mysql的建表環節和需求有很大關係。沒有明確的需求,表設計必定是不正確的。
數據庫支持有可能仍是不足夠的,那麼首先想到的可能就是緩存了。緩存是使用全局緩存?放在web前端機?須要用什麼hash算法?用什麼緩存?memcache?redis?mysql也有自帶緩存,如何查詢才能更好命中這個緩存?當數據更新的時候,緩存中的數據是不是髒數據?如何更新數據?
Web頁面開發
當須要作一個網站的時候,首先要考慮的是用戶量有多少?作一個SNS網站和作一個運營後臺網站徹底是兩個不一樣的概念。
首先是在頁面壓力上,SNS網站的qps可能幾千上萬,而運營後臺壓力幾乎徹底能夠不用計算。這個就意味着後端的數據庫支持不一樣了。SNS網站可能最常調用的會是好友關係和我的信息的接口,這樣的接口是否是須要獨立出來處理?這樣的請求會不少是重複的,是否是考慮使用中間件或者緩存來減輕對數據庫的直接壓力呢?運營數據通常使用單表就能夠解決的。我的以爲運營中統計的需求是最難作的。首先統計並非任意的統計要求均可以知足,這個須要和產品討論需求。其次,統計通常須要使用些訪問日誌之類的,可能涉及到許多shell腳本。
API開發
其實相對於Web開發,API開發是屬於被動的。意思就是,因爲客戶端多是手機產品,多是PC產品。每每都是有發佈和版本的。這個意味着API接口無法像Web那樣隨心所欲隨時更新代碼。它更多須要考慮到各個版本之間的兼容問題。兼容問題在很大程度上會變爲加法,永遠不會是減法。我的感受,若是毫無節制地知足需求,隨着版本愈來愈多,你的代碼中會愈來愈多if else,到最後,你的代碼就根本沒法維護了。而後就會是別人來接手你的工做,踩坑,邊罵邊重構….API開發是最須要依賴測試的。每每只有測試人員纔對各個版本的小改動,小特性如數家珍。
再考慮到非功能配套:
你可能須要對API調用時間進行統計,這樣你才明白你的接口表現如何。
你的代碼可能還會用到其餘機器上的服務,好比curl一個其餘服務,這樣的狀況,最好考慮下錯誤處理和日誌記錄。
對於有金錢交易的接口服務,日誌處理更是必不可少。
對於一些內部錯誤,最好不須要直接拋出顯示給用戶,因此須要使用的最好是白名單錯誤機制。
接口的加密方式,通常最少是須要有個簽名機制的,考慮到加密方法,大體有幾種:對稱加密和非對稱加密。加密的時候就須要考慮到一些狀況了,好比手機客戶端的用電量等。
若是是給手機開發接口,須要考慮流量問題,圖片的規格問題。
框架永遠是會變的,不說需求的變化,單就用戶量的變化,20w用戶和1000w用戶的框架必定是不同的。剛開始的時候你不可能根據1000w的用戶量來設計框架來給20w人用。因此一個好的服務端框架必定是隨着用戶量變化會進行幾回大的變化的。
…
後記
這篇是想到哪寫到哪,寫到這裏發現寫不下去了…總之,web服務開發的技巧和小東西仍是不少的。有的坑是須要本身踩過才知道痛的。可愛的是,我還在繼續踩坑中…
補充下,接口重構幾乎是每一個服務端開發人員必須經歷過的。相較於開發一個新系統,接口重構的難度能夠說是翻翻,固然這裏的難度也能夠理解爲難受程度…也會是很鍛鍊人的一個活。對於重構來講,測試尤其重要,如何有個很好的測試集來保證你的重構的正確性是個難度。