產(chǎn)品經(jīng)理懂點技術(shù)之:系統(tǒng)間是怎么同步信息的
本文將會從一個最簡單的請求講起,從同步異步請求,到輪詢回調(diào),再到更先進的解決方案消息隊列,用以介紹系統(tǒng)間不同的同步信息方式。
最近產(chǎn)品汪正在負責自家系統(tǒng)跟某個供應商的對接,經(jīng)常聽到技術(shù)們關(guān)于訂單狀態(tài)同步的事情吵得不可開交。
我方程序猿:你們系統(tǒng)狀態(tài)為啥都不同步回給我們啊,這我們怎么知道狀態(tài)變了啊
供應商對接人員:你們自己輪詢啊
我方程序猿:這樣很不靠譜啊,你們回調(diào)一下不行么
供應商對接人員:改這不要時間么
我方程序猿:你們怎么一些地方有回調(diào)一些地方?jīng)]有啊
供應商對接人員:不同時期同事寫的嘛……
我方程序猿:*&¥%*&%……
等到對接功能終于提測后,產(chǎn)品汪就問了一下程序猿哥哥,輪詢和回調(diào)是什么,他們有什么區(qū)別呢?
下文將會從一個最簡單的請求講起,從同步異步請求,到輪詢回調(diào),再到更先進的解決方案消息隊列,用以介紹系統(tǒng)間不同的同步信息方式。
一個簡單的請求 Request
程序猿哥哥說,要曉得為什么要輪詢和回調(diào),首先要知道兩個系統(tǒng)間信息是怎么交互的。例如你的手機APP要登錄,APP就要把輸入的賬號密碼發(fā)給后臺,后臺判斷發(fā)現(xiàn)這個賬號已經(jīng)注冊了,密碼也匹配,就會告訴APP登錄成功。
A發(fā)給B一些東西,B返回處理的結(jié)果,這就是一個簡單的信息請求(request)的過程。
小汪說,這個我知道啊。
于是程序猿哥哥又說,剛才這種請求,我們稱之為“同步請求”,就是你要什么,一會兒對方就給你發(fā)了回來,但事實上萬一處理的邏輯多且復雜,可能信息沒那么快返回,你說咋辦?
小汪說,在界面上一直loading等待中,轉(zhuǎn)圈圈么?
程序猿哥哥大笑,說好的用戶體驗呢?在這種情況下,我們就繼續(xù)做別的事情,然后對方返回了消息來,我們再接著做原來的事情,這樣體驗不就更好了么。
于是我們引進了“異步”的請求, 我方請求對方處理某個事情后,在等待過程中我們還可以繼續(xù)做點別事情,直至對方返回了內(nèi)容,這樣再接上,用戶體驗就比轉(zhuǎn)圈圈等待好多了。
產(chǎn)品汪:原來是這樣啊,那這又跟輪詢、回調(diào)有什么關(guān)系么?
輪詢 Polling
程序猿哥哥說:耐心點小伙子,你這樣不耐煩的樣子,就像極了輪詢。
當我方系統(tǒng),如圖中橙色的手機,將信息發(fā)給另外一個系統(tǒng)后, 即圖中藍色的服務(wù)器,需要處理一陣子才有結(jié)果。例如:
- 用戶下了一個訂單要商家發(fā)貨
- 一個合作伙伴在系統(tǒng)中提交了合同申請,需要等我方運營同事審批
- 一個員工在手機上提交了請假流程,需要等領(lǐng)導在OA里同意
這時候,對方系統(tǒng)不可能立即有結(jié)果,我方系統(tǒng)就會不斷的追問對方,商家發(fā)貨了沒啊,運營審批了沒啊,領(lǐng)導同意了沒啊,如果對方信息沒有更新,或者事情還沒有處理完,則返回未完成的消息。然后我方就繼續(xù)不斷的追問,直到對方答復,發(fā)貨啦、審批啦、同意啦,然后我方就更新自己的信息狀態(tài),流程截止。
小汪說,原來就是不斷的煩對方呀。
程序猿說,是的,當對方不能立即處理完成時,就需要我方通過輪詢不斷向?qū)Ψ讲樵冇唵螤顟B(tài)是否有更新。又或者我們的系統(tǒng)需要輪播顯示最新的新聞、通知、廣告時,我們也要用到這個技術(shù),不斷向服務(wù)器查詢有沒有新的內(nèi)容。
回調(diào) Callback
小汪說,輪詢我算懂了,就是不斷的問不斷的問,就可以獲得最新的信息、訂單狀態(tài)等等內(nèi)容,這個是挺實用的。但是這樣不會很耗費資源么,占網(wǎng)速、費電之類的?
程序猿回答,是啊,所以我們就有一個新的辦法,叫做“回調(diào)”,對方做好了告訴我們一聲不就好了么,這樣我們就省時省力啦。
產(chǎn)品汪說,那對方做好了能直接說一聲,既然有這么好的方案,為什么還要用輪詢呢?
程序猿繼續(xù)回答道,就像兩個人打電話一樣,如果對方沉默了很久,你會不會問“喂喂喂,還在么?”,又或者對方說了什么,由于信號不好,你沒聽到咋辦?
產(chǎn)品汪:搜嘎,回調(diào)要求雙方都在線,而且網(wǎng)絡(luò)通暢,如果自己掉線了或者雙方誰網(wǎng)絡(luò)不好,可能就會錯過對方回復的內(nèi)容了。那輪詢、回調(diào)必須搭配著用啊,那豈不是很復雜了?
程序猿補充道,現(xiàn)在很多平臺都有“多次回調(diào)”的機制,就是把結(jié)果重復發(fā)多幾次,免得我方?jīng)]收到,但是只用回調(diào)不能根治你剛才說的問題,萬一我全程不在線呢是吧,而且多次回調(diào)還有”冪等性“的一些問題,這個以后遇到再給你細說。
消息列隊 Message Queue
產(chǎn)品汪就好奇了,問程序猿哥哥,那有沒有既省事,又保障消息一定送達的方案呢?就是類似把輪詢和回調(diào)結(jié)合的方案。
程序猿說,有啊,你還記得很久前有些聊天軟件有“已讀”的功能么?
產(chǎn)品汪說,以前確實有段時間這個概念比較火,發(fā)出去的消息可以知道對方有沒有看,其實現(xiàn)在阿里旺旺跟賣家聊天也有這個功能。
程序猿說,把回調(diào)、輪詢相結(jié)合的方案,其實就類似已讀,我們找個服務(wù)器,把請求內(nèi)容都放在上面,像個聊天對話列表一樣,我們稱之為“消息隊列”(Message Queue,簡稱MQ)。有消息的時候就通知我一下,如果我不在線,下次上線的時候消息依然還在那里。我看完了可以點個“朕已閱”,然后對方就知道我已經(jīng)收到消息了。
產(chǎn)品汪說,這個有意思啊,這樣就不會錯過任何對方回復的東西啦!那為什么不都用消息列隊呢?這樣能減少系統(tǒng)間同步訂單狀態(tài)出錯的概率啊。
程序猿說,要做MQ,得要搭建個消息服務(wù)器。從同步請求、到異步請求,再到輪詢/回調(diào),我們的系統(tǒng)在越來越復雜,如果我們面對的不是很復雜的內(nèi)容處理,大部分時候都能做到立即返回結(jié)果,那可能輪詢、回調(diào)都不需要,我們要根據(jù)實際需求設(shè)計技術(shù)方案呀。復雜的技術(shù)流程不僅僅占用開發(fā)時間,還會影響用戶對程序速度的感覺,如果一個簡單的請求也走MQ的話,那就太曲折了,沒這個必要。
產(chǎn)品汪:原來如此啊,還是多快好省的問題啊哈哈哈哈。
程序猿又補充到,就像我們現(xiàn)在很多個子系統(tǒng),各種訂單支付、訂單發(fā)貨、商家、商品、傭金狀態(tài)等等,又跟多個供應商系統(tǒng)對接著,很多信息的修改都要有審批流程,審批完成之后才會把狀態(tài)同步回去,這時候我們就可以嘗試建立一套MQ服務(wù)器,利用MQ來確保各個子系統(tǒng)間信息的同步。
總結(jié)
在與程序猿哥哥聊完后,產(chǎn)品汪趕緊跑去趕地鐵回家吃晚飯,路上小汪就在想,其實不同系統(tǒng)同步信息有以下幾個問題:
- 時效性:有些內(nèi)容需要審批完,或者進行一系列復雜邏輯才能處理完的,不能讓一方系統(tǒng)在干等。
- 可靠性:例如一個訂單在我這邊已經(jīng)審批完了,如何確保其他人也知道這個結(jié)果,信息同步要到位,且準確,不能讓其他人收不到訂單狀態(tài)更新,或者收到錯誤的結(jié)果,例如已審批通過但是卻收到審批不通過的結(jié)果。
- 低功耗:用技術(shù)的話說可能是“高性能”,不能浪費太多資源在查詢狀態(tài)更新上,系統(tǒng)中有上萬個訂單要更新狀態(tài)同步給我們的供應商時,方案不對可能系統(tǒng)就卡死了。
如果一個請求的內(nèi)容特別重要,而且對方又不能立刻給結(jié)果時,消息隊列MQ是一個不錯的選擇,這樣我就不怕錯過消息了。如果只是些普通的請求,處理很快的,又或者用戶不能等的,那就用簡單的請求就好了,看來做技術(shù)也是要按具體需求來設(shè)計方案的呀。
本文由 @iCheer 原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理。未經(jīng)許可,禁止轉(zhuǎn)載
題圖來自Unsplash,基于CC0協(xié)議
你爸媽沒教你什么是羞恥之心嗎?他們就只教你不要臉,沒禮貌了是嗎
千萬別人一個半灌水開講技術(shù) 誤人子弟
太厲害了,總結(jié)下來就是講人話
這么通俗易懂的講解技術(shù)知識 贊贊贊?。。。。。。。〈蛸p了
生動有趣,希望以這種方式描述下前后端的協(xié)作哈哈
太棒了!
干貨,作者一定是大咖才能做到這么通俗
講的太清楚啦
多多益善,多多益善哈
這篇太贊了~
學習了~寫得簡單易懂,深入淺出~
很棒的分享,謝謝~
學習了!