请选择 进入手机版 | 继续访问电脑版

短信人论坛

 找回密码
 立即注册

综合交流大区| 通道资源| 答疑专区 短信营销论坛| 房产短信| 祝福短信 短信平台论坛| 教育短信| 金融短信

邦之信| 杭州短信论坛| 今信科技 亿美软通| 上海短信平台| 合肥短信 长沙短信| 郑州短信平台| 武汉短信

沈阳短信| 成都短信论坛| 其他地区 中国移动| 中国联通| 中国电信 骗子曝光| 站务处理| 济南短信论坛

查看: 5323|回复: 0

从零设计一个高可靠的短信平台

[复制链接]
发表于 2018-5-31 21:51:12 | 显示全部楼层 |阅读模式
目前企业级开发对发送短信的支持,一般都需要接入各种专门做短信服务的第三方服务提供商。第三方服务提供商根据你发送的短信数量按量收费。
我们自身的业务要求当然是,所有的短信100%能送达,所有的短信必须x秒内发到手机上,不能有时延,即使时延不可避免,我们也希望能尽量力保如验证码等需要及时响应的业务不受短信时延的影响。
短信无时延,短信百分百必达只是一个理想愿望,实际上国内无任何的短信服务提供商能做到。因为这个除了编程技术和架构的支持,也需要移动联通电信等运营商的支持。下图是发送一个短信的数据包流转流程:

短信平台

短信平台

根据图片我们知道。影响短信到达率的一共有三个地方。链路A,链路B,链路C。链路A保证了我们能否把短信毫无时延的上送给服务提供商。是我们自己要做保证的技术问题。链路B保证了服务提供商能否毫无时延的将短信请求上送给移动联通电信等短信运营商。是服务提供商要保证的事情。链路C决定了运营商能否毫无时延的将短信发送给用户。
上面三个链路中,我们能保证的只有链路A和链路B。
对于链路A,我们可以优化自身的短信通道吞吐量和处理性能。
对于链路B,短信服务商那么多,我们可以找技术底蕴深厚的商家来合作。
对于链路C,我们就只有一个移动总公司,一个联通总公司,一个电信总公司,无法选择。这也就决定了,再好的服务运营商,也总会遇到短信发不出去的时候。如果移动联通电信挂了,你用的谁的短信服务也不好使。这也就需要技术人和产品人接受一个现实:像短信类功能,当前的技术现状就是:短信功能总会有故障的时候。
如何选择靠谱第三方
其实上一个议题已经说明了决策的依据之一:就是要看服务提供商的技术底蕴。作为一个程序员,我当然也是肯定优先信任大厂。除了服务提供商的技术底蕴,还需要根据以下两种依据来完成整个决策:
一,要看服务提供商的基础服务是否提供到位。
一个功能其实需要包含完整的两个部分:核心实现和业务监控。短信功能的核心实现,当然是,发送文本短信。发送语音短信。而短信功能的业务监控。包括能够获取短信发送结果的回执的功能,比如短信服务商能够提供给客户一段时间(如一天)内的每个手机号的每个发送记录的送达结果(下行状态报告)。再做的好一点的话,可以提供每天的短信发送到达率统计图报。当然也需要提供一些周边的功能(余额查询,配置查询,缴费,余额告警等)。周边功能可以使用服务提供商控制台登陆并操作。


那拿到短信的发送状态回执又有什么用?一来,技术人最怕被冤枉。如果拿到的状态回执是:目标手机号欠费,空号,信号不好,黑名单,欺诈手机号,手机缓存问题。那么我们就可以明白,这个人收不到验证码是他个人原因,客服可以告知用户理由,还我们自己的清白。而不是每次都抓瞎。二来,如果拿到的手机号的状态回执是:延迟,延迟,延迟,丢失......那么我们就可以以此作统计分析的基础数据。决策出谁家的短息服务最好用。


二,要看服务商的服务态度。
出了问题,打客服,有人接,愿意为乙方的关键业务时期保驾护航,都是加分项。
短信服务的技术架构
根据上一个议题的论断,你也许已经猜到了技术架构的要点之一:多商家接入。(如果土豪的话)在后台引入了通道的概念,可以在一方出了故障时自觉切换另一方。这样能最大力度保证我们产品中短信部分的功能质量。
关键词:多通道
另外,审视我们自身的业务,会发现,短信发送有两种场景:即时性需求(验证码),非即时性需求。(获得了奖励,今天能通知到就可以了)对于即时性需求验证码,一般都由用户手动触发,需要及时返回。且请求验证码频繁需要告知用户,因此采用服务调用API的方式,非及时性需求,短信服务无需告诉服务调用者,因为无意义。则更多的需要考虑与其他的业务服务的解耦,首选采用消费消息队列的方式。且使用消息队列,自动屏蔽了服务限流,服务熔断等直接调用服务需要面对的复杂性和风险,不必担心短信服务挂掉后影响其他服务的风险,好处多多。下图为架构一:

短信平台

短信平台

进一步思考,实际上前端对及时类验证码的需求的请求限制,也就是60s内不能频繁请求......这部分一般可以直接通过前端app来进行限制,如果有人能跳过60s请求频繁的前端限制,说明他在抓包请求,对于此类请求,即使后台将其拦截也无须告知。这样一来,业务系统就可以完全不关心短信平台的接口返回了,这一步,就可以将业务系统和短信系统彻底解耦。架构如下:

