一个综合数据库设计与软件设计的实例讨论

类别:Java 点击:0 评论:0 推荐:

下面是我在接到了一个项目设计后的思考,这个项目是向不同的用户群(公司)提供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接口实现的争论,从性能上、安全性等等,哪种方式更好一些呢?


 

本文地址:http://com.8s8s.com/it/it16448.htm