系統(tǒng)之間的數(shù)據(jù)對接和傳輸,產(chǎn)品經(jīng)理視角的萬字總結(jié)
編輯導(dǎo)語:一個(gè)孤立的系統(tǒng)即使錄入了再多的數(shù)據(jù),其本身的作用也是有限的,只有和其他系統(tǒng)產(chǎn)生關(guān)聯(lián),互相之間進(jìn)行數(shù)據(jù)對接和傳輸,才能發(fā)揮其真正的功能和作用。本篇文章中,作者為我們分析總結(jié)了數(shù)據(jù)傳輸?shù)膱鼍昂鸵饬x、數(shù)據(jù)傳輸?shù)姆绞?、?shù)據(jù)傳輸?shù)奶幚頇C(jī)制以及數(shù)據(jù)傳輸?shù)淖⒁馐马?xiàng)。
一個(gè)系統(tǒng)裝再多數(shù)據(jù),不與其他系統(tǒng)交互,那也是孤島系統(tǒng)。一個(gè)系統(tǒng)若很外向,不斷撩撥周圍的系統(tǒng),也樂意被撩撥,成為了眾系統(tǒng)中的“交際花”,那么這貨基本就是中臺的性質(zhì)。
而更多的系統(tǒng)是介于上述兩種極端之間的,像人一樣,自己搞生產(chǎn),也要參與社交——就是系統(tǒng)之間的數(shù)據(jù)對接。對接的本質(zhì)是為了實(shí)現(xiàn)數(shù)據(jù)信息的傳輸,在后端產(chǎn)品的世界里,各子系統(tǒng)之間,或與外部系統(tǒng)之間的對接非常常見。
作為產(chǎn)品經(jīng)理,不僅要知道數(shù)據(jù)從哪來,還要理清楚獲取數(shù)據(jù)之后的握手方式、運(yùn)算邏輯、異常規(guī)則、容錯(cuò)機(jī)制、數(shù)據(jù)日志等等。
本文嘗試聊聊如下話題:
- 數(shù)據(jù)傳輸?shù)膱鼍昂鸵饬x
- 數(shù)據(jù)傳輸?shù)姆绞?/li>
- 數(shù)據(jù)傳輸?shù)奶幚頇C(jī)制
- 數(shù)據(jù)傳輸?shù)淖⒁馐马?xiàng)
一、?數(shù)據(jù)傳輸?shù)膱鼍昂鸵饬x
1. 數(shù)據(jù)傳輸?shù)膽?yīng)用場景
- 前端和后端本身無時(shí)不刻的數(shù)據(jù)互動;
- 公司的各個(gè)系統(tǒng)之間的信息共享:比如,式系統(tǒng)部署之后,就需要各個(gè)系統(tǒng)模塊之間進(jìn)行數(shù)據(jù)的配合,比如訂單系統(tǒng)的庫存扣減數(shù)據(jù)要同步給備貨系統(tǒng)進(jìn)行采購;
- 與第三方平臺的對接:比如入駐第三方銷售平臺亞馬遜之后,店家可能自己需要管理自己的訂單,這時(shí)候就要從亞馬遜平臺獲取訂單數(shù)據(jù),也就是抓取;
- 調(diào)用現(xiàn)成的公共插件:避免重復(fù)造輪子,市場上很多開放性的功能插件可以調(diào)用或接入,比如接入百度地圖的API,接入微信小程序的二次開發(fā)。
2. 數(shù)據(jù)傳輸?shù)囊饬x
- 不重復(fù)生產(chǎn)數(shù)據(jù)庫,避免資源和功能的浪費(fèi);
- 統(tǒng)一數(shù)據(jù)的維護(hù)或生產(chǎn)源頭,避免數(shù)據(jù)不同步:比如同一個(gè)公司的兩個(gè)系統(tǒng)都要用人員信息架構(gòu)數(shù)據(jù),如果各自都能維護(hù),勢必出現(xiàn)不一致,也浪費(fèi)資源;
- 別人家的數(shù)據(jù),自己沒辦法生產(chǎn);
- 復(fù)用現(xiàn)成的輪子,API或SDK共享(可能自己也發(fā)明不出來)。
二、數(shù)據(jù)傳輸?shù)姆绞?/h2>
數(shù)據(jù)傳輸?shù)姆绞?,作為產(chǎn)品經(jīng)理我將其分為:接口傳輸、中間件傳輸、message方式傳輸?shù)取I㈤_了說,比如:MQ(隊(duì)列)、HTTP接口、otter、文件共享傳輸?shù)龋恳环N又有細(xì)分的方式和適合的場景。
1. 接口
這是一種傳統(tǒng)的問答式的傳輸方式,是典型才c/s 交互模式。相當(dāng)于一臺客戶機(jī),一臺服務(wù)器(注:這里的客戶機(jī)或服務(wù)器根據(jù)數(shù)據(jù)的提供方和接收方相對而言的,并不一定是實(shí)際的)。
目前我們常用的http調(diào)用、java遠(yuǎn)程調(diào)用、webserivces 都屬于這種方式,只不過,不同的就是傳輸協(xié)議以及報(bào)文格式的區(qū)別。
1)接口的作用
通過接口,可以調(diào)用成熟的第三方功能插件為我所用(一般就是API接口),也可以根據(jù)實(shí)際需求由開發(fā)寫具體的接口代碼解決具體場合的信息傳輸問題(一般所說的http接口)。
對后端產(chǎn)品經(jīng)理來說,http接口的使用場景最多。比如:公司先上線了OA系統(tǒng),后上線了訂單系統(tǒng),訂單系統(tǒng)需要同步OA系統(tǒng)的人員組織結(jié)構(gòu)信息。那么一個(gè)可行做法就是OA系統(tǒng)創(chuàng)建一個(gè)接口,訂單系統(tǒng)請求,獲取最新的人員結(jié)構(gòu)信息。
這個(gè)籠統(tǒng)的方案描述中,包含了這么些信息:創(chuàng)建接口、請求接口、獲取最新信息等,那么分別是什么以及有什么原則呢?下面分別討論。
2)哪一方負(fù)責(zé)創(chuàng)建接口?
在討論需求的時(shí)候,開發(fā)會問哪方創(chuàng)建接口呢?有時(shí)候產(chǎn)品經(jīng)理只知道需要建接口,不知道哪個(gè)系統(tǒng)來建??梢赃@樣理解,如果把數(shù)據(jù)源比成一缸水,那么接口就像是鑿的一個(gè)口,口只能是在缸上面的。所以接口必須是在被請求的數(shù)據(jù)源這邊,由被請求的一方定義接口。
注意,這里的數(shù)據(jù)源是相對的數(shù)據(jù)源,就是被請求的一方就是數(shù)據(jù)源方。實(shí)際上可能目標(biāo)數(shù)據(jù)在請求方。比如例子中也可以是OA系統(tǒng)請求訂單系統(tǒng),但是如果這樣的話,接口就是訂單系統(tǒng)創(chuàng)建了,因此確切說是被請求的一方創(chuàng)建接口。
通俗的講就像是求婚:男方去求婚帶一百萬,女方接到后就把姑娘嫁過去,這是一來一回。女方也可以去求婚,只是是直接帶著姑娘去敲開男方的門,而后男方才把一百萬送到女方,這也是一來一回。
3)什么是定義接口
定義接口,其實(shí)就是定義缸上的出水口??诘拇笮 V網(wǎng)、放水的頻率等…就是個(gè)規(guī)則。這個(gè)規(guī)則約定了哪些數(shù)據(jù)是需要流過去,以及流過去的條件(像門禁密碼一樣)。
定義接口就是設(shè)定口令、數(shù)據(jù)范圍、推送前的篩選、轉(zhuǎn)化運(yùn)算規(guī)則等,這是接口的核心內(nèi)容。
4)數(shù)據(jù)在哪一方做轉(zhuǎn)義?
某些時(shí)候,數(shù)據(jù)從源頭到應(yīng)用端不是原封不動的,而是轉(zhuǎn)化了。比如80分、90分都是及格,可能使用者只需要兩個(gè)值:及格or不及格。
那么這就涉及到是在接收之前就轉(zhuǎn)化為是否及格,還是接收之后自己轉(zhuǎn)化的問題??紤]的依據(jù)主要是:該數(shù)據(jù)獲取之后是否還有其他用處,只要有可能被二次使用,最好是取原數(shù)據(jù)。
提前轉(zhuǎn)化的好處是,流轉(zhuǎn)的數(shù)據(jù)會變得簡單直接。但是需要注意的是轉(zhuǎn)化后數(shù)據(jù)量不一定會少,比如:數(shù)據(jù)源是訂單維度的,而目標(biāo)是轉(zhuǎn)化為訂單+商品維度的數(shù)據(jù),這就可能一條變多條了。
5)是主動獲取還是對方推送
有時(shí)候開發(fā)還會問是對方推,還是我們主動去取,這就是接口的post/ get方式問題。
get是從服務(wù)器方請求數(shù)據(jù),post是向服務(wù)器方傳送數(shù)據(jù)。前面也提到了,接口交互數(shù)據(jù)可以是主動推送,也可以是請求獲取。
主動推送一般是數(shù)據(jù)生產(chǎn)方一旦更新,則觸發(fā)推送,將所需字段對應(yīng)值傳遞過去;請求獲取就是數(shù)據(jù)需求方傳遞請求參數(shù)(請求參數(shù)一般是若干條件,比如:賬號+密碼)。數(shù)據(jù)生產(chǎn)方則按照協(xié)議響應(yīng),給出滿足條件的數(shù)據(jù)到請求方(也就是返回參數(shù))。
所以可以看出來,如果對時(shí)效要求高的,則建議生產(chǎn)方主動推。比如產(chǎn)生一個(gè)新用戶,那么就可以理解把用戶的信息主動推送給運(yùn)營方使用。如果是時(shí)效不高或者數(shù)據(jù)量大,則可以按一定頻率主動請求,有利于系統(tǒng)負(fù)荷壓力穩(wěn)定。
在具體使用的時(shí)候,如果你對接的系統(tǒng)比較多,那么建議做一個(gè)公共接口,以后誰想用他們自己來對接就好了,不然就要來一個(gè)對接一次,麻煩還有風(fēng)險(xiǎn)。
另外,選擇post/ get,最終由雙方開發(fā)權(quán)衡決定,但是一般而言:get傳送的數(shù)據(jù)量較小,不能大于2KB。post傳送的數(shù)據(jù)量較大,一般被默認(rèn)為不受限制。get安全性非常低,post安全性較高。
6)接口定義是開發(fā)的事情,但產(chǎn)品經(jīng)理需要給出輪廓
在輸出方案的時(shí)候,接口定義的規(guī)則是什么?傳參和返回參數(shù)是什么?重復(fù)傳參時(shí)是跳過還是再次獲?。ㄒ话愣荚佾@?。勘貍鲄?shù)是什么?是否回傳接收結(jié)果給數(shù)據(jù)生產(chǎn)方?這些都是要有大致明確并傳達(dá)給開發(fā)測試的。
比如:每小時(shí)/次取對方表中第一頁最新的50條數(shù)據(jù)。超過的數(shù)據(jù)下個(gè)小時(shí)繼續(xù)取,可以這樣設(shè)計(jì):
因?yàn)橐恍╆P(guān)鍵參數(shù)牽扯到業(yè)務(wù)的唯一性維度,這些都在產(chǎn)品經(jīng)理調(diào)研的時(shí)候獲知的,而這些可能開發(fā)根本不知道,因此產(chǎn)品經(jīng)理要給出輪廓和大概方向。
7)數(shù)據(jù)流轉(zhuǎn)的時(shí)效
接口創(chuàng)建之后,如果是接收的對方數(shù)據(jù)庫中的信息,那么上線之后,要考慮先進(jìn)行數(shù)據(jù)的初始化(保持基礎(chǔ)數(shù)據(jù)一致),然后確保后續(xù)雙方是同步的。
同步的機(jī)制和要求是在定義方案的時(shí)候就確定的,那么怎么確保同步呢?方法是兩種:觸發(fā)式和定時(shí)任務(wù)。
- 觸發(fā)式:就是一旦一個(gè)參數(shù)值滿足條件,則觸發(fā)同步;
- 定時(shí)任務(wù)式:一般用在不知道數(shù)據(jù)源什么時(shí)候更新,需求方就要設(shè)置一個(gè)定時(shí)任務(wù)的腳本,隔一段時(shí)間查詢一次,請求的頻率需要與更新的頻率相協(xié)調(diào)。
8)總結(jié)接口的特點(diǎn)
- 優(yōu)點(diǎn):時(shí)效性強(qiáng),可以觸發(fā)式實(shí)時(shí)問答。容易控制權(quán)限,通過傳輸層協(xié)議https,加密傳輸?shù)臄?shù)據(jù),使得安全性提高。通用性比較強(qiáng),無論客戶端是.net架構(gòu),java,python 都是可以的。
- 缺點(diǎn):服務(wù)器和客戶端必須同時(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ù),無需訪問源碼或理解內(nèi)部工作機(jī)制的細(xì)節(jié),即可調(diào)用的對象。比如和Windows系統(tǒng)溝通,需要調(diào)用Windows提供得API。和新浪微博進(jìn)行溝通,需要調(diào)用新浪微博提供得Api,其實(shí)它就是一個(gè)軟件系統(tǒng)對其他軟件系統(tǒng)提供得服務(wù)。
open api:是指對外開發(fā)的接口,比如百度地圖API、facebook的API等。
SDK(“軟體開發(fā)工具包”):可以理解為api的集合,也就是封裝后的API為,功能更完善。
http接口:是基于接口的傳輸方式(HTTP協(xié)議)來命名的,當(dāng)然也有基于其他協(xié)議傳輸?shù)慕涌凇?/p>
比如:
和Windows系統(tǒng)溝通,需要調(diào)用Windows的API(CreateWindowEx, bitblt,等等),是C語言函數(shù)形式的接口。
和.Net框架進(jìn)行溝通,需要調(diào)用.Net提供得Api,是以C#,VB函數(shù)/類形式的接口。和新浪微博進(jìn)行溝通,需要調(diào)用新浪微博提供得Api,是以Http請求形式的接口。
API接口的叫法相對http接口叫法更籠統(tǒng)和概念化一些。因此在寫方案的時(shí)候,http接口和API接口都可以,在具體的場景開發(fā)都可以理解的。
2. 數(shù)據(jù)庫對庫同步
接口完成的是信息的傳輸,相對來說比較保守,易于保護(hù)敏感信息。而數(shù)據(jù)庫同步實(shí)際就是表對表的共享,相對接口就大方多了,因此多發(fā)生在企業(yè)內(nèi)部兩小無猜的系統(tǒng)之間。
數(shù)據(jù)庫同步有這么幾種辦法:
1)使用中間表
例如:B系統(tǒng)要用A系統(tǒng)的數(shù)據(jù),可以新建一個(gè)數(shù)據(jù)庫DB,A系統(tǒng)將數(shù)據(jù)寫入DB,B系統(tǒng)再到數(shù)據(jù)庫中讀取數(shù)據(jù)。
也就是將數(shù)據(jù)放進(jìn)一個(gè)中間表中,A、B兩個(gè)系統(tǒng)都對這個(gè)表有訪問權(quán)限,這樣的好處就是選擇性地將一大批數(shù)據(jù)共享出去。
2)直接調(diào)取對方數(shù)據(jù)表
這個(gè)方式就是在B系統(tǒng)在開發(fā)時(shí),在代碼中加載A系統(tǒng)的數(shù)據(jù)表,直接從數(shù)據(jù)表中取數(shù)據(jù)。這就是實(shí)時(shí)拉取對方的數(shù)據(jù),B系統(tǒng)自己本地不做表保存。比較省,事但是耦合性較大,數(shù)據(jù)量大的時(shí)候不建議。
3)同步對方的數(shù)據(jù)表
直接將對方的數(shù)據(jù)表copy一份過來,并保持實(shí)時(shí)同步,otter技術(shù)就是常用的一個(gè)方法。
otte可以將mysql的數(shù)據(jù)同步至另外mysql或者oracle,也支持雙向同步(即A庫同步給B庫,B庫也同步給A庫)、文件同步等,主要應(yīng)用應(yīng)用是多數(shù)據(jù)中心、BI系統(tǒng)抽取數(shù)據(jù)、災(zāi)備。
該方式需要DB協(xié)助配置。也就是做了一個(gè)mysql的同步平臺(帶WEB管理界面),在界面上,你可以定義相應(yīng)的映射規(guī)則,otter進(jìn)程就會根據(jù)你定義的規(guī)則讀取binlog,并更新到目標(biāo)庫中去。
該方式主要用于內(nèi)部系統(tǒng)之間(一般一個(gè)公司的才這樣)庫對庫的傳輸,可以實(shí)現(xiàn)數(shù)據(jù)的相互同步更新。建議應(yīng)用在數(shù)據(jù)量大的時(shí)候,或者基礎(chǔ)數(shù)據(jù)對周邊兄弟系統(tǒng)提供基礎(chǔ)支持的時(shí)候。優(yōu)點(diǎn)是占用資源少,交互更加簡單可靠。
當(dāng)連接B的系統(tǒng)越來越多的時(shí)候,由于數(shù)據(jù)庫的連接池是有限的,導(dǎo)致每個(gè)系統(tǒng)分配到的連接不會很多,當(dāng)系統(tǒng)越來越多的時(shí)候,可能導(dǎo)致無可用的數(shù)據(jù)庫連接。
這時(shí)候otter比較適合。而兩個(gè)不同公司的系統(tǒng),不太會開放自己的數(shù)據(jù)庫給對方連接,因?yàn)檫@樣會有安全性影響。
3. 文件包共享方式
一些第三方公司為了保密,不愿意提供接口,那么會把文件存在類似網(wǎng)盤或網(wǎng)頁上,供需求方下載。
雙方系統(tǒng)約定文件服務(wù)器地址、密碼、文件命名規(guī)則、文件內(nèi)容格式等,通過上傳文件到文件服務(wù)器,進(jìn)行數(shù)據(jù)交互,對大數(shù)據(jù)量的也很適合。這就是一種異步的上傳下載機(jī)制,雙方的操作割裂開,并且一旦上傳可以被多個(gè)需求方使用。
比如:第三方支付公司與需求方約定好SFTP服務(wù)器(一種文件服務(wù)器,可以理解為網(wǎng)盤)的賬號密碼,然后支付公司將賬單數(shù)據(jù)上傳到SFTP服務(wù)器上,那么需求方就可以登陸SFTP客戶端,進(jìn)行下載、解析,然后保存使用。這也實(shí)現(xiàn)了數(shù)據(jù)在服務(wù)器之間的傳輸。
實(shí)際上這些數(shù)據(jù)本身也是加密的,所以只有協(xié)議的公司才能拿到解碼鑰匙。長期合作的公司就會持續(xù)更新,授權(quán)的公司就可以持續(xù)下載和解析。這里就有一個(gè)下載頻率的問題,一般使用定時(shí)任務(wù)按一定頻率去下載。并且要考慮丟包的機(jī)制。
案例:
到SFTP服務(wù)器抓取并解析WP支付平臺的賬單明細(xì),方案如下:到SFTP服務(wù)器找到文件路徑,篩選出需要的類型文件,打開文件,按規(guī)則解析所需的字段,對應(yīng)寫入本地?cái)?shù)據(jù)表。
腳本執(zhí)行邏輯:每次抓取路徑下‘修改時(shí)間’為前一天的文件。(這里有個(gè)隱患:如果出了故障,可能某天的數(shù)據(jù)就漏了)。
問題:怎么防止丟抓呢?
分析:因?yàn)槭峭獠繑?shù)據(jù),所以這里無法對源數(shù)據(jù)做“是否被抓取過”的標(biāo)注,因此建議防丟方案是增加斷抓補(bǔ)抓機(jī)制。
斷抓補(bǔ)抓機(jī)制:比如4號抓了修改時(shí)間為3號的數(shù)據(jù)。5號斷抓,則6號繼續(xù)抓取4、5號的數(shù)據(jù)。斷抓補(bǔ)抓的機(jī)制就是說一旦某一天的數(shù)據(jù)中斷了,發(fā)現(xiàn)不連續(xù),那么系統(tǒng)就自動在下次重新抓一次,看看是否能補(bǔ)上。直到三次都未取到,則不再補(bǔ)救。
該方案可以降低我方抓取故障導(dǎo)致的抓空情況。有時(shí)候開發(fā)懶省事不愿意考慮這么多,這時(shí)候產(chǎn)品經(jīng)理要提醒他。
4. 消息隊(duì)列MQ(Message Queue)
1)MQ概念
消息隊(duì)列技術(shù)是分布式應(yīng)用間交換信息的一種技術(shù)。目前市場上有很多開源的jms消息中間件,比如ActiveMQ, OpenJMS。
簡單說就是一方不斷把信息推到隊(duì)列中,像排隊(duì)進(jìn)隧道一樣,另一方依次消費(fèi)這些信息。消息隊(duì)列可駐留在內(nèi)存或磁盤上,隊(duì)列存儲消息直到它們被應(yīng)用程序讀走。
該方式更適用于公司內(nèi)部,數(shù)據(jù)量大,規(guī)律性強(qiáng),批量往來的數(shù)據(jù)。主要解決應(yīng)用解耦,異步消息,流量削鋒等問題。
2)以異步處理舉例說明
用戶注冊后,需要發(fā)注冊郵件和注冊短信。傳統(tǒng)的做法有兩種:
- 串行方式:將注冊信息寫入數(shù)據(jù)庫成功后,發(fā)送注冊郵件,再發(fā)送注冊短信。以上三個(gè)任務(wù)全部完成后,返回給客戶端。
- 并行方式:將注冊信息寫入數(shù)據(jù)庫成功后,發(fā)送注冊郵件的同時(shí),發(fā)送注冊短信。以上三個(gè)任務(wù)完成后,返回給客戶端。與串行的差別是,并行的方式可以提高處理的時(shí)間。
假設(shè)三個(gè)業(yè)務(wù)節(jié)點(diǎn)每個(gè)使用50毫秒鐘,不考慮網(wǎng)絡(luò)等其他開銷,則串行方式的時(shí)間是150毫秒,并行的時(shí)間可能是100毫秒。
因?yàn)镃PU在單位時(shí)間內(nèi)處理的請求數(shù)是一定的,假設(shè)CPU1秒內(nèi)吞吐量是100次。則串行方式1秒內(nèi)CPU可處理的請求量是7次(1000/150)。并行方式處理的請求量是10次(1000/100)
小結(jié):如以上案例描述,傳統(tǒng)的方式系統(tǒng)的性能(并發(fā)量,吞吐量,響應(yīng)時(shí)間)會有瓶頸,如何解決這個(gè)問題呢?
引入消息隊(duì)列,異步處理,改造后的架構(gòu)如下:
按照以上約定,用戶的響應(yīng)時(shí)間相當(dāng)于是注冊信息寫入數(shù)據(jù)庫的時(shí)間,也就是50毫秒。
注冊郵件,發(fā)送短信寫入消息隊(duì)列后,直接返回,因此寫入消息隊(duì)列的速度很快,基本可以忽略,因此用戶的響應(yīng)時(shí)間可能是50毫秒。因此架構(gòu)改變后,系統(tǒng)的吞吐量提高到每秒20 QPS。比串行提高了3倍,比并行提高了兩倍。
在設(shè)計(jì)方案的時(shí)候要注意異常情況的處理機(jī)制,比如:首次消費(fèi)失敗?
如果第一次數(shù)據(jù)消費(fèi)的時(shí)候,無法識別沒有匹配上,但是又想下次再消費(fèi)一次看是否匹配的上怎么辦?可以設(shè)定機(jī)制:無法識別的則重新插到隊(duì)列后面繼續(xù)推送。
如果一直循環(huán)仍消費(fèi)不掉信息積壓怎么辦?
設(shè)定處理機(jī)制:超過一定積壓數(shù)據(jù)量或者循環(huán)時(shí)間過長則進(jìn)行報(bào)警。
3)MQ、文件包共享、接口的對比
MQ推送過去之后,是否推送成功無需對方再用MQ返回,因?yàn)橥频街虚g站就意味著我方能做的事情已經(jīng)做完。
而接口是一來一往才知道是否成功的,也就是要返回一個(gè)信息。這點(diǎn)與mq是不一樣的。但是如果非要對方再返回是否接受成功的話,那么就要做反向MQ,這相當(dāng)于另一個(gè)獨(dú)立的MQ。
文件包共享也不需要反饋機(jī)制,因此傳到了文件服務(wù)器之后,數(shù)據(jù)方的事情就做完了。隊(duì)列的一個(gè)信息只能被消費(fèi)一次,不同系統(tǒng)不能共同消費(fèi)一個(gè)隊(duì)列。因此如果對接多個(gè)系統(tǒng)則要多次創(chuàng)建MQ。而接口可以創(chuàng)建一個(gè),讓其他很多系統(tǒng)調(diào)取。
在訂單系統(tǒng)對接各個(gè)銷售網(wǎng)站和平臺的時(shí)候就可以采用這樣的機(jī)制,避免多次對接。文件包共享也是可以上傳一次,供多個(gè)需求方下載。這點(diǎn)和接口有相似之處,是MQ所不具備的。
5. 其他手段
數(shù)據(jù)傳輸包含了數(shù)據(jù)信息的獲取和寫入,其實(shí)除了線上的自動機(jī)制,還有很多土辦法,在后端產(chǎn)品系統(tǒng)中也是常使用的。
1)導(dǎo)入導(dǎo)出
場景:沒有辦法做系統(tǒng)之間的對接,但是線下能獲得數(shù)據(jù)。數(shù)據(jù)量不太大,且有規(guī)則數(shù)據(jù),則可以通過導(dǎo)入的方式。
文檔一般用csv格式,該格式文件較小,兼容性好,然后需要定義好excel表格對應(yīng)字段的關(guān)系,比如A列對應(yīng)字段‘name’,B列對應(yīng)字段’age’。
上傳時(shí)需要對文件檢驗(yàn),比如格式不對、必填項(xiàng)為空等,建議一旦一處錯(cuò)誤,就全部不予導(dǎo)入。并返回錯(cuò)誤提示,修改后繼續(xù)導(dǎo)入。
若數(shù)據(jù)太大(與服務(wù)器的性能也有關(guān)系,比如超過一萬條),可以采用異步上傳機(jī)制,就是上傳之后不立即執(zhí)行寫入,而是后臺自動分批寫入。
2)爬取
作為數(shù)據(jù)需求方,獲取數(shù)據(jù)可以通過協(xié)商接口的方式、SFTP解析的方式、或者直接爬取的方式。
比如需要獲取第三方網(wǎng)站商標(biāo)庫中最新商標(biāo)名稱、注冊地、logo、授權(quán)期限等信息,如果該網(wǎng)站不給于開放的接口授權(quán),可能就需要我們開發(fā)寫爬蟲代碼爬取(當(dāng)然有的商業(yè)數(shù)據(jù)也是帶有反爬機(jī)制的,這就看誰道高一尺魔高一丈了)。
三、數(shù)據(jù)傳輸?shù)奶幚頇C(jī)制
1. 數(shù)據(jù)同步的觸發(fā)機(jī)制
前面提到了數(shù)據(jù)獲取的方式,那么數(shù)據(jù)獲取頻次或者觸發(fā)機(jī)制是怎么樣的呢?這要根據(jù)應(yīng)用場景來設(shè)定方案,但是一般都是要求持續(xù)獲取的。
一種方式是操作事件觸發(fā),比如頁面的按鈕點(diǎn)擊則觸發(fā)傳遞最新狀態(tài)。這種的時(shí)效性比較高,但是也會由于并發(fā)而增加系統(tǒng)負(fù)荷。
如果對時(shí)效要求不高就可以采用異步機(jī)制。比如使用腳本監(jiān)控。設(shè)定腳本的運(yùn)行頻率,當(dāng)讀取到更新時(shí)間為頻寬內(nèi)的數(shù)據(jù),則將其捕獲并傳輸。定時(shí)腳本也叫定時(shí)任務(wù)等,定時(shí)腳本在后端是很常用的。
比如說每次獲取A系統(tǒng)6小時(shí)內(nèi)更新的數(shù)據(jù),那么每2小時(shí)取一次的話是沒問題的。但是若每7小時(shí)獲取一次就會漏掉1小時(shí)的數(shù)據(jù)。因此一定是每次獲取的數(shù)據(jù)時(shí)間區(qū)間,要高于數(shù)據(jù)獲取的時(shí)間間隔。
當(dāng)然用時(shí)間是一種維度,更安全的是用標(biāo)示性字段。比如每次獲取is_got為0的數(shù)據(jù)。前臺是is_got做表索引(索引前面講到過),這樣遍歷(遍歷約等于全表查詢)數(shù)據(jù)庫的時(shí)候就不會太慢。
2. 是否異步執(zhí)行數(shù)據(jù)處理
如果獲取后還要在本地進(jìn)行規(guī)則運(yùn)算,則最好先落地到中間表,再由中間表寫入最終表,也就是異步寫入。
比如:按照訂單+包裹號維度,從物流系統(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ī)則的可變動性。一旦分?jǐn)傄?guī)則的參數(shù)不準(zhǔn)確,或者算法結(jié)構(gòu)變化,都會導(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)行寫入分?jǐn)傔\(yùn)費(fèi)的操作。
除了上述方便查錯(cuò)誤原因外(有種數(shù)據(jù)清洗的意思),這種異步操作同時(shí)也確保了較少的偶聯(lián),不至于一個(gè)環(huán)節(jié)出錯(cuò),則聯(lián)動出錯(cuò)。同時(shí)它作為一個(gè)基礎(chǔ)數(shù)據(jù),也可以被其他功能調(diào)用。若數(shù)據(jù)量萬級以上的,必須這樣做。
3. 判重機(jī)制
數(shù)據(jù)通道搭建好之后,數(shù)據(jù)流往往是持續(xù)獲的。而數(shù)據(jù)源在別人那里,可能會被增刪改,因此常常有相似或相關(guān)的數(shù)據(jù)進(jìn)來。在寫入本地表的時(shí)候,不管是覆蓋、更新還是插入,都是以確定若干字段做為判重的標(biāo)示為前題的。
比如職工信息表:(姓名+手機(jī)號+性別+家鄉(xiāng)+身份證號)。(姓名+手機(jī)號+性別+家鄉(xiāng))這幾個(gè)字段對一個(gè)職工不一定唯一,但是身份證號就是唯一的。因此如果我們更新這里的數(shù)據(jù),就以身份證號為唯一標(biāo)示。
比如獲取到同一個(gè)身份證號的手機(jī)號與我們的數(shù)據(jù)庫的不同,則更新。遇到我們的數(shù)據(jù)庫不存在的身份證號碼則插入。
某些時(shí)候無法確定那幾個(gè)是唯一字段,則可以添加一個(gè)備用字段,人為定義其取值規(guī)則,然后作為去重字段,比如這個(gè)字段叫unique_code,取數(shù)據(jù)源表的主鍵+日期,(或者直接就取源表的id,也就是外鍵)。
有了判重字段(也就是數(shù)據(jù)唯一的字段),就可以進(jìn)行更新、插入或者跳過規(guī)則設(shè)定了。
注意:若一段時(shí)間之后,改變了表的去重規(guī)則,則需要考慮到歷史數(shù)據(jù)對新數(shù)據(jù)的影響,因?yàn)槎叩呐兄鼐S度不一樣,可能會進(jìn)來和以前的歷史數(shù)據(jù)沖突的交叉數(shù)據(jù)。
4. 獲取到數(shù)據(jù)之后,如果使用?
一種是直接在頁面展示,不保存在本地?cái)?shù)據(jù)庫中。相當(dāng)于每刷新一次頁面則通過接口調(diào)取一次對方的數(shù)據(jù)展示。但這種從性能和場景上都是比較少的,一般都是先保存到本地?cái)?shù)據(jù)庫上,自己本地各種調(diào)用。
對于先保存到本地的情況,有兩個(gè)問題要考慮:是否異步保存,和如何確保同源同步。
5. 處理日志
數(shù)據(jù)日志:目的是記錄數(shù)據(jù)的來龍去脈,追溯以分析問題,日志要記錄三個(gè)主要事項(xiàng):數(shù)據(jù)源系統(tǒng)是否提供數(shù)據(jù)、目標(biāo)系統(tǒng)是否接收到數(shù)據(jù)、目標(biāo)系統(tǒng)是否寫入了數(shù)據(jù)。
產(chǎn)品經(jīng)理告訴開發(fā)加數(shù)據(jù)捕獲日志的時(shí)候,需要告知是否存到表里,因?yàn)橄到y(tǒng)一般都有一個(gè)類似緩存一樣的日記,只是會定期清理的,只有保存下來才能一直記錄和追溯。
開發(fā)后臺本身是有數(shù)據(jù)log日志的,因?yàn)閘og4j開源代碼定義了5個(gè)主要級別的log:FATAL、ERROR、WARN、INFO、DEBUG,一般情況下,開發(fā)都會自覺配置INFO或DEBUG級別的日志,以方便查數(shù)據(jù)。
但是代碼中的kog保存時(shí)間不會太長,比如一個(gè)月就會清除了。因此如果需要保留的時(shí)間長,則可以將其保存到本地?cái)?shù)據(jù)庫。
根據(jù)實(shí)習(xí)需要,存了數(shù)據(jù)庫就可以做成頁面,展示給用戶看,比如可以從以下維度展示:
四、數(shù)據(jù)傳輸?shù)淖⒁馐马?xiàng)
1. 目標(biāo)數(shù)據(jù)表最好和中間表的維度一致
假設(shè)從A系統(tǒng)獲取的數(shù)據(jù)存入B系統(tǒng),先落地到中間表b,然后經(jīng)過一些列運(yùn)算后將數(shù)據(jù)從b寫入到b’表。注意b和b’表的去重字段要對應(yīng)起來,并傳遞下去。因?yàn)榫S度相同,做到一對一,方便實(shí)現(xiàn)異常數(shù)據(jù)溯源。
2. 不同入口寫入同一類型數(shù)據(jù)時(shí),如何與自身入口的數(shù)據(jù)去重,且與其他入口的數(shù)據(jù)互相去重?
案例:有新舊兩個(gè)不同的寫入程序,寫數(shù)據(jù)到利潤表,寫入的都是‘退件入庫’利潤類型,是殊途同歸。不巧的是兩個(gè)寫入入口各自有本身的去重規(guī)則,彼此去重的規(guī)則不能通用:假設(shè)入口1對應(yīng)的去重字段是A+B,入口2寫入的去重字段是B+C。
這就意味著同一個(gè)數(shù)據(jù)如果分多次寫入,有可能從兩個(gè)入口都會寫入。如何實(shí)現(xiàn)避免重復(fù)寫入是核心問題。我們首先考慮的是,如果一條源信息從一個(gè)入口已經(jīng)寫入了利潤表,那么就不能從另一個(gè)入口再寫。
其次,如果從入口1寫入一次,那么后面源數(shù)據(jù)更新再次觸發(fā)寫入的時(shí)候(判重,確定是插入還是更新),就還要從入口1寫。也就是一旦從一個(gè)入口寫入,后面該數(shù)據(jù)的變更觸發(fā)的再次寫入也只能從這個(gè)入口繼續(xù)變更。
只有這樣才能保證這個(gè)數(shù)據(jù)不重復(fù)。好比先找到是哪家的孩子,再確定是第幾個(gè)孩子,且只能是基于這家內(nèi)部去確認(rèn)。
方案一:比如入口1遇到一個(gè)待寫入的數(shù)據(jù),則先按自己的去重字段A+B校驗(yàn)。如果發(fā)現(xiàn)不存在該數(shù)據(jù),則再按照入口2的去重字段B+C(這個(gè)事先是知道的)判斷是否存在,若也不存在,則回到入口1寫入。若存在,則入口1不在寫入,且結(jié)束進(jìn)程(因?yàn)槿肟?會觸發(fā)寫入該數(shù)據(jù)的)。
方案二:比如入口1遇到一個(gè)待寫入的數(shù)據(jù),則先按入口2的去重字段B+C校驗(yàn)。
查看對方入口下是否有重復(fù)數(shù)據(jù),有,則本入口不寫(繼續(xù)按對方的路徑寫);無,則自己的路徑寫。顯然方案二的判斷路徑更短,相對好一點(diǎn)。
3. 同步基礎(chǔ)數(shù)據(jù)的時(shí)候是否提前過濾
這個(gè)在上面內(nèi)容中也提到過。比如: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)的用戶忽然被A系統(tǒng)禁用,那么可能該用戶在B系統(tǒng)的生產(chǎn)數(shù)據(jù)報(bào)錯(cuò),這時(shí)候到中間表看狀態(tài)就可以看出來問題,而不需跨系統(tǒng)或跨部門溝通查證。
#專欄作家#
唧唧歪歪PM,公眾號:唧唧歪歪PM(ID:jjyypm),人人都是產(chǎn)品經(jīng)理專欄作家,2019年年度作者。《后端產(chǎn)品經(jīng)理寶典》作者,藥學(xué)碩士轉(zhuǎn)行互聯(lián)網(wǎng)產(chǎn)品多年;熟悉跨境電商業(yè)務(wù),醫(yī)藥領(lǐng)域;擅長大型后臺體系,社交APP。
本文原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理,未經(jīng)作者許可,禁止轉(zhuǎn)載
題圖來自Unsplash,基于CC0協(xié)議
邏輯還有措辭非常順,很舒服的看下來了,點(diǎn)贊!
那請問如何處理兩個(gè)系統(tǒng)的數(shù)據(jù)/字段的對應(yīng)呢,比如a系統(tǒng)字段為姓名,b系統(tǒng)為名稱,c系統(tǒng)為name,他們各自的數(shù)據(jù)格式也不同,這種情況如何創(chuàng)建一個(gè)公用的模塊或者方法來實(shí)現(xiàn)a系統(tǒng)與各種系統(tǒng)的對接呢
同問,請問有什么解決方法嗎?
具體的映射關(guān)系,要在公用模塊中進(jìn)行實(shí)際配置。這樣可以解決不同系統(tǒng)名稱不一樣的問題,也可以根據(jù)實(shí)際需要對字段靈活取用
太贊了 寫的詳細(xì)而且舉例通俗易懂 謝謝!
總結(jié)的比較詳細(xì),其實(shí)產(chǎn)品經(jīng)理知道有這些就夠了