汽车之家移动主App服务端架构变迁
聲明:本文為《程序員》原創(chuàng)文章,未經(jīng)允許不得轉(zhuǎn)載,更多精彩文章請訂閱2016年程序員:http://dingyue.programmer.com.cn/
導語:汽車之家移動主App服務端架構(gòu)經(jīng)歷了從外包的無架構(gòu)概念,到流量激增后的架構(gòu)調(diào)整、重構(gòu)等。本文主要介紹了其主App服務端架構(gòu)演進歷程中面臨的主要挑戰(zhàn)、解決思路和實施過程。
隨著移動互聯(lián)網(wǎng)時代的到來,移動技術(shù)也隨之飛速發(fā)展。如今,App已然成為絕大多數(shù)互聯(lián)網(wǎng)企業(yè)用來獲取用戶的核心渠道。以往以PC為主要承載平臺的各業(yè)務線,源源不斷集成加入到移動項目中來,原本以產(chǎn)品為中心快速迭代的單一開發(fā)模式,已經(jīng)無法應對這洶涌爆炸式的業(yè)務接入和高速增長。同時伴隨著用戶量的增長,流量的持續(xù)暴增,系統(tǒng)架構(gòu)面臨的一系列挑戰(zhàn)和轉(zhuǎn)型。怎么構(gòu)建出高可靠、高擴展、低成本、多快好省系統(tǒng)體系架構(gòu)已成為業(yè)界樂而不厭的長談話題。
發(fā)展
2010年-2012年
2010年移動端剛剛興起,公司組建了移動團隊(剛開始就幾個人)帶領(lǐng)著一家外包公司做了第一版。當時業(yè)務十分簡單,即把PC端的論壇文章等直接搬App端進行展示,服務端也是ALL IN ONE的結(jié)構(gòu),也沒有架構(gòu)的概念(如圖1),雖然系統(tǒng)耦合嚴重、但流量低也不見明顯的問題。
2013年-2014年
2013年公司上市,業(yè)務擴展,移動端流量開始增長,特別是2014年。
2014年末流量較年初增長了2.5倍。而原來的這種ALL-IN-ONE體系結(jié)構(gòu)的弊端日益凸顯,服務端經(jīng)常由于高峰期的訪問壓力宕機。這種高耦合的結(jié)構(gòu)常常由于某一個接口的超限流量導致其他接口也不能正常訪問。
而隨著業(yè)務的不斷擴張,應用的不斷迭代導致應用的體積不斷增大,項目越來越臃腫,冗余增加,維護成本水漲船高……老架構(gòu)力不從心。
面對日益嚴重的服務壓力,公司開始組建自己的移動研發(fā)團隊(C#+SQL Sever),服務端程序進行了第一次重構(gòu)。
服務端程序進行對應用分層(接口層API、業(yè)務邏輯層Service、數(shù)據(jù)訪問層DAO)、分割(根據(jù)App端的各個模塊把原來的ALL-IN-ONE的結(jié)構(gòu)分割成不同服務)、做動靜分離CDN加速、讀寫分離、集群負載。同時公司運維部根據(jù)我們的業(yè)務特點研發(fā)自己的CDN服務、二級緩存SCS服務對應用做進一步加速,經(jīng)過這次改造,暫時緩解了服務端的壓力。
2014年-至今
我2015年初加入汽車之家,當時移動端面臨的問題如下:
請求量更大,應該說是流量暴增的時代:2015年9月,汽車之家移動端日均獨立用戶總訪問量較2014年9月同比增加約73.0%。2016年初移動端PV實現(xiàn)億級。
依賴資源多: 依賴Redis、DB、RPC、HTTP、MongDB、MQ、數(shù)十個業(yè)務。
垂直業(yè)務耦合嚴重:如帖子、文章最終頁和評論系統(tǒng)這種垂直耦合業(yè)務常常出現(xiàn)評論系統(tǒng)掛掉導致帖子或文章最終不能訪問的情況。
運營推廣活動多:為了增加用戶粘度,提高用戶活躍度,各個業(yè)務方和我們自己的運營推廣活動大量增加。
發(fā)版快:每月固定兩次發(fā)版,多版本并存。
微軟技術(shù)體系:微軟收費服務都需要大把白花花的銀子,且高質(zhì)量的.NET工程師越來越難招,生態(tài)圈不太景氣。
為了應對流量的暴漲,服務的高可用性和團隊變大,所有開發(fā)人員集中針對同一個系統(tǒng)的嚴重沖突,App端進行插件化改造。服務端2015年初也開始了二次重構(gòu)計劃,進行了一次脫胎換骨的轉(zhuǎn)型,全面擁抱Java,主要的技術(shù)改變有:
Windows→Linux、SQL Server→MySQL、IIS→Tomcat、C#→Java。
重構(gòu)
需求方面主要有這幾點:文章、帖子的評論這種垂直業(yè)務不能掛掉;業(yè)務爆發(fā)能夠快速實現(xiàn);依賴(多業(yè)務方、多資源)解耦,故障時絕對不允許相互影響。
解決方案分為以下幾步:
分解。首先是團隊:根據(jù)App插件化的劃分,對服務端團隊研發(fā)人員進行分組,各小組只負責自己的模塊,每月固定的兩次迭代,各小組服務獨立上線互不影響。其次是服務結(jié)構(gòu),包括水平擴展:多集群、多機房部署提高并發(fā)能力和容災能力;垂直拆分:垂直業(yè)務進一步拆分,依賴解耦;業(yè)務分片:按功能特點分開部署,如活動、秒殺、推送等物理隔離;水平拆分:服務分層,功能和非功能分開,基礎(chǔ)核心服務非核心服務分開。
業(yè)務服務化,相互獨立,如咨詢、論壇、廣告等。
無狀態(tài)設(shè)計。調(diào)用鏈路無單點、無狀態(tài)服務,可線性擴容(盡可能不要把狀態(tài)數(shù)據(jù)保存到本機、接口調(diào)用做到冪等性)。
可復用。復用的粒度是業(yè)務邏輯的抽象服務,不是服務實現(xiàn)的細節(jié)、服務引用只依賴服務抽象。
資源分層。Redis、DB、MQ 主從設(shè)計,多機房部署、保障高可用。
松耦合、自保護、防雪崩。跨業(yè)務調(diào)用盡可能異步解耦,必須同步調(diào)用時設(shè)置超時、隊列大小、線程池大小、相對穩(wěn)定的基礎(chǔ)服務與易變流程的服務分層;線程池保護,超出服務器最大線程時DROP請求(Nginx、Tomcat)。Redis、DB、MQ、Turbo(RPC)、HttpClient等在后端資源出問題時可以自動降級請求調(diào)用、發(fā)送異常報警。
服務隔離可自理。服務可降級、可限流、可開關(guān)、可監(jiān)控、白名單機制。
各個服務獨立部署互不影響,服務異常自動熔斷,根據(jù)各個服務特點走相應的降級策略?;A(chǔ)服務下沉可復用基礎(chǔ)服務自治、相互獨立、基礎(chǔ)服務要求盡量精簡可水平擴展、物理隔離保證穩(wěn)定(如用戶中心、產(chǎn)品庫)。
分清核心業(yè)務。核心業(yè)務服務盡量精簡,利于穩(wěn)定(運行時優(yōu)先保證主流程順利完成、輔助流程采用異步:如日志上報)。
實現(xiàn)
- 單服務的體系結(jié)構(gòu)
App端請求經(jīng)過接入層(CDN、LVS、NG/SCS),通過接口控制層的設(shè)置校驗(CDN配置、反劫持配置、日志服務配置、安全校驗……)調(diào)用API層發(fā)布的REST接口,通過參數(shù)校驗后調(diào)用業(yè)務邏輯層的業(yè)務實現(xiàn)。同時業(yè)務邏輯層通過數(shù)據(jù)接口層(SourceInterface源接口服務、DbUtils數(shù)據(jù)庫分開分表組件、AIS4J異步請求組件、Trubo RPC服務)調(diào)用資源層的資源服務來完成本次業(yè)務的數(shù)據(jù)組裝,完成本次業(yè)務的調(diào)用。
配置方面,一個基于zookeeper的配置服務(配置服務用于系統(tǒng)的各種開關(guān)的實時配置如:源接口的限流熔斷閾值等);Monitor:監(jiān)控服務實時查看系統(tǒng)異常、流量;Trace:系統(tǒng)跟蹤服務;Log:(日志服務)。
- RPC-Trubo體系結(jié)構(gòu)
為了應對服務化作服務自理,2015年底我們?nèi)鎲⒂霉镜腞PC服務Trubo
框架特點主要有:多語言服務端發(fā)布,支持C#和Java;高效透明的RPC調(diào)用,多協(xié)議支持;基于ZooKeeper的注冊中心,用于服務發(fā)現(xiàn);客戶端軟負載和容錯機制;使用Spark進行服務監(jiān)控與跟蹤Trace分析;整合Locker(Docker調(diào)度平臺),實現(xiàn)服務部署自動化。
服務發(fā)現(xiàn)與RPC穩(wěn)定性和容錯方面,主要是雙機房部署ZooKeeper集群,主力機房5個節(jié)點(Leader/Follower集群),其他機房2個節(jié)點(Observer節(jié)點),保證性能和穩(wěn)定性;Trubo客戶端服務端添加守護線程,定時校驗本地緩存和ZooKeeper的數(shù)據(jù)一致性;Trubo客戶端會將緩存的服務信息持久化到本地,即使ZooKeeper掛掉或者重啟也不影響正常調(diào)用;嵌入Trace客戶端上報收集分布式跟蹤日志。
- 異步請求組件AIS4J
為了解決接口和資源依賴問題(源站或Redis、DB等資源層掛掉導致我們服務不可用的高風險),同時也為了請求響應時間受到源站依賴問題,我們封裝了異步請求組件AIS4J。同時嵌入我們的熔斷限流組件來對源站進行解耦。
引入AIS4J后大大緩解了對外部資源的依賴,提高了服務的可用性,但同時也帶來了一些問題。公司要求對緩存內(nèi)容時間限定在10分鐘以內(nèi),原來的時間被平均分配到了CDN和我們的二級緩存SCS上,現(xiàn)在加入這個組件為了滿足10分鐘的要求必須把原來的10分鐘拆分到AIS4J上,這就需要增大系統(tǒng)接口的回源率(10%左右)。這個時間就要對請求時間和系統(tǒng)壓力上做一個權(quán)衡。
服務監(jiān)測
就目前階段來說,服務分解封裝應對一段時間的流量增長已沒太大問題。但為了保證服務的高可用、系統(tǒng)的擴容預估、故障的實時定位……就必須有一套完善的監(jiān)測報警系統(tǒng)。
圖7是系統(tǒng)調(diào)用追蹤服務,通過對程序Java的Instrumentation和配置系統(tǒng)對系統(tǒng)程序進行埋點跟蹤,再通過Spark對跟蹤日志進行實時分析展現(xiàn)。
Trace實現(xiàn)
Trace ID標識唯一調(diào)用樹,Transaction ID標識唯一次調(diào)用,一次Trace調(diào)用會產(chǎn)生四條日志,Trace調(diào)用樹可以由Turbo、本地調(diào)用、HTTP或其他調(diào)用方式組成,Trace客戶端是獨立的,Turbo單向依賴Trace。
同時我們在APP端的請求頭中埋入Req ID,通過Req ID和Trace ID的對接記錄一次請求過程(CDN、SCS、后端服務、RPC/HttpClient調(diào)用)每一步的時間消耗。
為了更快的定位穩(wěn)定,我們在程序中預設(shè)了Debug模式,在內(nèi)網(wǎng)環(huán)境中只要拿到請求的URL開啟Debug模式就可以快速的調(diào)出系統(tǒng)調(diào)用資源鏈和每一步的程序調(diào)用消耗時間。
報警實現(xiàn)
通過Spark對日志記錄的分析結(jié)果,會實時對接到我們的報警系統(tǒng)上,實現(xiàn)對程序異常的實時報警。報警系統(tǒng)通過短信、郵件方式發(fā)生,內(nèi)容中包含請求的Trace ID超鏈到報表系統(tǒng)實現(xiàn)對異常問題的實時查看定位。
作者簡介:湯泉,2015年加入汽車之家,參與到移動主軟件服務端的架構(gòu)設(shè)計與開發(fā)。
責編:錢曙光(qianshg@csdn.net)
本文為《程序員》原創(chuàng)文章,未經(jīng)允許不得轉(zhuǎn)載,更多精彩文章請訂閱2016年程序員:http://dingyue.programmer.com.cn/
2016年4月22日-23日,由CSDN重磅打造的SDCC 2016數(shù)據(jù)庫&架構(gòu)技術(shù)峰會將在深圳舉行,目前18位講師和議題已全部確認。兩場峰會大牛講師來自百度、騰訊、阿里、京東、小米、唯品會、滴滴出行、攜程等知名互聯(lián)網(wǎng)公司,共同探討高可用/高并發(fā)/高穩(wěn)定/高流量的系統(tǒng)架構(gòu)設(shè)計、秒殺系統(tǒng)架構(gòu)、搜索架構(gòu)、中小企業(yè)架構(gòu)之道、數(shù)據(jù)平臺系統(tǒng)演進歷程和技術(shù)剖析、傳統(tǒng)數(shù)據(jù)庫與分布式數(shù)據(jù)庫選型/備份/恢復原理及優(yōu)化實踐、大數(shù)據(jù)應用實戰(zhàn)等領(lǐng)域的熱點話題與技術(shù)?!灸壳跋迺r6折,點擊這里搶票】
總結(jié)
以上是生活随笔為你收集整理的汽车之家移动主App服务端架构变迁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 路由器和三层交换机的基本实验操作
- 下一篇: iphone避坑指南