天天看點

App 背景架構設計方案 設計思想與最佳實踐App 背景架構設計方案 設計思想與最佳實踐1.靈活開發模式2.選擇合适的資料庫産品和伺服器系統3.選擇合适的消息隊列軟體4.使用分布式服務實作業務的複用5.使用者驗證方案最佳實踐6.App背景架構的演進原則7.社交App背景架構設計方案分享8.其他的一些經驗

App 背景架構設計方案 設計思想與最佳實踐

轉載請注明出處:http://blog.csdn.net/smartbetter/article/details/53933096

做App做的久了,就想研究一下與之相關的App背景,發現也是蠻有趣的。App背景的兩個重要作用就是 遠端存儲資料 和 消息中轉。這裡面的知識體系也是相當複雜,做好一個App背景也是需要長期錘煉的。本篇文章從 App 背景架構 的角度介紹。好了,下面進入正題:

說起架構,我們先看一下何為架構,百度百科是這樣說的:架構,又名軟體架構,是有關軟體整體結構與元件的抽象描述,用于指導大型軟體系統各個方面的設計。那麼我們也可以看出,架構是和業務緊密相關的,是由業務驅動的。

由于App用戶端的特性,是以App背景對技術實作和一般的Web背景是有差別的。首先看一個适合App開發的開發模式:

1.靈活開發模式

這裡推薦Scrum這個靈活開發架構,具體可以檢視Scrum官網學習使用,這裡隻是引入。

Scrum流程如下圖:

App 背景架構設計方案 設計思想與最佳實踐App 背景架構設計方案 設計思想與最佳實踐1.靈活開發模式2.選擇合适的資料庫産品和伺服器系統3.選擇合适的消息隊列軟體4.使用分布式服務實作業務的複用5.使用者驗證方案最佳實踐6.App背景架構的演進原則7.社交App背景架構設計方案分享8.其他的一些經驗

2.選擇合适的資料庫産品和伺服器系統

資料庫産品衆多,這裡我就針對Redis、MongoDB、MySQL還有MySQL的分支MariaDB展開說明:

1.資料庫産品

資料庫 資料存放位置 查找資料的差別
Redis 記憶體 基于鍵值對存儲,讀寫速度快
MongoDB 同時使用了硬碟和記憶體 每個資料有一個id(索引),知道id(索引)查詢速度快,不知道id(索引)效率低
MySQL(MongoDB) 硬碟 每個資料有一個id(索引),知道id(索引)查詢速度快,不知道id(索引)效率低

然後根據不同的産品需求選擇恰當的資料庫産品,如果沒有特殊的需求,Redis做緩存系統,MySQL 或 MariaDB 做資料庫(常見的設定是 資料庫預設字元集utf8,預設排序utf8_general_ci) 将會是很好的選擇。

軟體優化:

1)正确使用MyISAM和InnoDB存儲引擎

2)正确使用索引

3)避免使用 select *

4)字段盡可能的設定 非NULL

硬體優化:

1)增加實體記憶體

2)增加應用緩存

3)使用SSD硬碟

架構優化:

1)分表

2)讀寫分離

App 背景架構設計方案 設計思想與最佳實踐App 背景架構設計方案 設計思想與最佳實踐1.靈活開發模式2.選擇合适的資料庫産品和伺服器系統3.選擇合适的消息隊列軟體4.使用分布式服務實作業務的複用5.使用者驗證方案最佳實踐6.App背景架構的演進原則7.社交App背景架構設計方案分享8.其他的一些經驗
  1. 分庫(把一張表的資料分别存儲在不同的資料庫,可用MyCat實作,MyCat,關系型資料庫分布式處理軟體)。

  2. MyCat以代理伺服器的形式位于App伺服器和背景資料庫之間,

  3. 對外開放的接口是MySQL通信協定,将App伺服器傳過來的sql語句按照路由的規則拆解轉發到不同的背景資料庫,并把結果彙總傳回。

  4. MyCat部署模型如下:

App 背景架構設計方案 設計思想與最佳實踐App 背景架構設計方案 設計思想與最佳實踐1.靈活開發模式2.選擇合适的資料庫産品和伺服器系統3.選擇合适的消息隊列軟體4.使用分布式服務實作業務的複用5.使用者驗證方案最佳實踐6.App背景架構的演進原則7.社交App背景架構設計方案分享8.其他的一些經驗

2.伺服器系統

