神州系統(tǒng)是中通自主研發(fā)的網(wǎng)點(diǎn)智能管理平臺(tái),為網(wǎng)點(diǎn)提供與下屬網(wǎng)點(diǎn)、承包區(qū)、業(yè)務(wù)員、客戶之間的收、派、代收增值等結(jié)算工具,通過系統(tǒng)自動(dòng)算賬和結(jié)算,網(wǎng)點(diǎn)整體結(jié)算效率提升至2倍以上,降低了財(cái)務(wù)運(yùn)營成本。同時(shí)通過財(cái)務(wù)結(jié)算的自動(dòng)化,網(wǎng)點(diǎn)收件和到件掃描操作效率約提升50%。
系統(tǒng)還通過大數(shù)據(jù)計(jì)算,將客戶的運(yùn)費(fèi)、件量、發(fā)件區(qū)域占比、重量占比等數(shù)據(jù)報(bào)表快速準(zhǔn)確地展示出來,方便網(wǎng)點(diǎn)分析客戶,提升了網(wǎng)點(diǎn)的市場競爭力。另外,還提供了網(wǎng)點(diǎn)整個(gè)運(yùn)營環(huán)節(jié)的數(shù)據(jù)監(jiān)控,幫助網(wǎng)點(diǎn)糾正錯(cuò)誤操作,減少異常率,提升了網(wǎng)點(diǎn)管理水平,降低了網(wǎng)點(diǎn)的管理成本。
為了保證系統(tǒng)的高可用,實(shí)現(xiàn)海量運(yùn)單數(shù)據(jù)的實(shí)時(shí)賬單運(yùn)算、出賬以及數(shù)據(jù)分析,我們的技術(shù)人員都付出了什么樣的努力,神州系統(tǒng)的架構(gòu)剛開始并不是流行的微服務(wù)架構(gòu),這中間又發(fā)生了什么?下面請(qǐng)大家跟著我一起,探索神州系統(tǒng)的發(fā)展歷程。
神州系統(tǒng)自2017年1月立項(xiàng),根據(jù)當(dāng)時(shí)的情況分析,其中最重要的2個(gè)因素對(duì)我們決策有著直接影響。
第一個(gè)因素:數(shù)據(jù)量大,每日賬單數(shù)據(jù)量1600-2000萬不等;
由于MySQL數(shù)據(jù)庫單表記錄數(shù)過多會(huì)導(dǎo)致檢索效率下降,數(shù)千萬記錄就會(huì)導(dǎo)致普通查詢效率低下,對(duì)于聚合函數(shù),更是連千萬級(jí)數(shù)據(jù)都無法支撐,而我們的數(shù)據(jù)卻有數(shù)億。為了解決這種問題,我們使用dangdang公司開源框架sharding-jdbc分表分庫的解決方案,以便于我們將單表數(shù)據(jù)量控制在千萬左右。根據(jù)業(yè)務(wù)我們制定了3種分表規(guī)則:按網(wǎng)點(diǎn)、按單號(hào)、按時(shí)間。
網(wǎng)點(diǎn)的賬單數(shù)據(jù)理論上不會(huì)出現(xiàn)交際,正是借助這一點(diǎn),我們將賬單的數(shù)據(jù)按網(wǎng)點(diǎn)分表,查詢時(shí)針對(duì)一個(gè)網(wǎng)點(diǎn)查詢,這樣既能滿足業(yè)務(wù)需要,又能滿足系統(tǒng)性能需要。
而對(duì)于熱點(diǎn)數(shù)據(jù),在系統(tǒng)設(shè)計(jì)的過程中,需要多網(wǎng)點(diǎn)共享數(shù)據(jù)時(shí),比如同一個(gè)單號(hào)被多個(gè)網(wǎng)點(diǎn)掃描操作,需要將部分?jǐn)?shù)據(jù)共享在多個(gè)網(wǎng)點(diǎn)中,我們則可以采取單號(hào)分表,將多個(gè)網(wǎng)點(diǎn)的信息,記錄在一個(gè)單號(hào)上。而按時(shí)間周期統(tǒng)計(jì)的數(shù)據(jù)或計(jì)算的中間結(jié)果,則采用按時(shí)間分表。
上面所說的分表規(guī)則都是標(biāo)準(zhǔn)化的規(guī)則,但是標(biāo)準(zhǔn)化的分表規(guī)則,也許并不能完全滿足實(shí)際需要;比如我們就遇到了這樣的問題,按網(wǎng)點(diǎn)分表時(shí),幾十個(gè)網(wǎng)點(diǎn)被分配到1張表中,其中一個(gè)網(wǎng)點(diǎn)業(yè)務(wù)量非常大,數(shù)據(jù)占整張表的97%,使用的時(shí)候,不單當(dāng)前網(wǎng)點(diǎn)無法正常使用,其他網(wǎng)點(diǎn)也受到了牽連。此時(shí)使用特殊分表規(guī)則,將次網(wǎng)點(diǎn)的數(shù)據(jù),單獨(dú)存入一張獨(dú)立的表,此表中只有本網(wǎng)點(diǎn)數(shù)據(jù),根本不需要維護(hù)網(wǎng)點(diǎn)id的索引,可以把更多有效的索引資源放在其他業(yè)務(wù)字段上,大大提高了檢索效率。
另外我們采用了TBSchedule實(shí)現(xiàn)分布式調(diào)度,使海量賬單數(shù)據(jù)由多臺(tái)機(jī)器分開運(yùn)算。既保證了海量數(shù)據(jù)計(jì)算的時(shí)效,又保證了服務(wù)器不會(huì)重復(fù)運(yùn)算相同的數(shù)據(jù)。同樣我們可以使用自定義的分片規(guī)則,讓多臺(tái)服務(wù)器的工作量盡量地保持平衡。
第二個(gè)因素:研發(fā)時(shí)間少,項(xiàng)目要在3個(gè)月內(nèi)上線。
由于時(shí)間的因素,為了能夠快速實(shí)現(xiàn)產(chǎn)品需求,達(dá)到盡快上線運(yùn)行的目的,采用單體式架構(gòu)方式開發(fā)。由于單體式架構(gòu)簡單,易于調(diào)試,只需要簡單運(yùn)行此應(yīng)用。易于部署,只需要把打包應(yīng)用拷貝到服務(wù)器端,通過負(fù)載均衡,在后端運(yùn)行多個(gè)副本,就可以輕松實(shí)現(xiàn)應(yīng)用擴(kuò)展。
前端頁面采用 angularJS1.0,前后端分離模式開發(fā)(其實(shí)是java程序員在做前端開發(fā))。既可以減少服務(wù)器渲染頁面消耗的性能,又兼顧java程序員的前端技術(shù)水平,減少前端頁面的開發(fā)難度。
項(xiàng)目上線之初,我們也面臨層層考驗(yàn),首先大量的js和html文件請(qǐng)求到tomcat,導(dǎo)致鏈接被耗盡,因此我們添加了自己的nginx服務(wù)器,將靜態(tài)資源部署在nginx上,不但減少了tomcat服務(wù)壓力,也讓我們的前后端分離開發(fā)更接近于標(biāo)準(zhǔn)化,為我們后期做微服務(wù)架構(gòu)改革打下基礎(chǔ)。其次大量的導(dǎo)出數(shù)據(jù)嚴(yán)重消耗了我們的服務(wù)器資源,因此我們?cè)O(shè)計(jì)了基于前端的下載,在服務(wù)器端不生成文件,改由ajax請(qǐng)求數(shù)據(jù),瀏覽器中組裝生成文件并保存,成功解決了這個(gè)問題。
不幸的是,單體式架構(gòu)有很大的局限性。應(yīng)用會(huì)隨著時(shí)間推移逐漸變大。由于業(yè)務(wù)的發(fā)展迅速,不到1年時(shí)間,我們那個(gè)小而簡單的應(yīng)用已經(jīng)成長為了龐然大物。此時(shí)的代碼復(fù)雜性高,整個(gè)項(xiàng)目包含的模塊非常多,依賴關(guān)系不清晰。
開發(fā)時(shí)啟動(dòng)一次項(xiàng)目已經(jīng)需要3分鐘,這還不包含編譯的時(shí)間,開發(fā)電腦配置不好的話,會(huì)經(jīng)常導(dǎo)致卡頓甚至死機(jī),并且所有模塊代碼集中在一起,各模塊代碼提交時(shí)需要解決各種沖突,耗費(fèi)大量時(shí)間。
此時(shí)的開發(fā)團(tuán)隊(duì)很痛苦。開發(fā)和部署舉步維艱。而最嚴(yán)重問題是這個(gè)應(yīng)用太復(fù)雜,以至于沒有人能單獨(dú)搞定他。因此,修正bug和添加新功能變的非常困難,且耗時(shí)。由于不能快速的做出成績,整個(gè)開發(fā)團(tuán)隊(duì)都會(huì)變的消極。
而且我們的性能也達(dá)到了一定的瓶頸,所有的功能都堆積在一臺(tái)服務(wù)器上運(yùn)行,導(dǎo)致服務(wù)器硬件已經(jīng)不能很好的支撐如此多的業(yè)務(wù)代碼和數(shù)據(jù),硬件資源會(huì)產(chǎn)生很大的浪費(fèi),且性能很不穩(wěn)定,有許多宕機(jī)隱患。于是我們拆分了業(yè)務(wù)代碼,調(diào)整了部署方式,利用nginx反向代理,將不同的業(yè)務(wù)請(qǐng)求指向不同的服務(wù)器,處理不同的業(yè)務(wù)。
如圖所示,我們的每一個(gè)模塊都是可獨(dú)立運(yùn)行的項(xiàng)目,互相之間沒有依賴。采用了這種方法,我們以最小的成本,解決了性能上的燃眉之急(單體式架構(gòu)向垂直架構(gòu)的轉(zhuǎn)變)。
但是這樣的項(xiàng)目依然有一個(gè)很大的弊端,就是對(duì)于基礎(chǔ)功能,被其他功能引用的同一段代碼可能存在于多個(gè)項(xiàng)目中。代碼重復(fù)率高,維護(hù)難度大。一旦這些功能需要修改,則需要同時(shí)修改多個(gè)項(xiàng)目的代碼,并導(dǎo)致所有項(xiàng)目都要重新部署,成本非常高。
我們?cè)跇I(yè)務(wù)功能相對(duì)穩(wěn)定的時(shí)候,投入了大量精力,重新調(diào)整了我們的架構(gòu)。采用微服務(wù)架構(gòu)方式,將神州系統(tǒng)按業(yè)務(wù)域劃分為多個(gè)服務(wù)。但是系統(tǒng)架構(gòu)的改造,不是一蹴而就的事情,我們將改造分為了三步執(zhí)行。
第一:制定新的系統(tǒng)框架
定義代碼規(guī)范,代碼工具等;
第二:停止向老的項(xiàng)目中添加功能,所有功能用新的框架開發(fā)及部署
當(dāng)單體式應(yīng)用龐大到無法管理時(shí),應(yīng)該停止讓其繼續(xù)變大,也就是說當(dāng)開發(fā)新功能時(shí)不應(yīng)該為舊單體應(yīng)用添加新代碼,最佳方法應(yīng)該是將新功能開發(fā)成獨(dú)立的微服務(wù);
第三:舊功能服務(wù)化
對(duì)舊的功能,根據(jù)業(yè)務(wù)需求以及系統(tǒng)開發(fā)需要,排期修改。每當(dāng)抽取一個(gè)模塊變成微服務(wù),單體應(yīng)用就變簡單一些;一旦轉(zhuǎn)換足夠多的模塊,單體應(yīng)用本身已經(jīng)不成為問題了,要么消失了,要么簡單到成為一個(gè)服務(wù)。
將單體應(yīng)用分解為多個(gè)微服務(wù),解決了單體應(yīng)用過于復(fù)雜的問題。使開發(fā)和維護(hù)變得更容易。服務(wù)內(nèi)部可以自由的設(shè)計(jì)解決方案,實(shí)現(xiàn)對(duì)外透明。即使重寫單個(gè)微服務(wù)也不會(huì)太困難,相比重寫整個(gè)單體應(yīng)用容易多了。每個(gè)微服務(wù)獨(dú)立部署,開發(fā)者不再需要協(xié)調(diào)其它服務(wù)部署對(duì)本服務(wù)的影響。這種改變可以加快部署速度,并且每個(gè)服務(wù)可以獨(dú)立擴(kuò)展。
微服務(wù)架構(gòu)中的每個(gè)服務(wù)都可以由專門的團(tuán)隊(duì)來開發(fā)。開發(fā)團(tuán)隊(duì)之間解耦,服務(wù)內(nèi)部獨(dú)立迭代,有利于充分利用人力資源,減少了團(tuán)隊(duì)管理的難度。
以上內(nèi)容都是實(shí)踐經(jīng)驗(yàn),交流促進(jìn)步,研討共成長,感謝大家耐心地閱讀,謝謝。
此文系作者個(gè)人觀點(diǎn),不代表羅戈網(wǎng)立場
-END-
瑪氏中國|2025年度瑪氏箭牌北京區(qū)域包材及原材料倉儲(chǔ)(VMI)項(xiàng)目
2376 閱讀15倍爆發(fā)式增長,網(wǎng)絡(luò)貨運(yùn)行業(yè)跑出了一匹黑馬
1014 閱讀京東物流一線員工日10周年:為5年、10年老員工授勛,為15000名標(biāo)桿頒獎(jiǎng)
913 閱讀京東物流喀什倉正式運(yùn)營:南疆多縣市當(dāng)天可送貨上門
840 閱讀閃電倉到底靠不靠譜?從倉儲(chǔ)操作看它的真實(shí)挑戰(zhàn)
836 閱讀?16億美元大手筆!這家物流巨頭被UPS收購
796 閱讀德邦快遞“管家式服務(wù)”筑造工業(yè)園物流新模式
748 閱讀國務(wù)院同意15個(gè)城市(地區(qū))設(shè)立跨境電子商務(wù)綜合試驗(yàn)區(qū)
714 閱讀國內(nèi)首套大容量工業(yè)園區(qū)級(jí)分散式風(fēng)電項(xiàng)目正式開工
750 閱讀4月1-27日全國乘用車新能源市場零售72.8萬輛,同比增長24%
707 閱讀