
本書(shū)講了什么
通過(guò)闡述移動(dòng)互聯(lián)網(wǎng)中App后臺(tái)開(kāi)發(fā)的特點(diǎn),梳理了App后臺(tái)開(kāi)發(fā)中會(huì)遇到的各個(gè)技術(shù)點(diǎn),給出了生產(chǎn)環(huán)境常用軟件的實(shí)戰(zhàn)運(yùn)維經(jīng)驗(yàn)總結(jié)。
作者什么來(lái)頭
當(dāng)當(dāng)沒(méi)寫(xiě),我也懶得查。 曾健生
第1章 App后臺(tái)入門(mén)
App后臺(tái)的功能
遠(yuǎn)程存儲(chǔ)數(shù)據(jù)。
消息中轉(zhuǎn)。
App后臺(tái)架構(gòu)
梳理APP業(yè)務(wù)流程。
整理每個(gè)流程會(huì)遇到的問(wèn)題。
根據(jù)問(wèn)題,探討可行的技術(shù)方案。
有機(jī)融合這些方案,就是初步的架構(gòu)。
架構(gòu)設(shè)計(jì)的特點(diǎn)
架構(gòu)是和業(yè)務(wù)緊密相關(guān)。業(yè)務(wù)不同,解決方案也不同,架構(gòu)就不同。
架構(gòu)的演變是業(yè)務(wù)上的驅(qū)動(dòng),APP處于不同發(fā)展階段,架構(gòu)上也需變化。
架構(gòu)不是為了炫耀技術(shù),是為了滿足業(yè)務(wù)需要,不應(yīng)過(guò)度設(shè)計(jì)。
App和App后臺(tái)的通信
1.用HTTP協(xié)議還是私有協(xié)議?
APP與后臺(tái)通信分為使用通用語(yǔ)言和使用暗語(yǔ)兩種方式。協(xié)議就相當(dāng)于一套語(yǔ)言,雙方都知道每個(gè)字節(jié)的具體含義。HTTP協(xié)議是使用的最廣泛的協(xié)議。大多數(shù)開(kāi)發(fā)語(yǔ)言都支持通用協(xié)議,有大量成熟模塊供程序員調(diào)用,方便程序員解析這些通用協(xié)議的內(nèi)容。
使用私有協(xié)議相當(dāng)于使用暗語(yǔ),類似于開(kāi)發(fā)一種新的語(yǔ)言。私有協(xié)議對(duì)協(xié)議的封裝和拆解工作量大,APP程序員和后臺(tái)程序員都要增加額外的工作量,且私有協(xié)議對(duì)程序員的設(shè)計(jì)能力要求高。除非開(kāi)發(fā)者對(duì)APP的安全性和性能要求高,不然選擇HTTP協(xié)議就足夠。
2.APP和后臺(tái)通信使用長(zhǎng)連接還是短連接?
可以用打電話的模型理解:是一致保持通話,還是有需要才撥號(hào)通話。長(zhǎng)連接就相當(dāng)于一直保持通話,服務(wù)器能保持的通信數(shù)量有限,如果達(dá)到數(shù)量極限,需要增加服務(wù)器。這種通信方式多數(shù)是使用Socket和WebSocket連接長(zhǎng)時(shí)間連接,對(duì)程序員素質(zhì)要求高,開(kāi)發(fā)困難,除了手游和聊天推送外,不建議使用。當(dāng)APP和服務(wù)器使用短連接,主要使用HTTP協(xié)議,開(kāi)發(fā)效率高,推薦使用。
3.APP和后端是怎么通信的?
APP后臺(tái)只提供了一系列功能給APP使用,這些功能以API的形式提供。API(應(yīng)用程序編程接口)是一些預(yù)先定義的函數(shù),目的是提供應(yīng)用程序與開(kāi)發(fā)人員基于某軟件或硬件得以訪問(wèn)一組例程的能力,而又無(wú)需訪問(wèn)源碼,或理解內(nèi)部工作機(jī)制的細(xì)節(jié)。
當(dāng)APP調(diào)用API時(shí),需要明確:
API的用途。比如用取款器取款、查余額。
輸入什么。比如取款需要輸入金額。
結(jié)果是什么。比如取款成功還是失敗。
4.后端是返回給API的數(shù)據(jù)格式
API一般是以HTTP的形式調(diào)用的,通過(guò)HTTP傳入?yún)?shù)返回?cái)?shù)據(jù)。JSON是一種輕量級(jí)數(shù)據(jù)交換格式,比XML更省流。{“age”:11,“name”:“jeff”}
APP和后臺(tái)通訊過(guò)程

選擇服務(wù)器
如果出現(xiàn)了APP訪問(wèn)量爆發(fā)的情況,解決訪問(wèn)壓力最快的方式就是升級(jí)服務(wù)器的硬件。使用云服務(wù)升級(jí)硬件很簡(jiǎn)單:選擇硬件配置;付款;重啟服務(wù)器。上線初期一般都在一臺(tái)服務(wù)器上搭建所有服務(wù),隨著APP的發(fā)展,這些服務(wù)需要部署在不同的服務(wù)器上。
選擇編程語(yǔ)言
選擇符合業(yè)務(wù)場(chǎng)景的最熱門(mén)的變成語(yǔ)言。
1.每種編程語(yǔ)言都有自己擅長(zhǎng)的業(yè)務(wù)場(chǎng)景和性能特性。
2.選擇開(kāi)發(fā)效率最高的編程語(yǔ)言。
3.忌諱用兩套不同的語(yǔ)言維護(hù)同一個(gè)業(yè)務(wù)邏輯。
4.一個(gè)系統(tǒng)中,不同的業(yè)務(wù)邏輯可以用不同的編程語(yǔ)言實(shí)現(xiàn)。
研發(fā)階段
Android和iOS工程師先設(shè)計(jì)前端架構(gòu),或先做界面。后端架構(gòu)設(shè)計(jì)完成后,通過(guò)三點(diǎn)初步設(shè)定API接口:API是有什么用?API的輸入函數(shù)是什么?API返回什么數(shù)據(jù)?后臺(tái)工程師向前端說(shuō)明API接口,初期API不用實(shí)現(xiàn)功能,返回假數(shù)據(jù),后期慢慢實(shí)現(xiàn)。
最適合App的開(kāi)發(fā)模式——敏捷開(kāi)發(fā)
略,近期=找本敏捷的書(shū)學(xué)習(xí)下。
每日例會(huì)
昨天完成了哪些任務(wù)?
每個(gè)任務(wù)用了多少時(shí)間?
沒(méi)完成的任務(wù)還要多少時(shí)間?
今天準(zhǔn)備做哪些工作?
有什么工作需要其他同事配合?
回顧會(huì)議
這輪迭代做的好的和不好的地方。
第2章 App后臺(tái)基礎(chǔ)技術(shù)
從App業(yè)務(wù)邏輯中提煉API接口步驟:
業(yè)務(wù)邏輯思維導(dǎo)圖。
功能—業(yè)務(wù)邏輯思維導(dǎo)圖。
基本功能關(guān)系模塊。
功能模塊接口UML(設(shè)計(jì)出API)。
在設(shè)計(jì)稿標(biāo)注API。
編寫(xiě)API文檔。
業(yè)務(wù)邏輯思維導(dǎo)圖
用思維導(dǎo)圖把結(jié)構(gòu)關(guān)系列出來(lái),包括里面的功能。把相同的元素整理出來(lái),比如都是相同的推送、評(píng)論、圖片上傳,然后用相同顏色表示出來(lái)。
功能—業(yè)務(wù)邏輯思維導(dǎo)圖
MVC,寫(xiě)一個(gè)model的名字出來(lái),開(kāi)發(fā)人員能夠把業(yè)務(wù)邏輯里面的東西和其關(guān)聯(lián)。簡(jiǎn)單說(shuō)就是一對(duì)多,一就是model,多就是業(yè)務(wù)邏輯,一個(gè)model對(duì)應(yīng)多個(gè)業(yè)務(wù)邏輯。先做最上限的一層,盡可能多的進(jìn)行一對(duì)多的分析,然后按照最小獨(dú)立原則,看這個(gè)是不是一個(gè)最小的系統(tǒng),按設(shè)計(jì)原理:每個(gè)model都是一個(gè)可獨(dú)立運(yùn)行的模塊,也就是說(shuō)model和model之間是沒(méi)關(guān)系的。在思維導(dǎo)圖中,其實(shí)就是業(yè)務(wù)邏輯和功能模塊的結(jié)合。
劃分功能模塊依據(jù)三個(gè)原則:
功能模塊和業(yè)務(wù)邏輯之間的關(guān)系。
功能模塊和功能模塊之間不能有關(guān)系。
功能模塊要盡可能的實(shí)現(xiàn)一堆多(一個(gè)功能模塊對(duì)應(yīng)多個(gè)業(yè)務(wù)邏輯)。
基本功能模塊關(guān)系
現(xiàn)在要做第三個(gè)圖,步驟是從業(yè)務(wù)邏輯進(jìn)入功能模塊,功能模塊按人和事來(lái)分。
人有哪些功能模塊?
事有哪些功能模塊?
人和事之間的關(guān)系又有哪些功能模塊?
功能模塊接口UML(設(shè)計(jì)出API)
現(xiàn)在只考慮功能模塊,做功能模塊的UML圖,要設(shè)計(jì)哪些接口去解決哪些問(wèn)題。接口是基于現(xiàn)在的模塊、粗略的模塊?;诂F(xiàn)在的模塊設(shè)計(jì)接口,就是要提高耦合度,確保耦合正確。
編寫(xiě)在線API測(cè)試文檔
API在線測(cè)試文檔使用Swagger-UI搭建。
設(shè)計(jì)稿標(biāo)注API
后臺(tái)開(kāi)發(fā)在設(shè)計(jì)搞上標(biāo)注出哪個(gè)界面調(diào)用哪個(gè)API。
設(shè)計(jì)API的要點(diǎn)
根據(jù)對(duì)象而不是頁(yè)面設(shè)計(jì)API。
API命名簡(jiǎn)單易懂。
API安全性。
API所返回的數(shù)據(jù)。API返回的數(shù)據(jù)中正確值和空值的類型必須一樣。數(shù)據(jù)庫(kù)設(shè)計(jì)得時(shí)候,合理的設(shè)計(jì)原則是所有字段都有默認(rèn)值,不允許Null值。
圖片的處理。APP本地緩存圖片,緩存圖片不存在時(shí)才請(qǐng)求服務(wù)器API。當(dāng)APP需要某種尺寸的圖片,由APP通知服務(wù)器所需圖片的尺寸,服務(wù)端動(dòng)態(tài)生成并緩存。
返回的提示信息。APP后臺(tái)只返回信息代碼,具體文字APP決定。
在線API測(cè)試文檔。
APP啟動(dòng)時(shí)調(diào)用一個(gè)API獲取必要的初始化信息。
API版本升級(jí)需要注意:V2版本的Controller必須繼承V1版的Controller,這樣V2版本的API只重寫(xiě)需要改動(dòng)的API。
如何選擇合適的數(shù)據(jù)庫(kù)產(chǎn)品
Redis,MongoDB,MySQL讀寫(xiě)數(shù)據(jù)的區(qū)別
Redis的數(shù)據(jù)存放在服務(wù)器的內(nèi)存,內(nèi)存滿了需要擴(kuò)容,只能使用Redits的分布式方案。
MongoDB同時(shí)使用硬盤(pán)和內(nèi)容,使用MMAP機(jī)制進(jìn)行數(shù)據(jù)文件讀寫(xiě),可以直接把文件映射到進(jìn)程的內(nèi)存空間中,這樣文件在內(nèi)存中有對(duì)應(yīng)的地址,對(duì)文件的讀寫(xiě)是能通過(guò)操作內(nèi)存進(jìn)行的。
MySQL數(shù)據(jù)存放在硬盤(pán)中,緩存的是查詢結(jié)果而不是緩存數(shù)據(jù)。
Redis,MongoDB,MySQL查找數(shù)據(jù)的區(qū)別
Redis的數(shù)據(jù)是基于“鍵值對(duì)”存儲(chǔ),鍵相當(dāng)于門(mén)牌號(hào),值相當(dāng)于房間,Redis查找數(shù)據(jù)每次都是直奔目標(biāo),讀寫(xiě)速度快。
MongoDB和MySQL中,沒(méi)組數(shù)都有一個(gè)id(或?yàn)槊拷M數(shù)據(jù)建立索引),這個(gè)id和索引就相當(dāng)于門(mén)牌號(hào)。
MongoDB和MySQL中查找數(shù)據(jù)有兩種模式:知道id或索引,不知道id或索引。不知道的時(shí)候就要遍歷。
Redis,MongoDB,MySQL適用場(chǎng)景(略)
消息隊(duì)列的工作流程

