论坛首页 Java企业应用论坛

电信行业Http接口(通道)设计思路与实现过程

浏览 22494 次
精华帖 (1) :: 良好帖 (5) :: 新手帖 (11) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-05-30   最后修改:2009-05-31

  最近接口做了好长时间了,觉的有必要记录点什么下来!(虽然最近这一块不是我负责了有别的事要忙去,但是我还是经常会去看看项目开发情况。)

  

  项目主要是一个Http接口的开发,利于与其它公司合作在信息交互!因为我们这个是电信行业的项目,所以呢,在与合作商合作的时候会下发大量的短信,走数据库这有点太不专业了!用Ejb?这有点太过份了,而且很多公司赚钱是赚了不少钱,但技术实力不行。别的不说,就Http接口合作的好几家公司还真不会。 

  先说一下这个接口设计的一些重点:

  1、安全:这是肯定的,不能随便一个家伙跑过来就要用我们的接口发短信啊。

  2、效率:一家合作商用户订阅量在100多万,一天十几家下去,你的接口的扛的住啊。

  3、备份:这合作商发的信息你得有详细log啊,要是出了问题,这能找责任人啊。

 

  出于以上三点要抓信核心要点:

  1、加入安全验证机制

  2、减少数据库访问量,重构代码注重条理减少没效率的代码。采用Http能还有个好处就是规避了多线程的问题。

  3、采用log4j把详细的下发日志记录到log上,每个log的大小限制在1M.

 

 

      一、安全

  在安全方面最先考虑的是一个合作商就给他一个http链接,同时定义一个合作商编号,这样就可能起到隔离,起码你不是我和合作商你不知道发哪个Url,更别说编号了.

  但往深层想想这也不妥当:

  1、每加个合作商你得再搞个Url链接吧,这你多少还得重写点代码吧。不利于扩展。

  2、万一要是人家利用了别人的通道如何?Url发错了,编号通过了。或者更极端点。这安全级别不够。于是想到一个办法,在服务器Apache上做了手脚:验证IP(非合作商无法进入)。同时共用一个Url,会将合作商编号与产品编号一起生成一个md5号,通过后去验证一下md5就行了。虽然不是在最大程序上做到安全,不过我们都建立在友好合作的前提下的,没必要那么干,冒充别人的发。而且md5值你也无法知道。

  3、在实体类中加入:周未是否充下发(本来还想搞节假日,这太不靠谱了除非专门找人维护这个去,一年一个变。)、开启状态(关闭,暂停,运行)。从而决定这一堆信息能否下发。

  

  二、性能

  说实话安全这块做到这基本上就算成了。但还并不是很完美,但是有时候在性能上考虑,还真不能再加太多东西了,一天量一大必然影响性能。

  1、为了能够更好的实现性能上的最优,大家都知道减少数据库访问次数,这是最先考虑的,因为代码的速度运行远远高于数据库啊。所以呢我们的数据库就采用了一张大表设计(把合作商id,名称,产品,发送所有方式,发送方向,合作商md5编号等)。有些东西并不怎么符合范式,但是为了效率吗,这种东西多一张表,他就会多更多的复杂度。性能上会有更多的损耗。基本上每一个产品发送取一次数据库就行了。(一个产品上百万手机号+信息内容)

  2、其次就是代码了,数据库已经不是瓶颈了,基本上用户从进为就已经通过Ip验证了,也就是有钥匙了,而且去数据库取的东西无非就是“指纹验证”,并且预读入一些用户信息。数据库就算是一个钟头下发两三百个产品也不是问题。

      3、 所以现在的优化方向是代码:做的第一件事就是重构。大家也注意到了其实有多个下发方式,选择的下发方式不同那么实现代码也不同。原来写的代码if else过多,基本上代码没有可阅读性。于是采用策略模式重构了一下,把相同的代码抽出来,这样代码条理就清晰了。在策略模式上我们没有选择反射,更没有选择数据库,因为怕效率上跟不上,为了效率我们有context里写了个静态map用于存储各种实现方法。因为我们的下发方式非常固定,基本上大半年也改不了一两次,所以写到代码上比较合适。

  4、第四点从一定程度上还是讲的第一点,但是我还是有必要提一下。就是尽量把通用性的属性用静态方法写到代码里,这样会好很多。(虽然在数据库上数据是一口气全拿上来的,但是感觉这样会好点。至少便于阅读

   

  三、日志

  这一点非常重要,说难听的,以后出了问题打官司还得用他呢(至于能不能作为呈堂证供就是我们要过分研究的东西了。)。但我们的记录的详细,啥时间,啥内容,发向啥手机,发送状态等。这里主要就使用log4j.

      这个现在实现有点凌乱(到处乱加log),但是吧。主要是原来那个程序,一起还没按我写好的代码把东西重构好,不然这log得在一个统计的地方调用他。

 

  

      这个接口的设计吧我就写这么多,但是,总感觉不是很全面,也希望听听大家的想法。有什么砖可以拍。不过目前我们还没用上好的http接口的框架啊啥的。大家也可以推荐一下!

  

     

   发表时间:2009-05-30   最后修改:2009-05-30

希望大家能极力的拍砖,你的砖头我的荣幸啊!

0 请登录后投票
   发表时间:2009-05-30  
感觉你对性能这块提到的代码,基本将的都是重构。

可以再考虑几点:

1. 从服务商接受到发送短信请求后,采用线程池进行处理
2. 使用log4j记录,可以考虑下是否采用异步处理。 每秒几百的并发,log IO开销也不小。
3. 考虑代码的扩展性,比如水平扩展性(采用集群) 和 纵向扩展(业务分模块,分布式), 还有更深一点的云计算。 以后几千W的压力,单靠一台机器肯定不现实。

还有些小建议
1. 你们是通过apache进行了一个IP验证。 其实我觉得做为一个短信服务,安全这块已经属于你业务的一部分,可以在业务代码中专门设计一块内容处理。个人觉得使用apache不太合适。如果以后apache升级或者换http服务器,你这块安全验证迁移相对麻烦。
2. http接口框架可以考虑轻量级的hessian或者phprpc等,或者比较原始的xml,自己解析。
3. 可以结合业务采用cache机制,减轻服务压力。 比如对商户的信息或者其他的业务对象。
4. 对商户的请求数限制? 还是可以无限制? 如果一个商务进行恶意的高并发请求。。。
5. 没必要扣JAVA代码中一点反射和异常等的一点点性能。
。。。。。

暂时只能想到这些
1 请登录后投票
   发表时间:2009-05-30  
总感觉你这个东西做的 网关不像网关,接口不像接口. 有点粗糙的感觉.
1,根据你业务我任务可以定位成一个短信网关.
2,前端请求应该是一个短连接请求,只是负责发送指令,企业发送完指令后服务的应该给它一个服务令牌标识(标识这次任务的) 这样交互就完成了.
3,服务的(短信网关)在收到指令后应该是进行静默处理的.日志应该批量写(10000条写一次或者10分钟写一次), 线程也许可以帮你解决一些问题 但是要考虑线程的模型,这种我推荐用LF线程模型.
4,服务的应该有一个完整的任务处理机制,提供包括重试,任务状态定位,任务日志记载,容错处理等功能 比如某些任务可以进行重试的,某些任务不能重试直接到失败状态的等等
5,对于楼上agapple的建议,楼主可以考虑在设计模式上进行解决.应用链模式(可以包括校验链,任务链等等).服务的的框架应该是基于会话的,一个客户请求是一个会话,这个会话包括的流程可以有 合法性校验链(IP,用户,时间,业务ID等等), 前期处理逻辑链条(解压,加密,编码转换等等),业务处理链.这些JAVA的接口可以帮你的忙.这样做基于两个地方考虑 第一.你的领域是一个会话,领域模型很固定 第二,方便扩展,可以实现热插拔功能.代码也容易维护

6,客户端要跟踪这个任务的情况,可以根据2的任务标识进行跟踪.所以你的服务的应该有几个子处理逻辑 最少要包括 登入,提交,跟踪,退出.
个人意见仅供参考!
1 请登录后投票
   发表时间:2009-05-31  
fjlyxx 写道
总感觉你这个东西做的 网关不像网关,接口不像接口. 有点粗糙的感觉.
1,根据你业务我任务可以定位成一个短信网关.
2,前端请求应该是一个短连接请求,只是负责发送指令,企业发送完指令后服务的应该给它一个服务令牌标识(标识这次任务的) 这样交互就完成了.
3,服务的(短信网关)在收到指令后应该是进行静默处理的.日志应该批量写(10000条写一次或者10分钟写一次), 线程也许可以帮你解决一些问题 但是要考虑线程的模型,这种我推荐用LF线程模型.
4,服务的应该有一个完整的任务处理机制,提供包括重试,任务状态定位,任务日志记载,容错处理等功能 比如某些任务可以进行重试的,某些任务不能重试直接到失败状态的等等
5,对于楼上agapple的建议,楼主可以考虑在设计模式上进行解决.应用链模式(可以包括校验链,任务链等等).服务的的框架应该是基于会话的,一个客户请求是一个会话,这个会话包括的流程可以有 合法性校验链(IP,用户,时间,业务ID等等), 前期处理逻辑链条(解压,加密,编码转换等等),业务处理链.这些JAVA的接口可以帮你的忙.这样做基于两个地方考虑 第一.你的领域是一个会话,领域模型很固定 第二,方便扩展,可以实现热插拔功能.代码也容易维护

6,客户端要跟踪这个任务的情况,可以根据2的任务标识进行跟踪.所以你的服务的应该有几个子处理逻辑 最少要包括 登入,提交,跟踪,退出.
个人意见仅供参考!

恩楼上两位的发言都非常中肯,都是金砖。
楼上说的第二点我们确实是做了,每次请求结束,我们也会返一个信息给合作商。同时对于各种错误我们也约定好一些错误码:比如返回0100就是成功,0200ip验证无效等!
非常感谢大家提的一些好建议!
0 请登录后投票
   发表时间:2009-05-31  
天机老人 写道
fjlyxx 写道
总感觉你这个东西做的 网关不像网关,接口不像接口. 有点粗糙的感觉.
1,根据你业务我任务可以定位成一个短信网关.
2,前端请求应该是一个短连接请求,只是负责发送指令,企业发送完指令后服务的应该给它一个服务令牌标识(标识这次任务的) 这样交互就完成了.
3,服务的(短信网关)在收到指令后应该是进行静默处理的.日志应该批量写(10000条写一次或者10分钟写一次), 线程也许可以帮你解决一些问题 但是要考虑线程的模型,这种我推荐用LF线程模型.
4,服务的应该有一个完整的任务处理机制,提供包括重试,任务状态定位,任务日志记载,容错处理等功能 比如某些任务可以进行重试的,某些任务不能重试直接到失败状态的等等
5,对于楼上agapple的建议,楼主可以考虑在设计模式上进行解决.应用链模式(可以包括校验链,任务链等等).服务的的框架应该是基于会话的,一个客户请求是一个会话,这个会话包括的流程可以有 合法性校验链(IP,用户,时间,业务ID等等), 前期处理逻辑链条(解压,加密,编码转换等等),业务处理链.这些JAVA的接口可以帮你的忙.这样做基于两个地方考虑 第一.你的领域是一个会话,领域模型很固定 第二,方便扩展,可以实现热插拔功能.代码也容易维护

6,客户端要跟踪这个任务的情况,可以根据2的任务标识进行跟踪.所以你的服务的应该有几个子处理逻辑 最少要包括 登入,提交,跟踪,退出.
个人意见仅供参考!

恩楼上两位的发言都非常中肯,都是金砖。
楼上说的第二点我们确实是做了,每次请求结束,我们也会返一个信息给合作商。同时对于各种错误我们也约定好一些错误码:比如返回0100就是成功,0200ip验证无效等!
非常感谢大家提的一些好建议!

楼主,可能你有点误解我的意思了.我说的第二点 并不是指错误代码.和你举个例,比如你去银行取钱,你要先拿个流水号吧.我说的返回信息其实是指这个流水号,这个流水号是让企业用户能够查看这次任务的执行情况的.因为你上线程队列后其实用户是不知道执行情况如何的,你也不可能让用户一直保持连接 然后告诉他执行结果
0 请登录后投票
   发表时间:2009-05-31  
对数据量的优化我个人认为做的还不够,觉得对大数据量查询时应使用分表存储,(如果你不涉及太多的更新操作),每张表以索引来区分!小弟才浅,说错情见谅!
0 请登录后投票
   发表时间:2009-05-31  
天机老人 写道
fjlyxx 写道
总感觉你这个东西做的 网关不像网关,接口不像接口. 有点粗糙的感觉.
1,根据你业务我任务可以定位成一个短信网关.
……

恩楼上两位的发言都非常中肯,都是金砖。
……
quote]
楼主,可能你有点误解我的意思了.我说的第二点 并不是指错误代码.和你举个例,比如你去银行取钱,你要先拿个流水号吧.我说的返回信息其实是指这个流水号,这个流水号是让企业用户能够查看这次任务的执行情况的.因为你上线程队列后其实用户是不知道执行情况如何的,你也不可能让用户一直保持连接 然后告诉他执行结果


