本人最近對架構設計較感興趣,下面是我的設計,可以做到極大化性能和水準擴充,所有的性能issue都在網絡io。redis存儲方面輕松支援同時上億個訂單。
使用一個高可用的時間序列發生器伺服器。timeserver。
訂單server産生了訂單之後立即往redis的訂單号伺服器寫一條記錄,key為timeserver的nanosecond,存儲類型為sorted set。把訂單的詳細資訊寫入另一個redis的詳單伺服器叢集(用訂單号hash寫入)。
訂單伺服器有一個定時器線程,60s運作一次,時間到了發送一條消息(包含time server的目前nanosecond)給短信發送server。
短信發送server收到nanosecond的消息後,去redis訂單号伺服器取出所有小于該nanosecond的訂單号,開啟多個協程用訂單号去redis詳單伺服器叢集拿到詳單資料,發送短信。
redis配置成高可用。訂單業務server和短信server都是無狀态的,可以橫向水準擴充。
nanosecond為19個字元,并且nanosecond作為訂單号,假設為20字元,那麼20byte*100,000,000,一億個訂單的話,redis的訂單号伺服器需要大約 1.8gb 的記憶體。而redis的詳單伺服器可以水準擴充,存儲不是問題。
訂單server和短信server都是無狀态,可水準擴充。
redis存儲節點高可用,redis詳單伺服器叢集可水準擴充。
協程處理拿訂單資料和發送短信,簡單高效。
盡量避免了各種可預見的性能問題,例如:什麼定時器,每隔1s輪詢一次等等,另外也有對redis進行多次請求訂單号的,都對性能有一些影響。
有的人的設計甚至把隊列設計到了訂單server内,這嚴重影響了訂單server的擴充性,如果一旦訂單server挂了呢?呵呵。
有人想要采用mq的方式來做,但是如何搞定延時就是個大問題,因為mq的方式是,producer發送了之後,consumer會立即接收到,如果你在producer這邊緩存60s之後在發送,那萬一在這段時間該producer挂了呢?呵呵。這裡補充下,有人提到rabbitmq的延遲隊列,的确也是一中更加簡單的方案。先發送到隊列1,隊列1不處理,超過60s隊列系統自動發送到隊列2,隊列2的消費者進行處理。也是簡單。呵呵。
這是一個非常實用的需求。
redis是一個好東西,因為redis的設計和接口足夠簡單,是以我們沒有太多想象,是以我們的設計也足夠簡單。簡單才可能健壯。