一個(gè)系統(tǒng)裝再多數(shù)據(jù)仗岸,不與其他系統(tǒng)交互,那也是孤島系統(tǒng)借笙,孤獨(dú)沒(méi)女朋友扒怖。
一個(gè)系統(tǒng)若很外向,不斷撩撥周?chē)南到y(tǒng)业稼,也樂(lè)意被撩撥盗痒,成為了眾系統(tǒng)中的“交際花”,那么這貨基本就是中臺(tái)的性質(zhì)低散。
而更多的系統(tǒng)是介于上述兩種極端之間的俯邓。像人一樣,自己搞生產(chǎn)熔号,也要參與社交——就是系統(tǒng)之間的數(shù)據(jù)對(duì)接稽鞭。
對(duì)接的本質(zhì)是為了實(shí)現(xiàn)數(shù)據(jù)信息的傳輸。
在后端產(chǎn)品的世界里引镊,各子系統(tǒng)之間朦蕴,或與外部系統(tǒng)之間的對(duì)接非常常見(jiàn)。
作為產(chǎn)品經(jīng)理弟头,不僅要知道數(shù)據(jù)從哪來(lái)吩抓,還要理清楚獲取數(shù)據(jù)之后的握手方式、運(yùn)算邏輯赴恨、異常規(guī)則疹娶、容錯(cuò)機(jī)制、數(shù)據(jù)日志等等伦连。
本文嘗試聊聊如下話(huà)題:
(1)數(shù)據(jù)傳輸?shù)膱?chǎng)景和意義
(2)數(shù)據(jù)傳輸?shù)姆绞?/p>
(3)數(shù)據(jù)傳輸?shù)奶幚頇C(jī)制
(4)數(shù)據(jù)傳輸?shù)淖⒁馐马?xiàng)
一蚓胸、 數(shù)據(jù)傳輸?shù)膱?chǎng)景和意義
1、數(shù)據(jù)傳輸?shù)膽?yīng)用場(chǎng)景
前端和后端本身無(wú)時(shí)不刻的數(shù)據(jù)互動(dòng)除师。
公司的各個(gè)系統(tǒng)之間的信息共享沛膳。
比如,式系統(tǒng)部署之后汛聚,就需要各個(gè)系統(tǒng)模塊之間進(jìn)行數(shù)據(jù)的配合锹安,比如訂單系統(tǒng)的庫(kù)存扣減數(shù)據(jù)要同步給備貨系統(tǒng)進(jìn)行采購(gòu)。
與第三方平臺(tái)的對(duì)接
比如入駐第三方銷(xiāo)售平臺(tái)亞馬遜之后,店家可能自己需要管理自己的訂單叹哭,這時(shí)候就要從亞馬遜平臺(tái)獲取訂單數(shù)據(jù)忍宋,也就是抓取。
調(diào)用現(xiàn)成的公共插件
避免重復(fù)造輪子风罩,市場(chǎng)上很多開(kāi)放性的功能插件可以調(diào)用或接入糠排,比如接入百度地圖的API,接入微信小程序的二次開(kāi)發(fā)超升。
2入宦、數(shù)據(jù)傳輸?shù)囊饬x
不重復(fù)生產(chǎn)數(shù)據(jù)庫(kù),避免資源和功能的浪費(fèi)室琢。
統(tǒng)一數(shù)據(jù)的維護(hù)或生產(chǎn)源頭乾闰,避免數(shù)據(jù)不同步。
比如同一個(gè)公司的兩個(gè)系統(tǒng)都要用人員信息架構(gòu)數(shù)據(jù)盈滴,如果各自都能維護(hù)涯肩,勢(shì)必出現(xiàn)不一致,也浪費(fèi)資源巢钓。
別人家的數(shù)據(jù)病苗,自己沒(méi)辦法生產(chǎn)。
復(fù)用現(xiàn)成的輪子症汹,API或SDK共享(可能自己也發(fā)明不出來(lái))铅乡。
二、 數(shù)據(jù)傳輸?shù)姆绞?/b>
數(shù)據(jù)傳輸?shù)姆绞搅揖鳛楫a(chǎn)品經(jīng)理我將其分為:接口傳輸阵幸、中間件傳輸、message方式傳輸?shù)妊渴馈I㈤_(kāi)了說(shuō)挚赊,比如:MQ(隊(duì)列)、HTTP接口济瓢、otter荠割、文件共享傳輸?shù)取C恳环N又有細(xì)分的方式和適合的場(chǎng)景旺矾。
1蔑鹦、接口
這是一種傳統(tǒng)的問(wèn)答式的傳輸方式,是典型才c/s 交互模式箕宙。
相當(dāng)于一臺(tái)客戶(hù)機(jī)嚎朽,一臺(tái)服務(wù)器(注:這里的客戶(hù)機(jī)或服務(wù)器根據(jù)數(shù)據(jù)的提供方和接收方相對(duì)而言的,并不一定是實(shí)際的)柬帕。
目前我們常用的http調(diào)用哟忍、java遠(yuǎn)程調(diào)用狡门、webserivces 都屬于這種方式,只不過(guò)锅很,不同的就是傳輸協(xié)議以及報(bào)文格式的區(qū)別其馏。
1)接口的作用
通過(guò)接口,可以調(diào)用成熟的第三方功能插件為我所用(一般就是API接口)爆安,也可以根據(jù)實(shí)際需求由開(kāi)發(fā)寫(xiě)具體的接口代碼解決具體場(chǎng)合的信息傳輸問(wèn)題(一般所說(shuō)的http接口)叛复。
對(duì)后端產(chǎn)品經(jīng)理來(lái)說(shuō),http接口的使用場(chǎng)景最多扔仓。比如:公司先上線(xiàn)了OA系統(tǒng)褐奥,后上線(xiàn)了訂單系統(tǒng),訂單系統(tǒng)需要同步OA系統(tǒng)的人員組織結(jié)構(gòu)信息当辐。那么一個(gè)可行做法就是OA系統(tǒng)創(chuàng)建一個(gè)接口抖僵,訂單系統(tǒng)請(qǐng)求鲤看,獲取最新的人員結(jié)構(gòu)信息缘揪。
這個(gè)籠統(tǒng)的方案描述中,包含了這么些信息:創(chuàng)建接口义桂、請(qǐng)求接口找筝、獲取最新信息等,那么分別是什么以及有什么原則呢慷吊?下面分別討論袖裕。
2)哪一方負(fù)責(zé)創(chuàng)建接口?
在討論需求的時(shí)候溉瓶,開(kāi)發(fā)會(huì)問(wèn)哪方創(chuàng)建接口呢急鳄?有時(shí)候產(chǎn)品經(jīng)理只知道需要建接口,不知道哪個(gè)系統(tǒng)來(lái)建堰酿。
可以這樣理解疾宏,如果把數(shù)據(jù)源比成一缸水,那么接口就像是鑿的一個(gè)口触创,口只能是在缸上面的坎藐。
所以接口必須是在被請(qǐng)求的數(shù)據(jù)源這邊,由被請(qǐng)求的一方定義接口哼绑。
注意岩馍,這里的數(shù)據(jù)源是相對(duì)的數(shù)據(jù)源,就是被請(qǐng)求的一方就是數(shù)據(jù)源方抖韩。
實(shí)際上可能目標(biāo)數(shù)據(jù)在請(qǐng)求方蛀恩。比如例子中也可以是OA系統(tǒng)請(qǐng)求訂單系統(tǒng),但是如果這樣的話(huà)茂浮,接口就是訂單系統(tǒng)創(chuàng)建了赦肋。因此確切說(shuō)是被請(qǐng)求的一方創(chuàng)建接口块攒。
通俗的講就像是求婚:男方去求婚帶一百萬(wàn),女方接到后就把姑娘嫁過(guò)去佃乘,這是一來(lái)一回囱井。
女方也可以去求婚,只是是直接帶著姑娘去敲開(kāi)男方的門(mén)趣避,而后男方才把一百萬(wàn)送到女方庞呕,這也是一來(lái)一回。
3)什么是定義接口
定義接口程帕,其實(shí)就是定義缸上的出水口住练。口的大小愁拭、濾網(wǎng)讲逛、放水的頻率等,就是個(gè)規(guī)則岭埠。
這個(gè)規(guī)則約定了哪些數(shù)據(jù)是需要流過(guò)去盏混,以及流過(guò)去的條件(像門(mén)禁密碼一樣)。
定義接口就是設(shè)定口令惜论、數(shù)據(jù)范圍许赃、推送前的篩選、轉(zhuǎn)化運(yùn)算規(guī)則等馆类,這是接口的核心內(nèi)容混聊。
4)數(shù)據(jù)在哪一方做轉(zhuǎn)義?
某些時(shí)候乾巧,數(shù)據(jù)從源頭到應(yīng)用端不是原封不動(dòng)的句喜,而是轉(zhuǎn)化了。比如80分沟于、90分都是及格咳胃,可能使用者只需要兩個(gè)值:及格or不及格。
那么這就涉及到是在接收之前就轉(zhuǎn)化為是否及格社裆,還是接收之后自己轉(zhuǎn)化的問(wèn)題拙绊。
考慮的依據(jù)主要是:該數(shù)據(jù)獲取之后是否還有其他用處,只要有可能被二次使用泳秀,最好是取原數(shù)據(jù)标沪。
提前轉(zhuǎn)化的好處是,流轉(zhuǎn)的數(shù)據(jù)會(huì)變得簡(jiǎn)單直接嗜傅。但是需要注意的是轉(zhuǎn)化后數(shù)據(jù)量不一定會(huì)少金句,比如:數(shù)據(jù)源是訂單維度的,而目標(biāo)是轉(zhuǎn)化為訂單+商品維度的數(shù)據(jù)吕嘀,這就可能一條變多條了违寞。
5)是主動(dòng)獲取還是對(duì)方推送
有時(shí)候開(kāi)發(fā)還會(huì)問(wèn)是對(duì)方推贞瞒,還是我們主動(dòng)去取,這就是接口的post/ get方式問(wèn)題趁曼。
get是從服務(wù)器方請(qǐng)求數(shù)據(jù)军浆,post是向服務(wù)器方傳送數(shù)據(jù)。前面也提到了挡闰,接口交互數(shù)據(jù)可以是主動(dòng)推送乒融,也可以是請(qǐng)求獲取。
主動(dòng)推送一般是數(shù)據(jù)生產(chǎn)方一旦更新摄悯,則觸發(fā)推送赞季,將所需字段對(duì)應(yīng)值傳遞過(guò)去。
請(qǐng)求獲取就是數(shù)據(jù)需求方傳遞請(qǐng)求參數(shù)(請(qǐng)求參數(shù)一般是若干條件奢驯,比如:賬號(hào)+密碼)申钩。數(shù)據(jù)生產(chǎn)方則按照協(xié)議響應(yīng),給出滿(mǎn)足條件的數(shù)據(jù)到請(qǐng)求方(也就是返回參數(shù))瘪阁。
所以可以看出來(lái)撒遣,如果對(duì)時(shí)效要求高的,則建議生產(chǎn)方主動(dòng)推罗洗。比如產(chǎn)生一個(gè)新用戶(hù)愉舔,那么就可以理解把用戶(hù)的信息主動(dòng)推送給運(yùn)營(yíng)方使用钢猛。
如果是時(shí)效不高或者數(shù)據(jù)量大伙菜,則可以按一定頻率主動(dòng)請(qǐng)求壶愤,有利于系統(tǒng)負(fù)荷壓力穩(wěn)定勃救。
在具體使用的時(shí)候晕讲,如果你對(duì)接的系統(tǒng)比較多痊班,那么建議做一個(gè)公共接口废亭,以后誰(shuí)想用他們自己來(lái)對(duì)接就好了掌动,不然就要來(lái)一個(gè)對(duì)接一次眷射,麻煩還有風(fēng)險(xiǎn)。
另外,選擇post/ get职员,最終由雙方開(kāi)發(fā)權(quán)衡決定堪侯,但是一般而言:
get傳送的數(shù)據(jù)量較小次洼,不能大于2KB。
post傳送的數(shù)據(jù)量較大届吁,一般被默認(rèn)為不受限制再登。get安全性非常低,post安全性較高晾剖。
6)接口定義是開(kāi)發(fā)的事情锉矢,但產(chǎn)品經(jīng)理需要給出輪廓
在輸出方案的時(shí)候,接口定義的規(guī)則是什么齿尽?傳參和返回參數(shù)是什么沽损?重復(fù)傳參時(shí)是跳過(guò)還是再次獲取(一般都再獲妊贰)绵估?必傳參數(shù)是什么?是否回傳接收結(jié)果給數(shù)據(jù)生產(chǎn)方?這些都是要有大致明確并傳達(dá)給開(kāi)發(fā)測(cè)試的粘姜。
比如:每小時(shí)/次取對(duì)方表中第一頁(yè)最新的50條數(shù)據(jù)盗温。超過(guò)的數(shù)據(jù)下個(gè)小時(shí)繼續(xù)取》熳螅可以這樣設(shè)計(jì):
因?yàn)橐恍╆P(guān)鍵參數(shù)牽扯到業(yè)務(wù)的唯一性維度亿遂,這些都在產(chǎn)品經(jīng)理調(diào)研的時(shí)候獲知的,而這些可能開(kāi)發(fā)根本不知道渺杉。因此產(chǎn)品經(jīng)理要給出輪廓和大概方向蛇数。
7)數(shù)據(jù)流轉(zhuǎn)的時(shí)效
接口創(chuàng)建之后,如果是接收的對(duì)方數(shù)據(jù)庫(kù)中的信息是越,那么上線(xiàn)之后苞慢,要考慮先進(jìn)行數(shù)據(jù)的初始化(保持基礎(chǔ)數(shù)據(jù)一致)。然后確保后續(xù)雙方是同步的英妓。
同步的機(jī)制和要求是在定義方案的時(shí)候就確定的挽放。那么怎么確保同步呢?方法是兩種:觸發(fā)式和定時(shí)任務(wù)。
觸發(fā)式就是一旦一個(gè)參數(shù)值滿(mǎn)足條件蔓纠,則觸發(fā)同步辑畦。
定時(shí)任務(wù)式一般用在不知道數(shù)據(jù)源什么時(shí)候更新,需求方就要設(shè)置一個(gè)定時(shí)任務(wù)的腳本腿倚,隔一段時(shí)間查詢(xún)一次纯出。請(qǐng)求的頻率需要與更新的頻率相協(xié)調(diào)。
8)總結(jié)接口的特點(diǎn)
優(yōu)點(diǎn):時(shí)效性強(qiáng)敷燎,可以觸發(fā)式實(shí)時(shí)問(wèn)答暂筝。容易控制權(quán)限,通過(guò)傳輸層協(xié)議https硬贯,加密傳輸?shù)臄?shù)據(jù)焕襟,使得安全性提高。通用性比較強(qiáng)饭豹,無(wú)論客戶(hù)端是.net架構(gòu)鸵赖,java,python 都是可以的拄衰。
缺點(diǎn):服務(wù)器和客戶(hù)端必須同時(shí)工作它褪,當(dāng)服務(wù)器端不可用的時(shí)候,整個(gè)數(shù)據(jù)交互是不可進(jìn)行翘悉。當(dāng)傳輸數(shù)據(jù)量比較大的時(shí)候茫打,嚴(yán)重占用網(wǎng)絡(luò)帶寬,可能導(dǎo)致連接超時(shí)。使得在數(shù)據(jù)量交互的時(shí)候老赤,服務(wù)變的很不可靠饼煞。
9)相關(guān)概念擴(kuò)展
API:即“應(yīng)用程序編程接口”,是一些預(yù)先定義的函數(shù)诗越,無(wú)需訪(fǎng)問(wèn)源碼或理解內(nèi)部工作機(jī)制的細(xì)節(jié)砖瞧,即可調(diào)用的對(duì)象。比如和Windows系統(tǒng)溝通嚷狞,需要調(diào)用Windows提供得API块促。和新浪微博進(jìn)行溝通,需要調(diào)用新浪微博提供得Api床未。其實(shí)它就是一個(gè)軟件系統(tǒng)對(duì)其他軟件系統(tǒng)提供得服務(wù)竭翠。
open api:是指對(duì)外開(kāi)發(fā)的接口,比如百度地圖API薇搁、facebook的API等斋扰。
SDK(“軟體開(kāi)發(fā)工具包”):可以理解為api的集合,也就是封裝后的API為啃洋,功能更完善传货。
http接口:是基于接口的傳輸方式(HTTP協(xié)議)來(lái)命名的,當(dāng)然也有基于其他協(xié)議傳輸?shù)慕涌凇?/p>
比如:
和Windows系統(tǒng)溝通宏娄,需要調(diào)用Windows的API(CreateWindowEx, bitblt,等等)问裕,是C語(yǔ)言函數(shù)形式的接口。
和.Net框架進(jìn)行溝通孵坚,需要調(diào)用.Net提供得Api粮宛,是以C#,VB函數(shù)/類(lèi)形式的接口卖宠。和新浪微博進(jìn)行溝通巍杈,需要調(diào)用新浪微博提供得Api,是以Http請(qǐng)求形式的接口扛伍。
API接口的叫法相對(duì)http接口叫法更籠統(tǒng)和概念化一些筷畦。因此在寫(xiě)方案的時(shí)候,http接口和API接口都可以蜒秤,在具體的場(chǎng)景開(kāi)發(fā)都可以理解的汁咏。
了解更多,也可以看下這本書(shū):
2作媚、數(shù)據(jù)庫(kù)對(duì)庫(kù)同步
接口完成的是信息的傳輸,相對(duì)來(lái)說(shuō)比較保守帅刊,易于保護(hù)敏感信息纸泡。而數(shù)據(jù)庫(kù)同步實(shí)際就是表對(duì)表的共享,相對(duì)接口就大方多了,因此多發(fā)生在企業(yè)內(nèi)部?jī)尚o(wú)猜的系統(tǒng)之間女揭。
數(shù)據(jù)庫(kù)同步有這么幾種辦法:
1)使用中間表
例如:B系統(tǒng)要用A系統(tǒng)的數(shù)據(jù)蚤假,可以新建一個(gè)數(shù)據(jù)庫(kù)DB,A系統(tǒng)將數(shù)據(jù)寫(xiě)入DB吧兔,B系統(tǒng)再到數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)磷仰。
也就是將數(shù)據(jù)放進(jìn)一個(gè)中間表中,A境蔼、B兩個(gè)系統(tǒng)都對(duì)這個(gè)表有訪(fǎng)問(wèn)權(quán)限灶平。這樣的好處就是選擇性地將一大批數(shù)據(jù)共享出去。
2)直接調(diào)取對(duì)方數(shù)據(jù)表
這個(gè)方式就是在B系統(tǒng)在開(kāi)發(fā)時(shí)箍土,在代碼中加載A系統(tǒng)的數(shù)據(jù)表逢享,直接從數(shù)據(jù)表中取數(shù)據(jù)。
這就是實(shí)時(shí)拉取對(duì)方的數(shù)據(jù)吴藻,B系統(tǒng)自己本地不做表保存瞒爬。比較省,事但是耦合性較大沟堡,數(shù)據(jù)量大的時(shí)候不建議侧但。
3)同步對(duì)方的數(shù)據(jù)表
直接將對(duì)方的數(shù)據(jù)表copy一份過(guò)來(lái),并保持實(shí)時(shí)同步航罗,otter技術(shù)就是常用的一個(gè)方法俊犯。
otte可以將mysql的數(shù)據(jù)同步至另外mysql或者oracle,也支持雙向同步(即A庫(kù)同步給B庫(kù)伤哺,B庫(kù)也同步給A庫(kù))燕侠、文件同步等,主要應(yīng)用應(yīng)用是多數(shù)據(jù)中心立莉、BI系統(tǒng)抽取數(shù)據(jù)绢彤、災(zāi)備。
該方式需要DB協(xié)助配置蜓耻。也就是做了一個(gè)mysql的同步平臺(tái)(帶WEB管理界面)茫舶,在界面上,你可以定義相應(yīng)的映射規(guī)則刹淌,otter進(jìn)程就會(huì)根據(jù)你定義的規(guī)則讀取binlog饶氏,并更新到目標(biāo)庫(kù)中去。
該方式主要用于內(nèi)部系統(tǒng)之間(一般一個(gè)公司的才這樣)庫(kù)對(duì)庫(kù)的傳輸有勾,可以實(shí)現(xiàn)數(shù)據(jù)的相互同步更新疹启。建議應(yīng)用在數(shù)據(jù)量大的時(shí)候,或者基礎(chǔ)數(shù)據(jù)對(duì)周邊兄弟系統(tǒng)提供基礎(chǔ)支持的時(shí)候蔼卡。優(yōu)點(diǎn)是占用資源少喊崖,交互更加簡(jiǎn)單可靠。
當(dāng)連接B的系統(tǒng)越來(lái)越多的時(shí)候,由于數(shù)據(jù)庫(kù)的連接池是有限的荤懂,導(dǎo)致每個(gè)系統(tǒng)分配到的連接不會(huì)很多茁裙,當(dāng)系統(tǒng)越來(lái)越多的時(shí)候,可能導(dǎo)致無(wú)可用的數(shù)據(jù)庫(kù)連接节仿。
這時(shí)候otter比較適合晤锥。而兩個(gè)不同公司的系統(tǒng),不太會(huì)開(kāi)放自己的數(shù)據(jù)庫(kù)給對(duì)方連接廊宪,因?yàn)檫@樣會(huì)有安全性影響矾瘾。
3、文件包共享方式
一些第三方公司為了保密挤忙,不愿意提供接口霜威,那么會(huì)把文件存在類(lèi)似網(wǎng)盤(pán)或網(wǎng)頁(yè)上,供需求方下載册烈。
雙方系統(tǒng)約定文件服務(wù)器地址戈泼、密碼、文件命名規(guī)則赏僧、文件內(nèi)容格式等大猛,通過(guò)上傳文件到文件服務(wù)器,進(jìn)行數(shù)據(jù)交互淀零,對(duì)大數(shù)據(jù)量的也很適合挽绩。
這就是一種異步的上傳下載機(jī)制,雙方的操作割裂開(kāi)驾中,并且一旦上傳可以被多個(gè)需求方使用唉堪。
比如:第三方支付公司與需求方約定好SFTP服務(wù)器(一種文件服務(wù)器,可以理解為網(wǎng)盤(pán))的賬號(hào)密碼肩民,然后支付公司將賬單數(shù)據(jù)上傳到SFTP服務(wù)器上唠亚,那么需求方就可以登陸SFTP客戶(hù)端,進(jìn)行下載持痰、解析灶搜,然后保存使用。這也實(shí)現(xiàn)了數(shù)據(jù)在服務(wù)器之間的傳輸工窍。
實(shí)際上這些數(shù)據(jù)本身也是加密的割卖,所以只有協(xié)議的公司才能拿到解碼鑰匙。長(zhǎng)期合作的公司就會(huì)持續(xù)更新患雏,授權(quán)的公司就可以持續(xù)下載和解析鹏溯。這里就有一個(gè)下載頻率的問(wèn)題,一般使用定時(shí)任務(wù)按一定頻率去下載纵苛。并且要考慮丟包的機(jī)制剿涮。
案例:
到SFTP服務(wù)器抓取并解析WP支付平臺(tái)的賬單明細(xì)言津,方案如下:
到SFTP服務(wù)器找到文件路徑攻人,篩選出需要的類(lèi)型文件取试,打開(kāi)文件,按規(guī)則解析所需的字段怀吻,對(duì)應(yīng)寫(xiě)入本地?cái)?shù)據(jù)表瞬浓。
腳本執(zhí)行邏輯:每次抓取路徑下‘修改時(shí)間’為前一天的文件。(這里有個(gè)隱患:如果出了故障蓬坡,可能某天的數(shù)據(jù)就漏了)猿棉。
問(wèn)題:怎么防止丟抓呢?
分析:因?yàn)槭峭獠繑?shù)據(jù)屑咳,所以這里無(wú)法對(duì)源數(shù)據(jù)做“是否被抓取過(guò)”的標(biāo)注萨赁。因此建議防丟方案是增加斷抓補(bǔ)抓機(jī)制。
斷抓補(bǔ)抓機(jī)制:比如4號(hào)抓了修改時(shí)間為3號(hào)的數(shù)據(jù)兆龙。5號(hào)斷抓杖爽,則6號(hào)繼續(xù)抓取4、5號(hào)的數(shù)據(jù)紫皇。斷抓補(bǔ)抓的機(jī)制就是說(shuō)一旦某一天的數(shù)據(jù)中斷了慰安,發(fā)現(xiàn)不連續(xù),那么系統(tǒng)就自動(dòng)在下次重新抓一次聪铺,看看是否能補(bǔ)上化焕。直到三次都未取到。則不再補(bǔ)救铃剔。
該方案可以降低我方抓取故障導(dǎo)致的抓空情況撒桨。有時(shí)候開(kāi)發(fā)懶省事不愿意考慮這么多,這時(shí)候產(chǎn)品經(jīng)理要提醒他键兜。
4凤类、消息隊(duì)列MQ(Message Queue)
1)MQ概念
消息隊(duì)列技術(shù)是分布式應(yīng)用間交換信息的一種技術(shù)。目前市場(chǎng)上有很多開(kāi)源的jms消息中間件蝶押,比如ActiveMQ, OpenJMS踱蠢。
簡(jiǎn)單說(shuō)就是一方不斷把信息推到隊(duì)列中,像排隊(duì)進(jìn)隧道一樣棋电,另一方依次消費(fèi)這些信息茎截。消息隊(duì)列可駐留在內(nèi)存或磁盤(pán)上,隊(duì)列存儲(chǔ)消息直到它們被應(yīng)用程序讀走赶盔。
該方式更適用于公司內(nèi)部企锌,數(shù)據(jù)量大,規(guī)律性強(qiáng)于未,批量往來(lái)的數(shù)據(jù)撕攒。主要解決應(yīng)用解耦陡鹃,異步消息,流量削鋒等問(wèn)題抖坪。
2)以異步處理舉例說(shuō)明
用戶(hù)注冊(cè)后萍鲸,需要發(fā)注冊(cè)郵件和注冊(cè)短信。傳統(tǒng)的做法有兩種:a.串行的方式擦俐;b.并行方式
a脊阴、串行方式:
將注冊(cè)信息寫(xiě)入數(shù)據(jù)庫(kù)成功后,發(fā)送注冊(cè)郵件蚯瞧,再發(fā)送注冊(cè)短信嘿期。以上三個(gè)任務(wù)全部完成后,返回給客戶(hù)端埋合。
b备徐、并行方式:
將注冊(cè)信息寫(xiě)入數(shù)據(jù)庫(kù)成功后,發(fā)送注冊(cè)郵件的同時(shí)甚颂,發(fā)送注冊(cè)短信蜜猾。以上三個(gè)任務(wù)完成后,返回給客戶(hù)端西设。與串行的差別是瓣铣,并行的方式可以提高處理的時(shí)間。
假設(shè)三個(gè)業(yè)務(wù)節(jié)點(diǎn)每個(gè)使用50毫秒鐘贷揽,不考慮網(wǎng)絡(luò)等其他開(kāi)銷(xiāo)棠笑,則串行方式的時(shí)間是150毫秒,并行的時(shí)間可能是100毫秒禽绪。
因?yàn)镃PU在單位時(shí)間內(nèi)處理的請(qǐng)求數(shù)是一定的蓖救,假設(shè)CPU1秒內(nèi)吞吐量是100次。則串行方式1秒內(nèi)CPU可處理的請(qǐng)求量是7次(1000/150)印屁。并行方式處理的請(qǐng)求量是10次(1000/100)
小結(jié):如以上案例描述循捺,傳統(tǒng)的方式系統(tǒng)的性能(并發(fā)量,吞吐量雄人,響應(yīng)時(shí)間)會(huì)有瓶頸从橘。如何解決這個(gè)問(wèn)題呢?
引入消息隊(duì)列础钠,異步處理恰力。改造后的架構(gòu)如下:
按照以上約定,用戶(hù)的響應(yīng)時(shí)間相當(dāng)于是注冊(cè)信息寫(xiě)入數(shù)據(jù)庫(kù)的時(shí)間旗吁,也就是50毫秒踩萎。注冊(cè)郵件,發(fā)送短信寫(xiě)入消息隊(duì)列后很钓,直接返回香府,因此寫(xiě)入消息隊(duì)列的速度很快董栽,基本可以忽略,因此用戶(hù)的響應(yīng)時(shí)間可能是50毫秒企孩。因此架構(gòu)改變后锭碳,系統(tǒng)的吞吐量提高到每秒20 QPS。比串行提高了3倍柠硕,比并行提高了兩倍工禾。
在設(shè)計(jì)方案的時(shí)候要注意異常情況的處理機(jī)制运提。比如:首次消費(fèi)失敾热帷?
如果第一次數(shù)據(jù)消費(fèi)的時(shí)候民泵,無(wú)法識(shí)別沒(méi)有匹配上癣丧,但是又想下次再消費(fèi)一次看是否匹配的上怎么辦?可以設(shè)定機(jī)制:無(wú)法識(shí)別的則重新插到隊(duì)列后面繼續(xù)推送栈妆。
如果一直循環(huán)仍消費(fèi)不掉信息積壓怎么辦胁编?
設(shè)定處理機(jī)制:超過(guò)一定積壓數(shù)據(jù)量或者循環(huán)時(shí)間過(guò)長(zhǎng)則進(jìn)行報(bào)警。
3)MQ鳞尔、文件包共享嬉橙、接口的對(duì)比
MQ推送過(guò)去之后,是否推送成功無(wú)需對(duì)方再用MQ返回寥假,因?yàn)橥频街虚g站就意味著我方能做的事情已經(jīng)做完市框。
而接口是一來(lái)一往才知道是否成功的,也就是要返回一個(gè)信息糕韧。這點(diǎn)與mq是不一樣的枫振。但是如果非要對(duì)方再返回是否接受成功的話(huà),那么就要做反向MQ萤彩,這相當(dāng)于另一個(gè)獨(dú)立的MQ粪滤。
文件包共享也不需要反饋機(jī)制,因此傳到了文件服務(wù)器之后雀扶,數(shù)據(jù)方的事情就做完了杖小。
隊(duì)列的一個(gè)信息只能被消費(fèi)一次,不同系統(tǒng)不能共同消費(fèi)一個(gè)隊(duì)列愚墓。因此如果對(duì)接多個(gè)系統(tǒng)則要多次創(chuàng)建MQ予权。而接口可以創(chuàng)建一個(gè),讓其他很多系統(tǒng)調(diào)取转绷。
在訂單系統(tǒng)對(duì)接各個(gè)銷(xiāo)售網(wǎng)站和平臺(tái)的時(shí)候就可以采用這樣的機(jī)制伟件,避免多次對(duì)接。文件包共享也是可以上傳一次议经,供多個(gè)需求方下載斧账。這點(diǎn)和接口有相似之處谴返,是MQ所不具備的。
5咧织、其他手段
數(shù)據(jù)傳輸包含了數(shù)據(jù)信息的獲取和寫(xiě)入嗓袱,其實(shí)除了線(xiàn)上的自動(dòng)機(jī)制,還有很多土辦法习绢,在后端產(chǎn)品系統(tǒng)中也是常使用的渠抹。
1)導(dǎo)入導(dǎo)出
場(chǎng)景:沒(méi)有辦法做系統(tǒng)之間的對(duì)接,但是線(xiàn)下能獲得數(shù)據(jù)闪萄。數(shù)據(jù)量不太大梧却,且有規(guī)則數(shù)據(jù)。則可以通過(guò)導(dǎo)入的方式败去。
文檔一般用csv格式放航,該格式文件較小,兼容性好圆裕,然后需要定義好excel表格對(duì)應(yīng)字段的關(guān)系广鳍,比如A列對(duì)應(yīng)字段‘name’,B列對(duì)應(yīng)字段'age'吓妆。
上傳時(shí)需要對(duì)文件檢驗(yàn)赊时,比如格式不對(duì)、必填項(xiàng)為空等行拢,建議一旦一處錯(cuò)誤祖秒,就全部不予導(dǎo)入。并返回錯(cuò)誤提示剂陡,修改后繼續(xù)導(dǎo)入狈涮。
若數(shù)據(jù)太大(與服務(wù)器的性能也有關(guān)系,比如超過(guò)一萬(wàn)條)鸭栖,可以采用異步上傳機(jī)制歌馍,就是上傳之后不立即執(zhí)行寫(xiě)入,而是后臺(tái)自動(dòng)分批寫(xiě)入晕鹊。
2)爬取
作為數(shù)據(jù)需求方松却,獲取數(shù)據(jù)可以通過(guò)協(xié)商接口的方式、SFTP解析的方式溅话、或者直接爬取的方式晓锻。比如需要獲取第三方網(wǎng)站商標(biāo)庫(kù)中最新商標(biāo)名稱(chēng)、注冊(cè)地飞几、logo砚哆、授權(quán)期限等信息,如果該網(wǎng)站不給于開(kāi)放的接口授權(quán)屑墨,可能就需要我們開(kāi)發(fā)寫(xiě)爬蟲(chóng)代碼爬仍晁(當(dāng)然有的商業(yè)數(shù)據(jù)也是帶有反爬機(jī)制的纷铣,這就看誰(shuí)道高一尺魔高一丈了)。
三战转、數(shù)據(jù)傳輸?shù)奶幚頇C(jī)制
?1搜立、數(shù)據(jù)同步的觸發(fā)機(jī)制
前面提到了數(shù)據(jù)獲取的方式,那么數(shù)據(jù)獲取頻次或者觸發(fā)機(jī)制是怎么樣的呢槐秧?這要根據(jù)應(yīng)用場(chǎng)景來(lái)設(shè)定方案啄踊,但是一般都是要求持續(xù)獲取的。
一種方式是操作事件觸發(fā)刁标,比如頁(yè)面的按鈕點(diǎn)擊則觸發(fā)傳遞最新?tīng)顟B(tài)颠通。這種的時(shí)效性比較高,但是也會(huì)由于并發(fā)而增加系統(tǒng)負(fù)荷命雀。
如果對(duì)時(shí)效要求不高就可以采用異步機(jī)制蒜哀。比如使用腳本監(jiān)控。設(shè)定腳本的運(yùn)行頻率吏砂,當(dāng)讀取到更新時(shí)間為頻寬內(nèi)的數(shù)據(jù),則將其捕獲并傳輸乘客。定時(shí)腳本也叫定時(shí)任務(wù)等狐血。定時(shí)腳本在后端是很常用的。
比如說(shuō)每次獲取A系統(tǒng)6小時(shí)內(nèi)更新的數(shù)據(jù)易核,那么每2小時(shí)取一次的話(huà)是沒(méi)問(wèn)題的匈织。但是若每7小時(shí)獲取一次就會(huì)漏掉1小時(shí)的數(shù)據(jù)。因此一定是每次獲取的數(shù)據(jù)時(shí)間區(qū)間牡直,要高于數(shù)據(jù)獲取的時(shí)間間隔缀匕。
當(dāng)然用時(shí)間是一種維度,更安全的是用標(biāo)示性字段碰逸。比如每次獲取is_got為0的數(shù)據(jù)乡小。前臺(tái)是is_got做表索引(索引前面講到過(guò)),這樣遍歷(遍歷約等于全表查詢(xún))數(shù)據(jù)庫(kù)的時(shí)候就不會(huì)太慢饵史。
2满钟、是否異步執(zhí)行數(shù)據(jù)處理
如果獲取后還要在本地進(jìn)行規(guī)則運(yùn)算,則最好先落地到中間表胳喷,再由中間表寫(xiě)入最終表湃番。也就是異步寫(xiě)入。
比如:按照訂單+包裹號(hào)維度吭露,從物流系統(tǒng)獲取運(yùn)費(fèi)到財(cái)務(wù)系統(tǒng)吠撮,然后財(cái)務(wù)系統(tǒng)再將其分?jǐn)偟桨纳唐飞厦妫愠雒總€(gè)商品分?jǐn)偟倪\(yùn)費(fèi)金額讲竿。
這時(shí)候就很容易出錯(cuò)泥兰,因?yàn)榉謹(jǐn)傄?guī)則是個(gè)算法择浊,算法就帶有規(guī)則的可變動(dòng)性。一旦分?jǐn)傄?guī)則的參數(shù)不準(zhǔn)確逾条,或者算法結(jié)構(gòu)變化琢岩,都會(huì)導(dǎo)致最終分?jǐn)偟倪\(yùn)費(fèi)金額錯(cuò)誤。那么這時(shí)候追查錯(cuò)誤原因并修復(fù)數(shù)據(jù)就很麻煩师脂。
所以在進(jìn)行分?jǐn)傊暗?祝嚷涞氐截?cái)務(wù)系統(tǒng)的臨時(shí)表(中間表)中,然后獲取數(shù)據(jù)完成吃警。再進(jìn)行寫(xiě)入分?jǐn)傔\(yùn)費(fèi)的操作糕篇。
除了上述方便查錯(cuò)誤原因外(有種數(shù)據(jù)清洗的意思),這種異步操作同時(shí)也確保了較少的偶聯(lián)酌心,不至于一個(gè)環(huán)節(jié)出錯(cuò)拌消,則聯(lián)動(dòng)出錯(cuò)。同時(shí)它作為一個(gè)基礎(chǔ)數(shù)據(jù)安券,也可以被其他功能調(diào)用墩崩。若數(shù)據(jù)量萬(wàn)級(jí)以上的,必須這樣做侯勉。
3鹦筹、判重機(jī)制
數(shù)據(jù)通道搭建好之后,數(shù)據(jù)流往往是持續(xù)獲的址貌。而數(shù)據(jù)源在別人那里铐拐,可能會(huì)被增刪改,因此常常有相似或相關(guān)的數(shù)據(jù)進(jìn)來(lái)练对。
在寫(xiě)入本地表的時(shí)候遍蟋,不管是覆蓋、更新還是插入螟凭,都是以確定若干字段做為判重的標(biāo)示為前題的虚青。
比如職工信息表:(姓名+手機(jī)號(hào)+性別+家鄉(xiāng)+身份證號(hào))。(姓名+手機(jī)號(hào)+性別+家鄉(xiāng))這幾個(gè)字段對(duì)一個(gè)職工不一定唯一赂摆,但是身份證號(hào)就是唯一的挟憔。因此如果我們更新這里的數(shù)據(jù),就以身份證號(hào)為唯一標(biāo)示烟号。
比如獲取到同一個(gè)身份證號(hào)的手機(jī)號(hào)與我們的數(shù)據(jù)庫(kù)的不同绊谭,則更新。遇到我們的數(shù)據(jù)庫(kù)不存在的身份證號(hào)碼則插入汪拥。
某些時(shí)候無(wú)法確定那幾個(gè)是唯一字段达传,則可以添加一個(gè)備用字段,人為定義其取值規(guī)則,然后作為去重字段宪赶,比如這個(gè)字段叫unique_code宗弯,取數(shù)據(jù)源表的主鍵+日期,(或者直接就取源表的id搂妻,也就是外鍵)蒙保。
有了判重字段(也就是數(shù)據(jù)唯一的字段),就可以進(jìn)行更新欲主、插入或者跳過(guò)規(guī)則設(shè)定了邓厕。
注意:若一段時(shí)間之后,改變了表的去重規(guī)則扁瓢,則需要考慮到歷史數(shù)據(jù)對(duì)新數(shù)據(jù)的影響详恼,因?yàn)槎叩呐兄鼐S度不一樣,可能會(huì)進(jìn)來(lái)和以前的歷史數(shù)據(jù)沖突的交叉數(shù)據(jù)引几。
4昧互、獲取到數(shù)據(jù)之后,如果使用?
一種是直接在頁(yè)面展示伟桅,不保存在本地?cái)?shù)據(jù)庫(kù)中敞掘。相當(dāng)于每刷新一次頁(yè)面則通過(guò)接口調(diào)取一次對(duì)方的數(shù)據(jù)展示。但這種從性能和場(chǎng)景上都是比較少的贿讹,一般都是先保存到本地?cái)?shù)據(jù)庫(kù)上渐逃,自己本地各種調(diào)用。
對(duì)于先保存到本地的情況民褂,有兩個(gè)問(wèn)題要考慮:是否異步保存,和如何確保同源同步疯潭。
5赊堪、處理日志
數(shù)據(jù)日志:目的是記錄數(shù)據(jù)的來(lái)龍去脈,追溯以分析問(wèn)題竖哩。
日志要記錄三個(gè)主要事項(xiàng):數(shù)據(jù)源系統(tǒng)是否提供數(shù)據(jù)哭廉、目標(biāo)系統(tǒng)是否接收到數(shù)據(jù)、目標(biāo)系統(tǒng)是否寫(xiě)入了數(shù)據(jù)相叁。
產(chǎn)品經(jīng)理告訴開(kāi)發(fā)加數(shù)據(jù)捕獲日志的時(shí)候遵绰,需要告知是否存到表里,因?yàn)橄到y(tǒng)一般都有一個(gè)類(lèi)似緩存一樣的日記增淹,只是會(huì)定期清理的椿访。只有保存下來(lái)才能一直記錄和追溯。
開(kāi)發(fā)后臺(tái)本身是有數(shù)據(jù)log日志的虑润,因?yàn)閘og4j開(kāi)源代碼定義了5個(gè)主要級(jí)別的log:FATAL成玫、ERROR、WARN、INFO哭当、DEBUG猪腕,一般情況下,開(kāi)發(fā)都會(huì)自覺(jué)配置INFO或DEBUG級(jí)別的日志钦勘,以方便查數(shù)據(jù)陋葡。
但是代碼中的kog保存時(shí)間不會(huì)太長(zhǎng),比如一個(gè)月就會(huì)清除了彻采。因此如果需要保留的時(shí)間長(zhǎng)腐缤,則可以將其保存到本地?cái)?shù)據(jù)庫(kù)。
根據(jù)實(shí)習(xí)需要颊亮,存了數(shù)據(jù)庫(kù)就可以做成頁(yè)面柴梆,展示給用戶(hù)看,比如可以從以下維度展示:
四终惑、數(shù)據(jù)傳輸?shù)淖⒁馐马?xiàng)
1绍在、目標(biāo)數(shù)據(jù)表最好和中間表的維度一致
假設(shè)從A系統(tǒng)獲取的數(shù)據(jù)存入B系統(tǒng),先落地到中間表b雹有,然后經(jīng)過(guò)一些列運(yùn)算后將數(shù)據(jù)從b寫(xiě)入到b'表偿渡。
注意b和b'表的去重字段要對(duì)應(yīng)起來(lái),并傳遞下去霸奕。因?yàn)榫S度相同溜宽,做到一對(duì)一,方便實(shí)現(xiàn)異常數(shù)據(jù)溯源质帅。
2适揉、不同入口寫(xiě)入同一類(lèi)型數(shù)據(jù)時(shí),如何與自身入口的數(shù)據(jù)去重煤惩,且與其他入口的數(shù)據(jù)互相去重嫉嘀?
案例:
有新舊兩個(gè)不同的寫(xiě)入程序,寫(xiě)數(shù)據(jù)到利潤(rùn)表魄揉,寫(xiě)入的都是‘退件入庫(kù)’利潤(rùn)類(lèi)型剪侮,是殊途同歸。不巧的是兩個(gè)寫(xiě)入入口各自有本身的去重規(guī)則洛退,彼此去重的規(guī)則不能通用:假設(shè)入口1對(duì)應(yīng)的去重字段是A+B瓣俯,入口2寫(xiě)入的去重字段是B+C。
這就意味著同一個(gè)數(shù)據(jù)如果分多次寫(xiě)入兵怯,有可能從兩個(gè)入口都會(huì)寫(xiě)入彩匕。如何實(shí)現(xiàn)避免重復(fù)寫(xiě)入是核心問(wèn)題。
我們首先考慮的是摇零,如果一條源信息從一個(gè)入口已經(jīng)寫(xiě)入了利潤(rùn)表推掸,那么就不能從另一個(gè)入口再寫(xiě)桶蝎。
其次,如果從入口1寫(xiě)入一次谅畅,那么后面源數(shù)據(jù)更新再次觸發(fā)寫(xiě)入的時(shí)候(判重登渣,確定是插入還是更新),就還要從入口1寫(xiě)毡泻。也就是一旦從一個(gè)入口寫(xiě)入胜茧,后面該數(shù)據(jù)的變更觸發(fā)的再次寫(xiě)入也只能從這個(gè)入口繼續(xù)變更。
只有這樣才能保證這個(gè)數(shù)據(jù)不重復(fù)仇味。好比先找到是哪家的孩子呻顽,再確定是第幾個(gè)孩子,且只能是基于這家內(nèi)部去確認(rèn)丹墨。
方案一:比如入口1遇到一個(gè)待寫(xiě)入的數(shù)據(jù)廊遍,則先按自己的去重字段A+B校驗(yàn)。如果發(fā)現(xiàn)不存在該數(shù)據(jù)贩挣,則再按照入口2的去重字段B+C(這個(gè)事先是知道的)判斷是否存在喉前,若也不存在,則回到入口1寫(xiě)入王财。若存在卵迂,則入口1不在寫(xiě)入,且結(jié)束進(jìn)程(因?yàn)槿肟?會(huì)觸發(fā)寫(xiě)入該數(shù)據(jù)的)绒净。
方案二:比如入口1遇到一個(gè)待寫(xiě)入的數(shù)據(jù)见咒,則先按入口2的去重字段B+C校驗(yàn)。
查看對(duì)方入口下是否有重復(fù)數(shù)據(jù)挂疆,有改览,則本入口不寫(xiě)(繼續(xù)按對(duì)方的路徑寫(xiě));無(wú)缤言,則自己的路徑寫(xiě)恃疯。顯然方案二的判斷路徑更短,相對(duì)好一點(diǎn)墨闲。
3、同步基礎(chǔ)數(shù)據(jù)的時(shí)候是否提前過(guò)濾
這個(gè)在上面內(nèi)容中也提到過(guò)郑口。比如:A系統(tǒng)維護(hù)了員工的基礎(chǔ)信息鸳碧,其中有個(gè)狀態(tài)為【是否有效】,只有有效狀態(tài)的才能在整個(gè)系統(tǒng)中看得到才是生效的犬性。B系統(tǒng)要取用員工信息的數(shù)據(jù)瞻离,但不做數(shù)據(jù)維護(hù)。那么是否只取啟用狀態(tài)的數(shù)據(jù)到B乒裆,還是不區(qū)分狀態(tài)都取呢套利?
答案是:在數(shù)據(jù)量差異不大的情況下,取全量。
原因之一就是肉迫,若啟用狀態(tài)的用戶(hù)忽然被A系統(tǒng)禁用验辞,那么可能該用戶(hù)在B系統(tǒng)的生產(chǎn)數(shù)據(jù)報(bào)錯(cuò),這時(shí)候到中間表看狀態(tài)就可以看出來(lái)問(wèn)題喊衫,而不需跨系統(tǒng)或跨部門(mén)溝通查證跌造。