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