一個綜合數據庫設計與軟件設計的實例討論

面是我在接到了一個項目設計後的思考,這個項目是向不同的用戶羣(公司)提供wappush技術,說白了也就是做一個制定的ppg。具體的發送已經由底層封裝好,並且提供了規範的api,此項目需要做的就是完成對不同的sp實現接口,讓他們通過此係統進行push發送。此係統的功能要求是需要有穩定的性能、有日誌記錄。

下面是我接到的設計

1。接口部分,提供Socket的接口調用給SP使用,爲了提高性能,必須採用多線程並結合隊列實現。並提供一個client的例子

注意,需要經過身份認證方可使用,否則報錯。

 2。數據庫設計:(用mysql實現)
   3個表:
   SP表:
   mobile_user:每一個push,都應該把用戶登記到這個表中,sp_id可以通過登錄獲得,請keith補充。
   pushlog表:把每次發送的信息記錄在這個表中。


3。管理界面:(用php實現)
 a.SP的add,remove,delete,update, search may not required
 b.給一個手機號,能查出是哪家sp發送的push,有多少,列出來
 c.選擇SP,統計出一段時間的發送信息,有多少條,成功率
 d.給一個主題,能查出是哪家sp發送的

4.數據庫er圖:

------------------------------------------------

在看了上面的設計後,我給我的頭回信如下:

頭你好:
 設計已經收到,不過我個人覺得有些地方可能需要再討論一下:
  1 首先使用Socket的方式實現接口
    如果只提供Socket的方式實現接口,會存在平臺兼容性問題,因爲各個sp可能使用不同的開發語言,當然,這個問題應該可以解決,不過這樣也增加了sp的工作難度,如果增加了工作難度,那麼各個sp可能考慮會調用其他的難度要求較低的push網關來實現。我建議我們提供兩套接口:Socket接口和WebService接口。
  2 數據庫設計部分,我個人看過設計後,總有些疑惑,說出來我們討論一下吧:)
    如果按照當前的數據庫進行實現,分析一下從一個sp的push請求到我們將這個請求發送到手機用戶的過程,我想可能有兩種方式去實現:
 a)直接發送一步到位的實現方式;
 b)採用供應者-消費者模式。
 首先我們來分析第一種方式:當sp的一個調用請求到達我們的系統,我們首先進行sp鑑權(認證),對sp表進行select操作(建議對sp的鑑權操作這塊使用內存數據庫技術以提高性能),在鑑權通過的情況下我們將會進行發送操作,首先需要對mobile_user表進行select操作(因爲也許這個sp的mobile_user已經存在),根據select的結果分成兩種情況:1.如果此sp的mobile_user表中沒有這個手機用戶, 則對mobile_user表進行insert,然後進入下一步;2.如果此用戶已經存在,則直接進行下一步。下一步是進行發送操作(我們調用底層接口進行),在發送完畢後進行對pushlog表的insert操作。這種實現的擔心是:1.對mobile_user的多餘select,每一個sp-push的調用請求對要對應對mobile_user進行select,而且隨着系統的運行時間增長,mobile_user表的記錄數量也在不斷增長,這裏消耗的系統性能會越來越多;2.如果系統發生異常,不能記錄用戶的手機號碼等資源,不能對sp-push調用進行日誌記錄,因爲我們是在所有操作都結束時候進行log的;3.如果我們調用底層的接口push發送未能成功或者我們的調用部分發生錯誤異常,系統會癱瘓,無法記錄解下來的sp-push日誌和進行re-push操作。
 

然後我們再來分析一下第二種方式:第二種方式使用供應者-消費者模式實現(我傾向於這種方式,因爲這種模式從根本上避免了第一種實現的第2、3點擔心)。當sp的push請求到達我們的系統,首先進行鑑權,這個過程無需多說,鑑權通過後對mobile_user表進行select操作(因爲也許這個sp的mobile_user已經存在),根據select的結果分成兩種情況:1.如果此sp的mobile_user表中沒有這個手機用戶, 則對mobile_user表進行insert,然後進入下一步;2.如果此用戶已經存在,則直接進行下一步。下一步是進行對pushlog表的insert操作,insert pushlog表的部分字段(這些字段可能包括:id, mobilej_user_mb_id, subject, url, create_date[採用供應者-消費者模式必須增加這個字段], sent_status)。到此爲止供應者行爲結束。同事進行的消費者操作比較簡單:首先對mobile_user表和pushlog表進行聯合select操作(檢索出sent_status爲“未發送”狀態的記錄),然後發送(調用底層接口進行),最後對pushlog表進行update操作(更新的字段可能包括:sent_date, sent_status)。這種實現的擔心之處:1.供應者對mobile_user的多餘select,每一個sp-push的調用請求對要對應對mobile_user進行select,而且隨着系統的運行時間增長,mobile_user表的記錄數量也在不斷增長,這裏消耗的系統性能會越來越多;2.供應者和消費者同事對pushlog表進行write操作,在操作十分頻繁,pushlog表的記錄數量很多(會隨時間增長)的情況,很用以產生數據庫死鎖;3.消費者對mobile_user表和 pushlog表的聯合select操作,這兩個表都會隨着時間不斷增長(從均衡角度衡量,前者非線性後者線性,造成一對多的關係),那麼這個操作的系統消耗也會隨着系統的運行時間呈非線性增長。

---------------------------------------------------------------------------------------------------------------------------------------------

請各位幫助分析一下我的分析是否正確?還有一個問題,就是關於使用socket接口實現還是使用webservice接口實現的爭論,從性能上、安全性等等,哪種方式更好一些呢?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章