巨無(wú)霸系統(tǒng)的危害
隨著業(yè)務(wù)不斷增加,后臺(tái)系統(tǒng)由一個(gè)單一的應(yīng)用膨脹為巨無(wú)霸系統(tǒng),具體表現(xiàn)為系統(tǒng)中聚合了大量的應(yīng)用和服務(wù),各模塊之間有很多功能重復(fù)實(shí)現(xiàn),造成了開(kāi)發(fā)、運(yùn)維、部署上的麻煩。

遠(yuǎn)程服務(wù)的優(yōu)點(diǎn)
解決上述問(wèn)題的方法是把重復(fù)實(shí)現(xiàn)的模塊獨(dú)立部署為遠(yuǎn)程服務(wù),新增的業(yè)務(wù)調(diào)用遠(yuǎn)程服務(wù)所提供的功能實(shí)現(xiàn)相關(guān)業(yè)務(wù),不依賴于里面具體的代碼實(shí)現(xiàn)。下圖為把登錄模塊部署為一個(gè)遠(yuǎn)程服務(wù)。遠(yuǎn)程服務(wù)的實(shí)現(xiàn):REST/PRC/開(kāi)源PRC庫(kù)。

搜索技術(shù)的基本原理
如果知道每行數(shù)據(jù)中包含多少關(guān)鍵字,然后建立一個(gè)映射表,把每個(gè)關(guān)鍵字出現(xiàn)在哪行數(shù)據(jù)中記錄下來(lái),搜索就不用遍歷。當(dāng)知道關(guān)鍵字,只需要查找映射表,找到關(guān)鍵詞,根據(jù)關(guān)鍵詞建立的映射關(guān)系就能查到包含這個(gè)關(guān)鍵詞的數(shù)據(jù)。知道每行數(shù)據(jù)中包含多少個(gè)關(guān)鍵字的過(guò)程,就是分詞。常見(jiàn)開(kāi)源搜索軟件:Lucene/Solr/ElasticSearch/Sphnix/CoreSeek
定時(shí)任務(wù)
APP后臺(tái)開(kāi)發(fā)經(jīng)常需要執(zhí)行一些定時(shí)任務(wù),如定期清理垃圾文件等。
第3章 App后臺(tái)核心技術(shù)
用戶驗(yàn)證方案
使用HTTPS協(xié)議
HTTPS基于HTTP開(kāi)發(fā),用于在客戶計(jì)算機(jī)和APP后臺(tái)之間交換信息。其使用安全套接字層(SSL)進(jìn)行信息交換,簡(jiǎn)單來(lái)說(shuō)其是HTTP的安全版。HTTPS實(shí)際上使用了安全套接字層(SSL)作為HTTP應(yīng)用層的子層。
基本的用戶登錄方案