短信平台

短信平台

害怕使用消息队列会降低短信发送实时性?其实无须担心,现在的消息队列技术,如Kafka,如RocketMq,已经做了很好的实时性。实现不行,可以针对实时性要求高的短信和实时性要求不高的短信分别使用不同的队列处理。将实时性高的通道重点维护。这样就可以即兼顾业务响应实时性,又兼顾技术架构上的解耦性。架构如下:

短信平台

短信平台

以上三种架构,可以酌情根据实际情况有所取舍,选择其一。如果有时候必须要给用户返回一些什么,比如说他今天连着请求了100条短信,超限了,要提醒用户。(产品需要思考这部分提醒必须要做吗?)则只能必须有服务接口。
关键词:消息队列
短信服务的代码架构
短信服务的代码架构,需要从功能和将来的可维护性入手


功能有啥?对于短信核心实现,
一,多通道切换。
二,发送语音短信,发送文本短信。
三,黑名单,限流(同一用户x秒只能发送y条短信),限次(同一用户z小时只能发送k条短信)。对于短信运维服务:定时任务定期去每一个服务方拉取近期的发送下行状态报告。也需要作一个web界面,供客服人员直接查询下行状态报告,得知该短信是否发送成功,发送失败的原因是什么。


可维护性是啥?
一,在语言层面,不要把所有逻辑都写到一处,构成代码耦合。在运维层面,为了方便,一些和策略相关的配置都要做成活配。例如,x,y,z,k可以上配置中心。甚至和状态相关的东西(每个服务的sdk用的账号密码等配置,都可以活配,更改配置立即生效)
java语言,要从面相对象的角度思考与分析问题。接下来从短信核心实现和短信运维服务两个层面分别来设计代码。


短信核心实现之发送语音短信,发送文本短信。


这部分很容易使用策略模式来进行抽象。因为你可能有多个短信通道。为了便于维护,多个短信通道的细节不应该暴露给调用的客户端。根据面向接口编程与依赖抽象而不是依赖实现类的OO原则,你的客户端代码(API或者消息队列消费者)应该直接依赖一个抽象(例如,依赖一个Interface)而不要依赖一个实现类。你的Interface的一个职责就是:抽象发短信的行为,并将每一个短信通道的请求返回状态码和响应文字,转化成我们内部的API的响应码和响应文字。(外部状态转化为内部状态,相当于翻译)。但是,第三方错误码一定要保留,不能凭空吃掉。


接口中有几个函数?再根据业务线请求来抽象:
语音验证码   |   文本验证码   |   有限流限次黑名单逻辑 (验证码用) |  无限流限次黑名单逻辑。(后台业务用)...... 二二正交,则显而易见的接口需要提供四个函数:
一,发送文本短信,无限制
二,发送文本短信,带限流限次黑名单逻辑
三,发送语音短信,无限制
四,发送语音短信,带限流限次黑名单逻辑
A渠道B渠道C渠道分别是短信发送接口的三个实现类。


短信核心实现之通道切换


你的客户端代码(API或者消息队列消费者)到底需要注入什么样的实现类,则需要短息通道切换处理类来完成。
也就是说,你的客户端代码中的发送短信Interface,需要交给负责短信通道切换的类来实例化(策略工厂)
通道切换类负责做啥?
一,实例化短信发送实现类
二,切换通道
三,给每一个通道打分
怎么实现呢?
创建一个通道打分表,存储通道id和分数。每个通道的分数,初始值可能很大。
1:10000000000000000
2:9985865759885867
3:5697565745568607
配置中心的配置:当前通道id
current:3
通道切换类需要实现2个函数:
一,获取通道实现类(根据配置中心的id返回对应的实现类)
二,执行通道切换逻辑。
执行通道切换逻辑的实现细节:
一,当前通道降分。
二,找到另外n个通道中分数高的一个通道,设置current。
什么时候需要执行通道切换逻辑?
当第三方短信服务抛异常或者返回了非用户造成的错误码(注意:请求频繁,用户黑名单,手机号不合法等属于用户行为造成的错误,不属于短信服务商的问题,不应该执行通道切换逻辑。)
分析到这里,我们知道,由于哪些错误码是非用户造成的错误码,只有短信发送接口知道,因此,短信发送接口中除了之前的四个发送短信验证码的功能,需要再加一个函数声明ifCanChangeChannel(String errCode) 是否需要切换通道,由具体的子类实现。


短信核心实现之限流限次黑名单
   
需要有一些类专门处理这些逻辑,入参一般是手机号。根据上面的分析很明显我们可以知道,这些类需要自行实例化后注册到短信发送接口的实现类的限流实现队列中。(可以使用java责任链模式)


短信运维实现程序的功能


短信运维的功能其实就很简单了。
一,定时任务定期查询每个通道n天内的下行状态回执入库。
二,定时任务定期从数据库中删除每个通道n天外的下行状态回执。
三,也可以定期根据入库的回执记录作数据分析,对每个通道进行分数调整。
四,提供查询数据库每个手机号每次发送结果和状态查询的页面。
五,提供在页面上输入手机号直接去第三方查询最新的发送状态记录并入库的功能。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|新帖|sitemap|关于我们|短信人论坛

GMT+8, 2019-4-22 16:15 , Processed in 0.117484 second(s), 22 queries .

Powered by Discuz!X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表