1. 程式人生 > >1年時間業務量瘋長40倍,談人人車的平臺架構演進之路

1年時間業務量瘋長40倍,談人人車的平臺架構演進之路

人人車業務平臺從最初典型的LNMP單機單服務部署架構,發展到如今分散式服務化架構,五百多臺虛擬機器部署,一路走來,踩過不少坑,也遇到過不少挑戰,特別是對於基於雲服務進行業務開發的場景,以及從零開始服務化與SOA之路更是頗有心得,希望通過此次分享全面回顧人人車業務平臺技術架構發展之路,重點分享如下內容:
• 創業初期技術架構選型思考,那些年我們趟過的坑,雲服務與三方服務使用心得;
• O2O型網際網路創業公司,重線下團隊技術型公司,技術架構優化之路,分享我們人人車是如何做服務拆分、如何做服務化、如何做SOA、如何做DB慢SQL優化等;
• 人人車HTTP服務管理框架介紹相關使用經驗分享;
• 人人車業務平臺技術架構規劃;

  人人車是由一幫百度兄弟們,於 2014年4月成立,作為二手車C2C模式首創者,以及典型的O2O二手車網際網路電商企業, 創業兩年多,目前業務範圍已經覆蓋全國數十個城市了,今年年底將覆蓋到過百城市。
  我們業務平臺負責全部核心業務系統研發工作,包括:CRM系統、釋出系統、編輯系統、評估系統、銷售系統,金融支付等業務系統,承擔人人車所有線下業務團隊收車、賣車等核心環節技術支援!
  好了,接下來,就進入到今天的第一個話題,分享下我們創業初期的技術架構和技術選型思考。
  

創業初期技術架構選型思考

  為了快速開發迭代,初期人人車業務平臺所有服務全部基於LNMP進行搭建,從前到後一套系統,2臺雲主機機器,非常簡單清晰,V 0.1版本架構如下圖所示:
這裡寫圖片描述

  從上圖可以看出創業初期我們的V0.1版本的技術架構非常簡單,主要基於一下幾點考慮:
1. 研發資源的限制,我們必須集中精力做最重要的事情,業務需求滿足是第一位的;
2. 產品快速迭代的需要,創業初期整個技術團隊技術能力成熟度不高,因此我們更是傾向簡單、清晰、研發熟練度高的技術框架;
3. 初期業務規模較小,技術架構需求較低,簡單框架完全可以滿足業務需求,適合業務需求的架構就是好架構;
4. 輕量級LNMP框架,選擇足夠簡單靈活的PHP CI框架, 雲MySQL RDS服務,簡單易上手,運維部署成本非常低,大大節省了我們運維成本,以及開發人員的學習成本;

  為了能夠快速搭建服務把創業專案搞上線,我們之前一直堅持的幾個原則也跟大家分享下:
1. 大量使用雲服務,包括:虛擬機器、DB、MQ中介軟體、Redis等基礎服務,大大降低了這些技術能力要求高的基礎主件、儲存服務、訊息中介軟體等服務的部署運維代價;其實就是:花錢買服務,花錢買時間,花錢買研發能力;
2. 大量使用第三方收費服務,以代價換時間,例如:Teambition服務、BDP報表服務、ODPS資料管理、圖片儲存服務、語音通話服務等等;
3. 權衡自研系統與三方採購系統代價,對於非核心業務系統,如果能通過採購滿足需求,就快速採購服務,應用到一線業務中去,例如:HR系統、OA系統、培訓系統、雲報銷系統、工作流引擎等等;
4. 擁抱開源,GitHub是個金礦,值得每一位創業者去挖掘,去發現自己的需求,其實很多同行已經做了我們要做的基礎研發事情;
5. O2O創業專案,線下業務系統是第一位的,所有資源”all in” 去提升線下團隊工作效率,優化線下業務系統流程,提升線索轉化漏斗,提高轉化率;
6. 低頻冷門電商業務,口碑推廣,營銷推廣,廣告投放,SEM等都是需要精細運營的,是流量運營最重要的幾個關鍵點;

  雖然我們堅持了上面提到的很多原則,不經意間我們還是踩了很多坑,例如:
1. 雲服務不靠譜,出問題造成雪崩,導致整個站點不可用。這塊我的經驗是不能把整個站點的生死寄託在別人手中,一定要多給自己留個B計劃,容災方案不管是公司發展到哪一步都需要的;雲服務作為基礎服務在做架構部署時,一定要多考慮幾家互為容災備份;
2. 第三方服務在使用時,一定要與自己業務服務解耦,能簡單封裝一個proxy代理層那就最好了,避免直接巢狀第三方SDK到業務程式碼中,這樣就相當於跟第三方捆綁在一條船上了,友誼的小船說翻就翻啊;
3. 核心系統容災,核心系統在選擇第三方服務時,一定要多挑選幾個合作伙伴,系統架構上,最好能支援容災切換,在一個第三方服務出問題時,能夠快速進行切換,避免將核心系統生死權掌握到第三方服務上去。例如我們人人車是一個重電銷型公司,呼叫中心就是我們的核心,這套系統之前我們設計初期就僅僅只支援一家供應商,導致後面只要合作伙伴出問題,我們就跟著掛了,非常非常的被動;真是不怕神一樣的對手,就怕豬一樣的隊友啊!
4. 重視DB設計,這個問題,可能在初期大家覺得MySQL DB資料庫表可以隨便設計,表的欄位個數,欄位型別都影響不大,其實初期嚴格把關DB設計,後期就會少填很多坑,我們曾經有個大json_data欄位,歷史原因設計不友好,導致我們花了2年時間才把這個欄位拆掉,真的是非常痛苦的經歷;

人人車業務平臺技術架構優化之路

  隨著我們業務不斷髮展,線下團隊出現了爆炸性的增長,銷售、評估師、客服人員等都增長不止一個量級,我們的車輛數、訂單量、客服量等都是飛速增長,同時由於前期主要關注產品需求,而對技術架構的優化工作相對滯後,導致這個階段我們業務系統問題不斷,這使得我們陷入了非常被動的局面。
  這種背景下,我們意識到必須要緩一緩業務需求開發了,不能再一直堆程式碼了,我們需要進行重構需要梳理我們之前的系統架構,因此這才有了我們全面梳理人人車業務系統架構與系統重構這項工作,希望重點從技術架構合理性上去梳理現有系統!
  回頭大家可以反觀當時這個階段我們的技術架構,我叫它為V0.2版本架構,如下圖所示:
這裡寫圖片描述

  相對於1年前的V0.1版技術架構,此時整個業務端架構,做了部分系統拆分,但是這種拆分僅僅是程式碼層面的複製,重新創建出了很多業務模組,而真正的底層DB、資料庫表、快取等都還是未進行拆分的;
  由於所有業務都使用一個業務DB庫,因此DB成了整個業務的單點與雷區,隨時可能被引爆,同時由於業務複雜度的不斷增大,DB慢查詢也不斷湧現,DB連線數、CPU、IOPS等核心資源都出現了競爭與爭搶,只要一個業務系統出問題,則所有服務都將受影響,出現雪崩效應,正是由於這些問題使得我們業務進展越來越艱難!
  在啟動服務架構優化專案之前,我們首先從如下兩個方面進行梳理,全面診斷我們系統架構存在的問題:
  1、流程規範與運維部署問題梳理:
• 全部服務部署在2臺雲主機,高度耦合,相互影響,資源競爭;
• 釋出方式原始,svn check、scp覆蓋;
• 回滾流程與工具缺失,遇到問題回滾不方便、回滾不完全;
• 上線流程不規範,無通報相關機制、無回滾預案;
• 上線後迴歸驗證方法不全面,不易確定功能是否完整;
  2、服務耦合與服務拆分梳理:
• 所有專案copy自car_publish這個專案,大量冗餘程式碼,框架使用不純淨;
• 通用庫、工具、類未能複用,未提取部署到統一路徑獨立部署維護;
• API分層邏輯不嚴格,跨層、躍層呼叫現象明顯,業務調用出口不統一,不便於後續維護;
• 專案耦合太緊密,未按功能進行服務化拆分,服務呼叫關係混亂,難以管理;
• Cache層缺失,缺少核心邏輯快取加速,系統有時響應緩慢;
• DB資料庫耦合嚴重,未按業務獨立拆分,部分欄位設計不合理包含大JSON、長欄位、慢查詢;
• 日誌列印不規範,關鍵路徑日誌缺失,日誌檔案切分與清理機制缺少
• 介面級別監控缺少,超時、流量變化等業務級別監控缺少;

  為了解決上面分析的問題,我們從如下幾個方面重點跟進,對人人車業務平臺進行有史一來最大的一次優化重構,涉及到:服務拆分、運維部署流程優化、服務監控、DB拆分、慢SQL 優化、同步轉非同步等事項。

1、服務拆分

  從上面分析可以看出,現有系統最大問題,就是各模組之間耦合太高,模組之間依賴太重,因此我們首先啟動的專案,就是服務拆分,從服務部署上物理拆分開,避免一個模組出問題造成整個業務系統雪崩。
  服務拆分的核心原則如下:
• 各模組Git程式碼層面獨立管理與維護
• 線上獨立SLB、獨立部署、獨立運維
• DB層面資料隔離,獨立從庫
• 通用功能抽取到API層
• 核心業務邏輯增加cache層
  通過以上的拆分工作,我們的服務部署架構變成如下圖所示,各個模組獨立部署,通過SLB進行負載均衡,從物理部署上將服務拆分開來。
這裡寫圖片描述

2、DB慢查詢優化,我們從如下幾個方面著手:

  第一,每天通過SQL工具分析出top 5慢查詢,要求研發同學必須完成優化,將慢查詢優化作為例行事項,每天去review,到後期我們規範化慢SQL排查流程,從如下幾個維度分析周級別慢SQL:執行耗時、掃描行數、返回行數等條件,綜合分析出高優先順序SQL提交給研發同學參考優化;
  第二,DB讀寫分離,所有讀請求切換到從庫,同時各個服務按優先順序使用不同從庫,這樣主庫只剩下更新操作,基本可以杜絕大部分慢SQL,通過慢SQL每天分析報告可以清楚看到需要重點優化的問題SQL;
  第三,對於DB輪詢操作相關業務邏輯優化,調整輪詢為通知機制,降低程式輪詢給DB帶來的壓力,通過更新通知機制保證資料實時通知到業務方,再通過 API查詢詳細資料,減少各業務模組對主庫的直接SQL查詢;
  第四,加強SQL稽核,所有上線SQL,都必須通過SQL稽核才可以到線上DB執行,之前由於業務迭代過快,線上DB運維與許可權把控不夠,導致研發同學直接線上操作DB, 各種慢SQL層出不窮;
  第五,加強DB表設計review ,所有對線上資料庫DDL相關操作,都必須通過線上DB schema稽核才可執行;對於DB設計我們同樣歸納出統一的 mysql DB設計規範,所有線上設計都必須滿足規範才可執行!
  
  人人車DB Schema規範如下:
• 所有資料庫的DDL操作全部收回,由OP統一管理;
• 每張表/檢視要有註釋(comment),格式為 模組|用途|負責人|建立日期 ,例如:貸款|記錄貸款使用者身份證號碼|張三|2016-03-25;
• 每個欄位要有註釋(comment),格式為 用途|負責人|建立日期 , 例如:記錄使用者性別@1:男@0:女@2:未知|李四|2016-03-25;
• 每張表三個必加欄位,id (自動增長), create_time , update_time 用作儲存主鍵,記錄建立時間,記錄更新時間 , 這三個欄位由OP維護,RD無需處理;
• 有邏輯刪除需求的表,可選增加delete_flag欄位(int型別,預設值為0),用來標識欄位是否被邏輯刪除;
• 收回RD的delete許可權,所有資料不能做物理刪除(邏輯上刪除的需求可以通過flag標籤的方式來處理);
• 欄位來源需要說明,來自哪張表的那個欄位,例如:記錄車輛ID,#取自cp_used_car.car_id|李四|2016-03-25;

3、DB拆分:

  由於前期業務相對簡單,所有業務資料全部集中存放在一個DB裡面,這樣導致重要資料與普通日誌資料都混在一個庫中,各業務模組資料也全部落在一個庫中,導致業務主庫壓力過大,隨時可能因為一條SQL導致的DB問題,將整個人人車業務平臺都給拖垮,因此DB拆分對於我們來說,也迫在眉睫。
  我們執行DB拆分的核心原則如下:
• 各實體分庫分表設計
• DB主從拆分
• 資料加密杜絕明文儲存
• 表與DB設計:必須遵循人人車DB設計規範與schema設計規範
• 索引設計:合理使用索引,杜絕濫用索引
  為了能夠更好的相容之前的系統,做到平滑遷移,減少對業務系統的影響,在做DB拆分時,我們首先對業務系統進行實體拆分,再抽取API,對於業務方只需要將之前SQL查詢方式遷移到API呼叫即可。
  基於人人車業務實際場景,我們將之前的DB庫拆分為如下實體:
• Json_data 資料拆分 (解決DB 中json_data欄位內容過大造成效能問題而拆分)
• Car 實體抽取
• User 實體抽取
• Order 實體抽取
• Clue 實體抽取
  對於我們最核心的car車輛實體拆分,基本是將之前主庫中一個核心表與json_data全部重新拆開設計的,由原來的一張表擴充套件到如下圖所示的實體設計:
這裡寫圖片描述

人人車服務化與SOA架構

一、服務化與SOA架構:

  在我們做完服務部署架構拆分後,服務化與SOA架構規劃其實已經排上了日程,我們做服務化與SOA架構主要出於以下考慮:

1、業務平臺視角

• 多樣的需求直達 (業務端各類系統需求的滿足)
• 一致的使用者體驗 (使用者使用與行為習慣的延續,減少培訓成本)
• 快速迭代 (各子系統、業務線只關注自有特性開發、專人專事,避免“重複造輪子”)
• 資源的最有效利用 (便於人力資源、軟硬體資源的高效共用與複用)
• 系統穩定性與服務質量的提升
• 問題避免與定位、解決速度的提升

2、公司全域性視角

• SOA與服務化架構的探索
• 公司級服務化框架的試點與應用
• 技術積累與沉澱的需要,研發人員技能提升的必由之路
• 打造高效O2O線上、線下平臺的基石
• 提升研發效率、降低研發成本的利劍
  人人車服務化架構設計的核心指標如下表所示:
這裡寫圖片描述

  對於人人車來說,服務化架構是必行之路,前期的高度耦合的技術架構,已經在很大程度上制約整個公司業務的發展,對於產品需求,響應速度越來越慢,需求堆積越來越多,業務抱怨也越來越大!
  因此我們對現有技術團隊做了簡單的組織架構調整,單獨抽取精幹力量,搭建專門負責服務化的基礎架構團隊,開始啟動人人車服務化架構之路,我們主要從如下幾個方面著手開展工作的:
• 現有系統功能劃分與子系統梳理;
• DB層拆分:各子系統DB獨立,解耦降低依賴;
• 所有子系統、應用間的互動都要通過服務的方式來進行,不允許其他方式如:讀庫、同步腳步、搭建私服、跨層呼叫等;
• 所有子系統、應用,都以服務的方式將其資料與功能開放出來,通過API的形式提供訪問;
• 服務的實現方式,初期以現有的HTTP協議為準,後續擴充套件到RPC、自定義協議等;
  通過上面這一系列的優化重構,人人車業務平臺技術架構終於站到了 V1.0版本,如下圖所示:
這裡寫圖片描述
  從上圖我們可以看到,我們的V1.0版本系統架構,基本達到如下效果:
• 服務已經完全拆分開,模組化與元件化也初步建立;
• 產出多個基礎服務如:基於zookeeper的通用配置管理服務、通用反作弊服務、通用驗證碼服務等;
• 產出一批執行規範:通用錯誤碼規範、通用日誌管理規範、MySQL規範、PHP編碼規範等;
• 對於一些通用庫與通用配置,也完成拆分,單獨通過Git專案進行管理,建立comm libs, comm configs等多個通用配置與程式碼庫。
  可以說這一階段,是我們人人車業務研發團隊最艱難的階段,同樣也是大家收穫最大的階段,從零開始,我們全程見證了自己的服務,從開始的混亂不堪,逐步變成規範與穩定,每一步拆分,每一個優化,其實都凝聚著所有業務平臺研發同學的無限心血!
  通過服務化相關專案的推進,我們在專案研發過程中,發現之前的研發流程與研發思路也需要進行調整與轉變,主要表現在如下幾點:
  轉變需要解決的主要問題
• 從簡單“堆程式碼”實現業務需求,到模組化開發“堆積木”滿足需求;
• 從簡單程式碼copy,到模組服務化與基礎庫沉澱,便於後續各類系統快速開發;
  轉變的關鍵點
• 通用流程業務的抽象;
• 核心流程的拆分與解耦 (服務、子系統、模組級別拆分);
• 服務的可定製 -> SAAS;
• 服務的可插拔 -> SOA;

二、人人車HTTP微服務管理框架:

  在做服務化過程中,我們基於實體拆分,抽取了多個實體API服務,為了能夠統一管理這些HTTP API,我們提取了統一的服務接入層,對我們所有http-api進行管理,通過統一的微服務管理框架,實現如下核心功能:
• 統一的API接入層:所有業務實體拆分後對應API全部接入到服務管理框架,實現對外介面統一,對內統一管理;
• 統一的許可權管理與鑑權:可以實現多種API訪問的許可權管理,如:jwt、OAuth 2.0、IP白名單機制等等;
• 統一的API分析與管理:通過WEB上實現服務註冊,簡單配置下,即可實現服務路由、API分析、流量控制、服務容災、failover等通用功能;
• 統一的API監控與統計:統一實行qps統計、日誌、監控、openfalcon打通上報資料等功能;
• 採用Nginx+lua的模式,功能模組採用lua可靈活擴充套件,基於Nginx實現達到高效能與高可靠,在最上層實現功能需求,減少對業務的侵入與效能的損耗;
  人人車微服務管理框架,架構圖如下:
這裡寫圖片描述
  人人車業務平臺微服務管理框架,基於開源OpenResty框架進行搭建,通過Lua指令碼進行功能擴充套件,實現個性化需求,所有 HTTP請求呼叫全部通過微服務管理框架,由框架進行路由、鑑權等功能;
  由於微服務管理的請求都是無狀態的HTTP請求,因此在微服務框架層面可以靈活的擴充套件,避免單點問題。對於一些核心業務,我們甚至可以靈活的從物理層面獨立部署微服務管理框架,從而隔離各個核心模組之間的相互影響。

三、人人車V2.0版本架構:

  雖然人人車業務平臺V1.0的架構,階段性的滿足了快速發展的業務需求,但是從技術架構角度看,還是存在諸多問題的,例如:
• 跨層呼叫大量存在;
• API化不夠徹底;
• DB拆分仍不完整;
• HTTP服務缺乏統一管理,缺少統一的服務治理框架;
• 對於HTTP服務所有模組鑑權、安全、監控等都有大量重複工作。
  因此,在2016年上半年我們花了大概小半年的時間,通過進行上面提到的的SOA與服務化,HTTP api統一接入層的加入, 微服務管理框架的加入等一系列工作,終於將人人車業務平臺技術架構再次往前推進一步到V2.0版架構,V2.0架構圖如下所示:

人人車業務平臺技術架構規劃

  對於下一步人人車業務平臺技術架構的走向,總體規劃如下圖所示:
  
  概括的講,我們將重點關注服務穩定性、異地容災、資料儲存隔離、基礎服務元件化、通用業務模組化、持續整合、運維與安全協同等方面,重點跟進如下幾點:
• 基礎支撐專案服務化與元件化:重點跟進呼叫平臺化、派單服務化、CRM平臺化、配置服務化、反作弊通用服務、驗證碼服務化等基礎業務支撐專案;
• 基礎運維與安全:協同OP一起構建更加方便靈活的運維安全體系,對整個人人車業務平臺所有服務進行安全護航;
• 持續整合支撐:協同QA團隊一起打造從Git提交程式碼開始的自動化流程,包括:自動化測試,自動化釋出,自動化迴歸驗證等核心指標;
• 前端架構分離與服務化:協同FE團隊一起打造服務化的前端架構,徹底做到前後端分離,真正實現前後端資料隔離,進一步打造人人車自己的前端開發元件和框架;
• 資料儲存隔離:協同DBA團隊一起構建人人車業務系統資料訪問層,對於底層DB真正做到業務隔離與上層透明,增強DB資料安全性;
• 異地容災支撐系統:基於各家雲服務提供商,構建人人車自有資源定位層,實行各雲服務商之間災備,同時通過自建proxy服務方式,實現自建服務與雲服務之間的災備功能;
• 服務質量評價體系建立:基於現有的業務系統,構建統一的服務質量評價體系,能夠實現各服務缺陷管理、穩定性度量、穩定性評價指標統一監控等功能;
  作者介紹
  徐章健,南開大學計算機軟體與理論碩士研究生畢業,2015年加入人人車,擔任業務平臺總架構師,總體負責業務平臺的架構及技術規劃,目前重點推進人人車業務平臺服務化、SOA、業務服務平臺化、資料平臺化等基礎專案研發管理工作;徐章健同學擁有多年網際網路研發管理工作,歷任百度ksarch核心研發工程師,360搜尋onebox組架構師,美團INF基礎架構組架構師。多年來專注於基礎架構方面的研究,對於大規模web架構、搜尋架構演算法、大規模叢集基礎設施建設,都有一定的見解; 對於高併發、大流量分散式服務、RPC框架、服務治理、服務SOA化等都有豐富的實戰經驗,對專案管理、團隊建設、人才培養等也都頗為擅長!