CentOS 則是一個不錯的選擇。關于伺服器的部署,我在之前已經介紹過了,位址如下:

Nginx + Tomcat 反向代理 負載均衡 叢集 部署指南 

http://blog.csdn.net/smartbetter/article/details/53535435

Nginx + Tomcat 反向代理 如何在高效的在一台伺服器部署多個站點 

http://blog.csdn.net/smartbetter/article/details/53615313

下面補充兩個常見的Linux指令:

  1. top 顯示系統資源情況

  2. netstat 檢視網絡相關資訊

3.選擇合适的消息隊列軟體

當背景系統發現完成某些小任務需要花費很多時間,而且遲點晚成也不影響整個任務的完成進度時,就會把這些小任務交給消息隊列。例如發送郵件、短信、推送消息等任務都非常适合在消息隊列中處理。

把這些任務放在消息隊列中,可加快App背景請求都響應時間。同時消息隊列也能把大量的并發請求變成串行的請求,來減輕伺服器的負擔。

常見的消息隊列軟體有:

消息隊列軟體 說明
RabbitMQ 重量級,适合企業級的開發,自帶Web監控界面,友善監控隊列的情況
Redis 輕量級,是一個key-value系統,但是也支援消息隊列這種資料結構,App背景中Redis被廣泛使用
ZeroMQ 号稱最快,尤其針對大吞吐量的需求場景
ActiveMQ Apache的一個子項目,能夠以代理人和點對點的技術實作隊列

4.使用分布式服務實作業務的複用

随着業務不斷增加,背景系統由一個單一應用膨脹為一個巨無霸系統,系統中聚合了大量的應用和服務,各個子產品之間有很多功能重複實作(例如登入子產品),造成了開發、運維、部署的麻煩。

App 背景架構設計方案 設計思想與最佳實踐App 背景架構設計方案 設計思想與最佳實踐1.靈活開發模式2.選擇合适的資料庫産品和伺服器系統3.選擇合适的消息隊列軟體4.使用分布式服務實作業務的複用5.使用者驗證方案最佳實踐6.App背景架構的演進原則7.社交App背景架構設計方案分享8.其他的一些經驗

大量應用中的重複子產品會帶來大量的通路,而每個應用與資料庫的連接配接,一般是使用資料庫的連接配接池,這個連接配接池的資源一般是不釋放且一直保留着。假設連接配接池中有10個連接配接,中一個數百的伺服器叢集中,就占用了資料庫1000個連接配接。資料庫中的每個連接配接都是十分珍貴的資源,在資源有限的情況下,這裡被占用了,其他能用的資源就少了。

解決這些問題的方法就是把重複實作的子產品獨立部署為遠端服務,新增的業務調用遠端服務所提供的功能實作相關的業務,不依賴于裡面具體的代碼實作。

App 背景架構設計方案 設計思想與最佳實踐App 背景架構設計方案 設計思想與最佳實踐1.靈活開發模式2.選擇合适的資料庫産品和伺服器系統3.選擇合适的消息隊列軟體4.使用分布式服務實作業務的複用5.使用者驗證方案最佳實踐6.App背景架構的演進原則7.社交App背景架構設計方案分享8.其他的一些經驗

實作遠端服務可以 參考 REST設計原則 和 RPC遠端調用協定。

開源的RPC庫有:

開源的RPC庫 說明
Hprose 輕量級、跨語言、跨平台、無侵入式、高性能動态遠端對象調用引擎庫
Dubbo 分布式服務架構,緻力于提供高性能和透明化的RPC遠端調用服務和SOA服務治理方案

5.使用者驗證方案最佳實踐

App操作中經常涉及使用者登入操作,登入就需要使用到使用者名和密碼,為了安全起見,在登入過程中暴漏密碼的次數越少越好。

1.使用HTTPS協定

HTTPS協定是 HTTP協定 和 SSL/TLS協定 的組合。其是一個安全通信通道,基于HTTP開發,用于在客戶計算機和App背景之間交換資訊。其使用安全套接字層(SSL)進行資訊交換,簡單來說就是HTTP的安全版。

HTTPS實際上應用了安全套接字層(SSL)作為HTTP應用層的子層。

HTTPS的模型:

HTTP
SSL/TLS(安全套接字層/傳輸層安全協定)
TCP
IP
網絡傳輸

避免資訊的洩漏,最基本的方案是所有涉及安全性的API請求都必須使用HTTPS協定。

2.選擇JSON作為資料交換格式

JSON是一種輕量級的資料交換格式,采用完全獨立于語言的文本格式,易于編寫,也易于機器解析和生成,而且對比XML更省流量,這些特性使得JSON成為理想的資料交換語言。

3.基本的使用者驗證方案

傳統Web網站使用Cookie+Session保持使用者的登入狀态,App背景則使用token進行驗證,流程如下:

App 背景架構設計方案 設計思想與最佳實踐App 背景架構設計方案 設計思想與最佳實踐1.靈活開發模式2.選擇合适的資料庫産品和伺服器系統3.選擇合适的消息隊列軟體4.使用分布式服務實作業務的複用5.使用者驗證方案最佳實踐6.App背景架構的演進原則7.社交App背景架構設計方案分享8.其他的一些經驗

此時App已經擷取到了token值,為了安全,我們不在網絡上傳輸token,而使用簽名校驗(這裡使用URL簽名)的方式,API請求加上URL簽名sign和使用者id後如下:

  1. test.com/user/update?uid=2&sign=3f1e736bc4ae958ae7e8500b45aefdbb&age=22

這樣,token就不需要附在URL上了。App背景簽名校驗流程如下:

App 背景架構設計方案 設計思想與最佳實踐App 背景架構設計方案 設計思想與最佳實踐1.靈活開發模式2.選擇合适的資料庫産品和伺服器系統3.選擇合适的消息隊列軟體4.使用分布式服務實作業務的複用5.使用者驗證方案最佳實踐6.App背景架構的演進原則7.社交App背景架構設計方案分享8.其他的一些經驗

還有的童鞋喜歡設定時間戳,這樣時間一長,URL就失效了,也是一種不錯的進一步的優化方案。

建議:為了保障資料安全,這裡建議 同時使用 HTTPS 和 簽名校驗。

6.App背景架構的演進原則

App背景的架構是由業務規模驅動而演進的,App背景是為業務服務的,App背景的價值在于能為業務提供其所需要的功能,不應過度設計。

從項目的角度,當App通路量不大時,應該快速搭建App背景,讓App盡快上線給使用者提供服務,驗證商業模式的正确性,同時快速疊代産品。

當App通路量不斷上升,這時要在保證快速疊代的前提下,同時兼顧高性能和高可用。

當App通路量達到一定階段後,增長曲線就會放緩,但業務變得更加複雜,對高性能和高可用的要求也更高,性能問題、子產品間的耦合、代碼的複雜性會更加突出和明顯,這時要使用業務拆分、分布式服務調用,甚至是技術轉型等問題。

1.項目啟動時——單機部署

我們看一個App背景極簡化的架構:

App 背景架構設計方案 設計思想與最佳實踐App 背景架構設計方案 設計思想與最佳實踐1.靈活開發模式2.選擇合适的資料庫産品和伺服器系統3.選擇合适的消息隊列軟體4.使用分布式服務實作業務的複用5.使用者驗證方案最佳實踐6.App背景架構的演進原則7.社交App背景架構設計方案分享8.其他的一些經驗

一開始就使用Redis的好處:

既能用作緩存,又能充當隊列服務,而且并發性能高,能在長時間内應對業務壓力,非常适合初期的項目。

這裡使用Redis驗證使用者資訊,充當消息隊列。

而檔案服務初期可以選擇 檔案雲存儲服務,或者自己搭建一個資源伺服器。

2.項目一定規模時——分布式部署

我們看一個百萬級到千萬級的架構:

App 背景架構設計方案 設計思想與最佳實踐App 背景架構設計方案 設計思想與最佳實踐1.靈活開發模式2.選擇合适的資料庫産品和伺服器系統3.選擇合适的消息隊列軟體4.使用分布式服務實作業務的複用5.使用者驗證方案最佳實踐6.App背景架構的演進原則7.社交App背景架構設計方案分享8.其他的一些經驗

這裡新增了專門用于連接配接内部伺服器的SSH服務的外網通道,保證SSH操作随時可用,同時加入了伺服器叢集,提供負載能力。

随着業務的發展,某些資料表的規模會以幾何級增長,當資料達到一定規模時,查詢讀取性能就下降的厲害,資料庫主從的架構不能應對業務上的讀寫壓力,這時架構上要考慮分表(水準拆分/垂直拆分)。

當業務繼續不斷發展,資料庫分表後的讀寫性能也可能沒法滿足業務上的需求,這時隻能采用進一步的拆分政策——分庫。用 Cobar 或者 MyCat 等關系型資料等分布式處理系統後,分庫後的架構如下:

App 背景架構設計方案 設計思想與最佳實踐App 背景架構設計方案 設計思想與最佳實踐1.靈活開發模式2.選擇合适的資料庫産品和伺服器系統3.選擇合适的消息隊列軟體4.使用分布式服務實作業務的複用5.使用者驗證方案最佳實踐6.App背景架構的演進原則7.社交App背景架構設計方案分享8.其他的一些經驗

下來看一個真實社交App項目所采用的背景架構方案:

7.社交App背景架構設計方案分享

場景:類似 微網誌,使用者與使用者之間存在關注/粉絲兩種關系,一個使用者發表了新内容,關注他的使用者也能在個人首頁上收到最新的動态。類似 微網誌 這種場景:

App 背景架構設計方案 設計思想與最佳實踐App 背景架構設計方案 設計思想與最佳實踐1.靈活開發模式2.選擇合适的資料庫産品和伺服器系統3.選擇合适的消息隊列軟體4.使用分布式服務實作業務的複用5.使用者驗證方案最佳實踐6.App背景架構的演進原則7.社交App背景架構設計方案分享8.其他的一些經驗

社交核心功能是 Feed(指使用者通過關注,聚合了被關注使用者的最新的内容,也包含自己的内容,以供自己浏覽的資訊服務)。

1.Feed基本表結構

常見的Feed架構是把資料存儲在MySQL,熱點資料存儲(一般最近3天)在緩存(Redis/Memcached),保證絕大多數請求通過緩存直接傳回,隻有少量請求穿透緩存落到資料庫。

下面看一下最簡單的Feed表結構:

send_content:發送内容表,存儲使用者發表的内容:

字段 說明
feed_id 發表的feed的id,主鍵自增
author_id 發表該feed的使用者id
content feed的内容

reveive_content:接收内容表,用于推模式時存儲使用者接收的内容:

字段 說明
feed_id 發表的feed的id,主鍵自增
author_id 發表該feed的使用者id
reveive_id 接收該feed的使用者id
content feed的内容

followings:關注表,存儲使用者關注的人:

字段 說明
id 主鍵自增
uid 使用者id
following_id 該使用者關注的其他使用者id

followers:粉絲表,存儲使用者的粉絲:

字段 說明
id 主鍵自增
uid 使用者id
follower_id 關注該使用者的使用者id

2.Feed推拉模式——推模式使用者發表一條内容的流程

1)uid為1的使用者發表一條内容 “HelloWorld” 資訊。 

2)這條内容寫入發送内容表 “send_content” 後内容如下:

feed_id author_id content
1 1 HelloWorld

3)在粉絲表 “followers” 查找uid為1使用者的粉絲,粉絲表 “followers” 的内容如下:

id uid follower_id
1 1 2

可知,id為1使用者的粉絲是id為2的使用者。

4)因為id為2的使用者的feed中需要顯示這條内容,是以把内容寫入接收内容表 “reveive_content”,寫入後接受内容表 “reveive_content” 内容如下:

feed_id author_id reveive_id content
1 1 2 HelloWorld

5)當id為2的使用者顯示feed時,通過sql語句 “select * from reveive_content where reveive_id=2” 就能查詢該使用者需要顯示的資料了。

推模式的缺點是:

  1. 推送人數過大會出現延時,而且浪費存儲空間;

  2. 更新操作成本大,不但變更 “send_content” 表,而且需要同步變更 “reveive_content” 表。

3.Feed推拉模式——拉模式使用者發表一條内容的流程:

1)uid為5的使用者發表一條内容 “Thinks” 資訊。 

2)這條内容寫入發送内容表 “send_content” 後内容如下:

feed_id author_id content
1 1 HelloWorld
2 5 Thinks

3)當uid為10的使用者顯示feed時,在關注表 “followings” 查找uid為10所關注的使用者,關注表如下:

id uid following_id
1 10 5

可知,uid為10的使用者關注了uid為5的使用者,是以需要擷取uid為5的使用者發表的内容。

4)uid為5的使用者通過sql語句 “select * from send_content where author_id in (5)” 查詢是以需要顯示的内容。

由上述可知,拉模式采用了時間換空間的政策,使用者推送内容時效率很高,但當使用者顯示feed時,需要花費大量的時間在聚合運算上。

總結:

- 發表内容 顯示feed 變更通知
推模式 推送給所有粉絲 一個sql語句就能完成 變更成本高
拉模式 不推送 需要大量的聚合運算 無變更成本

像 “微網誌” 中公開的微網誌采用拉模式,私密性的微網誌采用推模式。

拉模式最大的問題就是大量的聚合運算,請求的響應時間可能較長,可以通過緩存政策讓大部分的請求的響應時間達到2到3毫秒。

8.其他的一些經驗

1.高效更新資料——内容的推拉

平常App設計中,如果App需要知道首頁是否有内容更新,通過一個輪詢機制通路擷取資料API,從API是否傳回更新的資料得知是否有内容更新,輪詢上很典型的拉模式,但是耗電、耗流量。

怎麼減少輪詢呢? 這裡給出解決方案是推模式,如下圖:

App 背景架構設計方案 設計思想與最佳實踐App 背景架構設計方案 設計思想與最佳實踐1.靈活開發模式2.選擇合适的資料庫産品和伺服器系統3.選擇合适的消息隊列軟體4.使用分布式服務實作業務的複用5.使用者驗證方案最佳實踐6.App背景架構的演進原則7.社交App背景架構設計方案分享8.其他的一些經驗

當然不能隻用推模式,因為手機環境的複雜性,不能保證資料更新的通知一定能夠到達App,是以也要采用輪詢的方式定期拉資料,時間間隔設定可以相對長一點,通過這種推拉結合的模式,就能大大減少App通路App背景的頻率和傳輸的資料量。

2.處理表情的一些技巧

表情在MySQL的存儲,表情UTF-8編碼有的是3個位元組,有的是4個位元組,是以一般的UTF編碼(3個位元組)是無法存儲表情資料的,常用的解決方案是:

把MySQL更新到5.5以上,然後把字元編碼改為utf8mb4_general_ci。

3.可供選擇的成熟穩定的開源軟體

功能 可供選擇的開源軟體
項目管理軟體 Mantis、BugFree
代碼管理軟體 SVN、Git
程式設計語言 Java、PHP、Python等
伺服器系統 CentOS、Ubuntu
HTTP/HTTPS伺服器 Nginx、Tomcat、Apache
負載均衡 Nginx、LVS、HAProxy
郵件服務 Postfix、Sendmail
消息隊列 RabbitMQ、ZeroMQ、Redis
檔案系統 Fastdfs、mogileFS、TFS
Android推送 Androidpn、gopush
IOS推送 Javapns、Pyapns
地理位置查詢LBS MongoDB
聊天 Openfire、ejobberd
監控 ngiOS、zabbix
緩存 Memcache、Redis
關系型資料庫 MySQL、MariaDB、PostgreSQL
NoSQL資料庫 Redis、MongoDB、Cassandra
搜尋 Coreseek、Solr、ElasticSearch
圖檔處理 GraphicsMagick、ImageMagick
分布式通路服務 dubbo、dubbox

3.可供選擇的成熟可靠的雲服務

對于初創公司還是建議盡可能的使用成熟可靠的雲服務和開源軟體,自身隻專注于業務邏輯。

功能 可供選擇的雲服務
項目管理工具 Teambition、Tower
代碼托管平台 GitHub、Gitlab、Bitbucket、CSDN CODE、Coding
負載均衡 阿裡雲SLB、騰訊雲CLB
郵件服務 SendCloud、MailGun
消息隊列 阿裡雲MNS、騰訊雲CMQ
檔案系統、圖檔處理 七牛雲、阿裡雲對象存儲OSS、騰訊雲對象存儲COS
Android推送 極光、個推、百度推送
IOS推送 極光、個推、百度推送
聊天 融雲、環信
監控 監控寶、雲伺服器自帶的監控服務
緩存 阿裡雲緩存服務、騰訊雲彈性緩存
關系型資料庫 阿裡雲RDS、騰訊雲CDB
NoSQL資料庫 阿裡雲NoSQL産品、騰訊雲NoSQL産品
搜尋 阿裡雲開放搜尋、騰訊雲搜TCS
分布式通路服務 阿裡雲EDAS
防火牆 阿裡雲雲盾、騰訊雲安全
短信發送 shareSDK、bmob、Luosimao
社交登入分享 shareSDK

最後,在移動網際網路項目中,産品的研發講求 小步快走,快速疊代。 架構的設計也可以遵循同樣的思路,喜歡本文的記得 頂 一下哦!

繼續閱讀