URL簽名

AES對(duì)稱加密(略)
App后臺(tái)發(fā)送短信簡(jiǎn)介

發(fā)送手機(jī)短信要通過(guò)運(yùn)營(yíng)商的短信通道,但通道費(fèi)用過(guò)高,進(jìn)而催生了短信平臺(tái)。短信平臺(tái)購(gòu)買了運(yùn)營(yíng)商的短信通道后,把一個(gè)通道給一批企業(yè)共同使用,讓企業(yè)按發(fā)送短信數(shù)量付費(fèi),從而降低了企業(yè)發(fā)送短信的成本,同時(shí)短信平臺(tái)也初步審核短信內(nèi)容,避免出發(fā)短信通道的使用限制。APP后臺(tái)購(gòu)買了短信平臺(tái)的短信服務(wù)后,就能通過(guò)短信平臺(tái)的API接口發(fā)送短信。
內(nèi)容的推拉
如果APP要知道首頁(yè)是否有內(nèi)容更新,通過(guò)輪詢機(jī)制訪問(wèn)獲取API,從API是否返回更新的數(shù)據(jù)得知是否有內(nèi)容更新。輪詢即每隔一段時(shí)間,APP向后臺(tái)發(fā)送請(qǐng)求獲取是數(shù)據(jù)。缺點(diǎn):耗電、耗流量。