了解你的意思了,这有点像队列。
目前我们就有用户差不多有这种需求,他需要了解有哪些号码的内容没有发送成功。就是你说的这种实现方式,每次请求就给分返回一个流水号(像去银行先领一张排队号)。然后能根据流水号返回相应的执行情况。
  不过我们这个体系目前还不是建的很完整,需要更健全一点。谢谢你的提醒,我们当时有点是被这个需求牵着走不得以做了这么一个功能。你这么一说我倒提醒我了,有必要把这个功能做的更健全一些,以应对合作商的需求!
0 请登录后投票
   发表时间:2009-05-31  
我看数据库里一个大表的设计可能不是什么好方法。
读取数据库时有一些表连接没什么大问题的。
不知道你是凭感觉猜的,还是做过性能测试,你的大表设计是否的确能提高性能?
0 请登录后投票
   发表时间:2009-05-31  
fjlyxx 写道
天机老人 写道
fjlyxx 写道
总感觉你这个东西做的 网关不像网关,接口不像接口. 有点粗糙的感觉.
1,根据你业务我任务可以定位成一个短信网关.
2,前端请求应该是一个短连接请求,只是负责发送指令,企业发送完指令后服务的应该给它一个服务令牌标识(标识这次任务的) 这样交互就完成了.
3,服务的(短信网关)在收到指令后应该是进行静默处理的.日志应该批量写(10000条写一次或者10分钟写一次), 线程也许可以帮你解决一些问题 但是要考虑线程的模型,这种我推荐用LF线程模型.
4,服务的应该有一个完整的任务处理机制,提供包括重试,任务状态定位,任务日志记载,容错处理等功能 比如某些任务可以进行重试的,某些任务不能重试直接到失败状态的等等
5,对于楼上agapple的建议,楼主可以考虑在设计模式上进行解决.应用链模式(可以包括校验链,任务链等等).服务的的框架应该是基于会话的,一个客户请求是一个会话,这个会话包括的流程可以有 合法性校验链(IP,用户,时间,业务ID等等), 前期处理逻辑链条(解压,加密,编码转换等等),业务处理链.这些JAVA的接口可以帮你的忙.这样做基于两个地方考虑 第一.你的领域是一个会话,领域模型很固定 第二,方便扩展,可以实现热插拔功能.代码也容易维护

6,客户端要跟踪这个任务的情况,可以根据2的任务标识进行跟踪.所以你的服务的应该有几个子处理逻辑 最少要包括 登入,提交,跟踪,退出.
个人意见仅供参考!

恩楼上两位的发言都非常中肯,都是金砖。
楼上说的第二点我们确实是做了,每次请求结束,我们也会返一个信息给合作商。同时对于各种错误我们也约定好一些错误码:比如返回0100就是成功,0200ip验证无效等!
非常感谢大家提的一些好建议!

楼主,可能你有点误解我的意思了.我说的第二点 并不是指错误代码.和你举个例,比如你去银行取钱,你要先拿个流水号吧.我说的返回信息其实是指这个流水号,这个流水号是让企业用户能够查看这次任务的执行情况的.因为你上线程队列后其实用户是不知道执行情况如何的,你也不可能让用户一直保持连接 然后告诉他执行结果


楼主是那公司的?你的设计怎么这么熟悉呢?
不过要说一点哦,你这个接口只是一个接收数据的功能,正真和移动通信的功能不在这。。。呵呵

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics