1. 程式人生 > >app後端架構

app後端架構

(1)Restful設計原則

    Restful風格:RESTfu設計原則,它被Roy Felding提出(在他的”基於網路的軟體架構“論文中第五章)。而REST的核心原則是將你的API拆分為邏輯上的資源。這些資源通過http被操作(GET ,POST,PUT,DELETE)。

       但現在看,一般的操作只有兩種:GET ,POST。

    這個設計原則最簡單的應用就是根據object而不是頁面來設計api。最開始的時候,app的一個頁面需要什麼資料,api就返回什麼資料。結果隨著app的UI不斷改版,需要的資料不斷變化,不停地修改api,最後當api的改動會影響以前的版本的時候,只能寫一個新的api版本,最後弄得api中有很多_V2,V3這樣的標誌,惡夢!

    後來在網站的重構過程中,就根據object來設計api,但根據object來設計,又有一個問題,一個大object可能包含很多小object,是一個api返回全部小object,還是分為多個api返回?根據業務和技術,頻寬等仔細考慮吧。

(2) api的命名

    其中一個原則,一看api名字就知道這個api是幹啥。在創業團隊中,一般就只有一兩個人負責後臺,當你要負責幾十甚至上百個api,你就知道不能“望名知api”是個什麼樣的痛苦。

(4) api返回資料

    app客戶端的語言 java 和object-c都是強型別語言,所以怎麼處理空值顯得特別重要,不合理的設計很容易造成app的閃退。

    從後臺的角度來說,api中返回的資料中,正確值和空值的型別必須一樣,舉例,使用者名稱的欄位是“realname": "xxx”,如果使用者名稱為空,則應該返回“realname": ""。如果返回值是一個array,空資料則返回一個空array,絕對禁止null值。

    對於客戶端,必須用個全域性的函式來處理所有api的返回資料,需要有一個機制:對於某個客戶端需要資料,如果api中缺失,客戶端自動補上並給予預設值。這個機制在我們的實踐中大大減少了app的閃退。

    同時,在資料庫設計的時候,一個合理的設計必須是所有欄位都有預設值,不應該允許null值。null在大量的語言和資料庫中,會帶來無窮的問題。對於這個資料庫設計原則,我以前不太明白,現在經歷了一年的api設計後,終於懂得。

    如果客戶端是php,還有一個問題,php中陣列和字典都是array,但在java 和object-c中是不一樣,這個問題一定要注意。

(5)圖片的處理

    在不同版本的app中,各種不同尺寸的手機中,同一張圖片顯示的尺寸可能是不一樣,如果每次都需要用返回原圖,然後在客戶端處理,則極大浪費網路資源。而如果是後臺處理好圖片才返回,則又是一個挑戰,怎麼有效儲存和裁剪多種圖片尺寸呢

    例如,一開始頭像只需要返回60*60的尺寸,後來在新的版本需要返回70*70, 又出了一個新版本,需要返回80*80, 每次增加一個新的尺寸,怎麼在資料庫上記錄下來。這個問題在一開始做api的時候沒考慮,後來不得不用了一個極端的方法,沒增加新的圖片尺寸,就在資料庫中增加一個新的欄位,儲存並生成新的圖片尺寸,結果最後資料庫的頭像欄位有"avatar","avatar_60_60","avatar_70_70","avatar_80_80",這種極度惡虐的設計。

    最後,針對圖片,我們才用了這樣的策略:

(1)客戶端本地快取圖片,只有沒有合適的圖片,才去伺服器取。

(2)當客戶端需要某種尺寸的圖片,由客戶端告訴服務端圖片的尺寸,服務端動態生成並快取起來。

     例如,客戶端需要圖片(http://www.baidu.com/img/bdlogo.gif)的80*80的尺寸,則在圖片的路徑加上寬和高的引數(類似於CDN的機制) http://www.baidu.com/img/bdlogo.gif?w=80&h=80, 則伺服器就生成80*80的尺寸並返回。

    採用了這樣的圖片處理機制,資料庫中只要有一個欄位儲存原圖就行了,其它尺寸就由客戶端告訴服務端動態生成。以後無論什麼尺寸的圖片,資料庫中都不需要記錄,資料庫只有原圖就行了。

(6)返回的提示資訊

   最科學的情況,服務端只返回資訊程式碼,具體的文字提示由客戶端決定。

    如果文字資訊是由服務端返回,則最起碼要區分2種資訊:提示使用者的資訊,提示客戶端程式設計師的資訊。這兩者的區別:

1.提示使用者的資訊是要在讓客戶知道的,提示客戶端程式設計師的資訊不需要讓客戶知道的。

2. 提示使用者的資訊文字很友好,客戶不需要專業基礎一看就知道是什麼,提示客戶端程式設計師的資訊則很專業,例如告訴客戶端少傳了哪個引數?哪個引數有問題等等。

(7)線上api文件和測試

    我們網站的api線上測試文件,既是一份線上api文件,也是一個線上測試工具,極大方便溝通和測試。每次客戶端程式設計師覺得某個api有什麼問題,我們就是這個線上工具上討論溝通的。客戶端程式設計師最喜歡這個玩意了^-^。

    上個圖解一下饞(這個圖是舊版的api,已經棄用了):

負責做這個功能的同事專門寫了篇部落格詳細介紹了這個線上api測試文件,還帶有demo:

----------------------------------------------------------------------------------------------------------

   個人認為,在小型的創業團隊中,特別是以應用產品為主,在架構後臺的時候,需要集中精力解決自身業務上的問題,不是花時間解決第三方已經解決的問題,簡單點來說,就是能用第三方服務就使用第三方的服務。基於這個原則,就有了下面的系統架構:

1. apns:由於在apns中,無效的token會導致連線apns連線的失效從而使apns資訊丟失。解決的方案是維護髮送佇列,當apns伺服器返回錯誤的token後,把這個錯誤token後的訊息重發。第三方推送很好了實現了這個技術方案,我們選擇了百度雲推送。

2. email:要考慮郵件傳送失敗的重發問題,所以不再在伺服器上搭建sendmail服務傳送,選擇了郵件服務商mailgun。mailgun還提供每個賬號每月1萬封郵件的免費額度,很適合創業團隊。

3. coreseek: 一個基於Sphinx的全文檢索引擎。在前面描述的LBS模組中,和檢索使用者暱稱,商鋪等搜尋功能上需要用到。

4. redis:一個支援多種資料結構的key-value資料庫,在LBS模組,效能優化等多個方面都有廣泛的用處。

5. httpsqs:輕量級的訊息佇列。

6. xmpp:採用了開源的openfire,當web服務需要向openfire通訊,有兩種情況:

(1)實時的需求,例如註冊的時候在聊天伺服器註冊一個使用者,那麼是直接連聊天伺服器。

(2)如果是其它非實時的需求,例如通過聊天伺服器向app傳送一個更新通知,那麼就在佇列中處理。

7. 監控,採用了監控寶和雲伺服器提供的監控資料,能滿足目前的需求了。

參考: