去年,一部《超級快遞》給大家帶來了不少歡樂,除了歡笑,我們也看到了準時送達作為一種增值服務或者高階服務在快遞物流行業中可能性和市場。而每天上億的快遞數量靠人肉來保證已經幾無可能,在這裡,我們從系統的角度來看看如何搭建乙個保證快遞能夠準時到達的系統。
要保證快遞能準時到達收件人手裡,就需要能夠主動及時的發現那些可能會遲到的快遞,並在第一時間進行檢視和處理,比如聯絡到快遞小哥確認狀態等等。
在這裡,我們將快遞在整個流轉的過程進行拆分,當快遞達到乙個狀態之後,確定下乙個狀態以及達到時間,在規定的時間內沒有到達則需要通知相關的負責人進行處理,我們將快遞的每一次狀態的更新都寫入資料庫中,然後採取下面兩種方案進行簡單的處理:
方案一
每次更新快遞的狀態時與前一次狀態進行比較,中間的時間差超出期望時間則報警。
方案二
定時對所有的快遞狀態進行檢查,最近一次狀態更新的時間距當前時間超出期望則報警。
__方案一__只在快遞更新時做處理,對系統的壓力最小,但是需要依賴快遞的到達時間觸發,時效性太差,快遞到的越晚就越晚才發現快遞遲到,往往是發現快遞不能準時送達的時候快遞就已經遲到了。
__方案二__發現可能遲到的快遞的時效性取決去檢查的週期,最壞情況下就是快遞在檢查之後馬上就超時了,等到下次檢查才能發現,而且對日均千萬甚至億級別的快遞狀態進行儲存本來就是乙個非常頭疼的問題,再掃全庫進行查詢又會大大增加資料庫的負擔,很有可能查詢的時間就會超過快遞的超時時間。
所以,我們選用了阿里雲的**儲存與訊息服務的延時佇列功能來解決這個難題。
首先,我們將快遞的每乙個狀態都儲存在**儲存中。
**儲存很好的解決了資料規模與讀寫併發上的問題,單錶能夠支撐到萬億級資料規模,自動負載均衡能夠讓使用者不需要做任何動作就可以將資料表的讀寫併發擴充套件到百萬級別,按量付費又可以避免資源的浪費。同時,讀寫效能不受資料規模的影響,也不用擔心資料積累之後的效能問題。
首先,我們根據業務情況在訊息服務上建立多個不同的佇列,每個佇列設定不同的delayseconds,進入該佇列的訊息將在設定的delayseconds之後才會被消費者取到。
超時檢查系統從上述佇列中取訊息進行檢查,根據訊息中的快遞單號在**儲存中查詢該快遞的最近一次狀態資訊,如果查到的最新狀態時間大於訊息中的時間,則說明該快遞在超時時間內達到了下乙個狀態,否則該快遞則有不能按時到達的風險,迅速進行報警處理。
架構優勢
**儲存與訊息服務都是高併發、按量付費產品,不需要評估業務的訪問情況,再購買相應的規格,按量付費也不會出現資源的浪費。
**儲存的高併發優勢可以在幾十萬的qps下依然提供毫秒級的讀寫延時,從容應對超時檢查系統以及來自真實使用者的快遞查詢需求。
快遞到達超時時間之後能夠立刻被消費者也就是超時檢查系統看到,大大提高了處理的實時性。
乙個佇列可以對應多個消費者,每個訊息只會被乙個消費者取到,所以檢視佇列裡面的訊息堆積情況,包括未到喚醒時間的訊息和已經喚醒等待處理的訊息數量,當等待處理的訊息數量過多則說明系統處理的慢了,這個時候就可以動態增加處理節點了,節點間沒有狀態引入,直接去獲取訊息時間處理即可,部署架構又大大簡化。
如何用ResourceBundle來讀取配置檔案
對於ja va基礎很好的人來說,這個應該是簡單的不能再簡單的了。不過估計一些ja va新手不一定會知道 比如我,上次為別人寫乙個東西,需要從外存讀檔案來設定物件的值,因為不知道有resourcebundle這種東西,就自己用filereader在那搞,折騰了半天,最後還不能把配置檔案和jar包打在一...
如何用ResourceBundle來讀取配置檔案
對於ja va基礎很好的人來說,這個應該是簡單的不能再簡單的了。不過估計一些ja va新手不一定會知道 比如我,上次為別人寫乙個東西,需要從外存讀檔案來設定物件的值,因為不知道有resourcebundle這種東西,就自己用filereader在那搞,折騰了半天,最後還不能把配置檔案和jar包打在一...
如何用readstring()來讀檔案
對於一般檔案的讀取,建議還是用cstdiofile來進行行的讀與寫操作,這樣非常方便的.問題提出 一資料檔案一行一條記錄,我用file.readstring 一次讀一行,並對讀取的資料做一些處理 請問 while 檔案還沒到結尾 檔案還沒到結尾如何判斷?如果,到了指定位置不讀了,過一會兒再讀又如何做...