推模式的流程
不能只用推模式,手機(jī)網(wǎng)絡(luò)環(huán)境的復(fù)雜性,不能保證數(shù)據(jù)更新的通知一定能到達(dá)APP,所以也要采用輪訓(xùn)的方式定期拉數(shù)據(jù),使用推拉結(jié)合時(shí)輪詢的時(shí)間間隔可以設(shè)置的比較長(zhǎng)。

文件系統(tǒng)
盡量使用成熟可靠的云服務(wù)和開(kāi)源軟件,自身只專注于業(yè)務(wù)邏輯。
第4章 Linux-App后臺(tái)應(yīng)用最廣泛的系統(tǒng)
后臺(tái)開(kāi)發(fā)需要兼顧開(kāi)發(fā)與運(yùn)維兩方面,現(xiàn)在的APP服務(wù)器大多是運(yùn)行在Linux系統(tǒng),因此開(kāi)發(fā)工作中設(shè)計(jì)大量Linux的運(yùn)維操作。具體操作不看了。
第5章 Nginx-App后臺(tái)HTTP服務(wù)的利器
Nginx是一個(gè)高性能的HTTP和反向代理服務(wù)器,在BAT和眾多互聯(lián)網(wǎng)公司有廣泛應(yīng)用,其主要特點(diǎn)是占用內(nèi)存少,并發(fā)能力強(qiáng)。略略略。
第6章 MySQL-App后臺(tái)最常用的數(shù)據(jù)庫(kù)

第7章 Redis-App后臺(tái)高性能的緩存系統(tǒng)
MySQL速寫(xiě)速度慢,隨著互聯(lián)網(wǎng)發(fā)展,越來(lái)越多業(yè)務(wù)場(chǎng)景需要滿足:少量數(shù)據(jù)需要經(jīng)常被讀寫(xiě),對(duì)速度要求高;能提供豐富的數(shù)據(jù)結(jié)構(gòu);提供數(shù)據(jù)落地的功能。Redis就死滿足上述需求的開(kāi)源Key-Value內(nèi)存存儲(chǔ)系統(tǒng)。
第8章 MongoDB——App后臺(tái)新興的數(shù)據(jù)庫(kù)
MongoDB是介于關(guān)系型數(shù)據(jù)庫(kù)和非關(guān)系型數(shù)據(jù)庫(kù)之間的產(chǎn)品,是非關(guān)系型數(shù)據(jù)庫(kù)當(dāng)中功能最豐富、最像關(guān)系型數(shù)據(jù)庫(kù)的數(shù)據(jù)庫(kù)。是由10gen公司基于C++編寫(xiě),知名IT公司使用其構(gòu)建自己的核心應(yīng)用的有eBay、Cisco、Adobe等。它的主要特點(diǎn):讀寫(xiě)性能高、靈活的文檔模型給開(kāi)發(fā)帶來(lái)的方便、水平擴(kuò)展機(jī)制能輕松應(yīng)對(duì)從百萬(wàn)到十億級(jí)別的數(shù)據(jù)處理。這也是MongoDB名字來(lái)源于單詞humongous的原因。
第9章 App后臺(tái)架構(gòu)剖析(略)
第10章 App后臺(tái)架構(gòu)的演進(jìn)
架構(gòu)的核心要素
高性能。
高可用。
可伸縮。
可擴(kuò)展。
安全性。
架構(gòu)的演進(jìn)
單機(jī)部署。
分布式部署。
服務(wù)化。
架構(gòu)的特點(diǎn)
每個(gè)App的后臺(tái)架構(gòu)不會(huì)完全一樣。
架構(gòu)的演進(jìn)是由業(yè)務(wù)驅(qū)動(dòng)的。
架構(gòu)不是為了炫耀技術(shù)。