资讯动态

中国移动MAS普通短信接入实战:架构、接口与避坑指南

发布时间:2026/10/16 11:01:43 来源:尧图企业网站定制
1. 从一条短信说起为什么还要折腾MAS短信这东西现在很多人觉得它已经过时了微信、钉钉、飞书满天飞谁还看短信但如果你在企业里做过系统对接尤其是做过通知类、验证码类、营销类消息的下发你就会发现短信依然是触达率最稳的那条通道。原因很简单它不需要用户装任何App不需要联网权限之外的任何授权也不需要对方在线。只要手机有信号短信就能到。而中国移动MASMobile Agent Server移动代理服务器就是企业接入中国移动短信通道的一个核心网关。说白了它是企业IT系统和移动短信网络之间的一个中间层。你这边把要发的短信内容、目标号码提交给MASMAS再把它送进移动的短信中心最终落到用户手机上。普通短信也就是我们常说的SMS是MAS最基础、最常用的一种业务形态。我之所以想写这篇东西是因为最近帮一个朋友的公司做了一套基于MAS普通短信的下发系统从申请账号、配置IP白名单、调接口、处理回执到后面踩了一堆坑整个过程下来积累了不少实战经验。网上关于MAS的资料要么太老要么太碎要么就是厂商文档那种冷冰冰的说明书真正从开发者角度讲清楚怎么接、怎么调、怎么排错的内容并不多。所以我把这次项目里的东西整理出来给后面要接MAS的人省点时间。这篇文章适合谁看如果你是后端开发、系统集成工程师、运维或者你是一个中小企业的技术负责人需要给公司系统加上短信通知能力那这篇内容应该能帮到你。我不讲虚的直接讲架构、讲参数、讲代码、讲排错。看完你至少能知道MAS普通短信是怎么回事怎么接接的时候要注意什么。2. MAS普通短信的整体架构与接入思路2.1 MAS到底是个什么东西先把这个概念说清楚。MAS不是中国移动直接暴露给所有开发者的一个公开API它更像是一个部署在企业侧或者移动侧的服务节点。传统上MAS有两种常见的部署形态一种是移动侧集中部署企业通过专线或者指定协议接入另一种是企业侧本地部署一台MAS服务器这台服务器再和移动的短信网关对接。不管哪种形态企业系统要发短信本质上都是把请求提交给MAS由MAS完成后续的协议转换和路由。普通短信在MAS里通常走的是CMPP协议或者SGIP协议这两个都是国内短信网关的经典协议。CMPP是中国移动的短信网关接口协议SGIP是中国联通的后来也有一些互通场景。对于MAS普通短信来说你作为企业开发者很多时候并不需要直接去写CMPP的二进制包因为MAS会提供更上层的接口比如HTTP接口、WebService接口或者提供SDK。但理解底层的CMPP结构对你排查问题非常有帮助因为很多错误码和状态报告都是从那一层透传上来的。我这次项目里用的是MAS提供的HTTP接口方式。为什么选HTTP因为团队里没有人熟悉CMPP的二进制协议而且HTTP接口调试成本低用Postman就能测日志也好看。当然HTTP接口的吞吐量不如直接走CMPP长连接但对于我们这种日均几千条、峰值几万条的场景完全够用。2.2 接入前必须搞清楚的几个问题在动手写代码之前有几件事你必须先确认否则后面会反复返工。第一你的短信是什么类型。普通短信分两种一种是验证码/通知类一种是营销类。这两者在运营商侧的管控力度完全不同。验证码类通常要求模板报备内容格式固定发送频率也有限制营销类则需要用户明确同意而且发送时间有严格限制比如不能在大半夜发。你如果搞混了轻则短信被拦截重则通道被关停。第二你的目标号码覆盖哪些运营商。MAS是中国移动的网关它发移动号码是最顺的。如果目标号码里有联通和电信的MAS通常也能发但走的是互通路由到达率和延迟可能不如移动本网。如果你的用户里非移动占比很高那就要考虑是否要接多个通道。第三你的发送量级和并发要求。MAS的HTTP接口一般有QPS限制具体数值取决于你申请的通道规格。如果你要群发几十万条那就不能一条一条同步调必须做队列和异步处理。这个后面我会详细讲。第四回执怎么拿。短信发出去不等于用户收到了。运营商会返回状态报告告诉你这条短信是DELIVRD成功送达还是UNDELIV未送达还是EXPIRED过期。这些回执对账、排错、统计到达率都非常重要。MAS通常提供两种回执获取方式一种是主动推送你提供一个回调地址另一种是你主动去拉。我建议用推送实时性好但你的回调接口必须稳定否则回执丢了就对不上账。2.3 整体链路长什么样我把这次项目的链路画一下虽然不能用图但用文字描述清楚。企业业务系统产生短信需求比如用户注册要发验证码。业务系统把消息丢进一个消息队列比如RabbitMQ或者Kafka。为什么用队列因为业务系统不应该被短信接口的延迟拖死短信发不出去不能影响主流程。队列后面是一个短信发送服务这个服务从队列里消费消息组装成MAS要求的HTTP请求提交给MAS。MAS返回一个提交结果比如提交成功或者提交失败错误码XXX。发送服务把这个结果记录下来同时等待MAS推送的状态报告。状态报告回来之后更新这条短信的最终状态并触发后续逻辑比如失败重试或者告警。这个链路里最核心的是发送服务和回执处理服务。发送服务要处理限流、重试、模板渲染、号码校验回执处理服务要处理并发写入、幂等、对账。下面我逐个拆开讲。3. 核心细节解析与实操要点3.1 账号申请与IP白名单配置MAS的接入不是你自己注册个账号就能用的通常需要走商务流程。你需要向移动或者移动的代理商提交申请说明你的业务场景、预计发送量、短信内容类型。审核通过后你会拿到几个关键信息账号、密码、接口地址、端口、企业代码有些叫SPID或者AppID、以及一个或者多个IP白名单。IP白名单这个事特别重要。MAS侧通常会限制只有白名单里的IP才能调用接口。这意味着你的发送服务必须部署在固定的公网IP上或者通过NAT网关出去。如果你用的是云服务器弹性公网IP可能会变那就得提前规划好用固定IP或者NAT网关。我这次就踩了一个坑测试环境用的是动态IP结果调接口一直报IP未授权查了半天才发现是白名单没加测试机的IP。注意申请白名单时要把生产环境、测试环境、灾备环境的出口IP都加上并且预留几个备用IP。否则一旦IP变动短信就断了。另外账号密码一般有有效期有些是90天强制更换。你要把这个写进运维日历不然到期那天短信突然发不出去排查起来很麻烦。3.2 短信模板报备与内容规范普通短信的内容不是你想发什么就发什么。运营商对短信内容有严格的审核机制尤其是验证码类短信必须使用报备过的模板。模板里可以带变量比如您的验证码是{code}5分钟内有效。报备的时候你要把模板内容、变量规则、使用场景都写清楚。模板报备通过后你会拿到一个模板ID。发送的时候你提交模板ID和变量值MAS会帮你拼装成最终内容。这样做的好处是运营商侧知道你在发什么不容易被拦截。如果你绕过模板直接发自定义内容短期内可能没事但一旦被运营商的风控系统抓到轻则拦截重则封通道。我这次项目里验证码模板报备花了大概两个工作日。营销类模板更久而且需要提供用户授权证明。所以如果你有上线时间要求模板报备一定要提前做。内容规范方面有几个红线不能碰不能包含敏感政治词汇不能包含色情暴力内容不能包含赌博、诈骗信息不能包含未经用户同意的营销内容。另外短信开头一般要带签名比如【某某公司】这个签名也是要报备的。签名和模板是绑定的不能随便换。3.3 HTTP接口的请求结构与参数详解MAS的HTTP接口通常是一个POST请求Content-Type一般是application/json或者application/x-www-form-urlencoded具体看版本。我这次用的是JSON格式。请求体里一般包含以下字段account你的账号password密码有些版本要求MD5加密后传msgid你生成的消息ID用于幂等和回执关联phone目标号码多个号码用逗号分隔但一般建议单条提交content短信内容如果用了模板这里可能是模板ID加变量templateid模板IDsign签名有些版本要求sendtime定时发送时间可选响应体里一般包含code状态码0或者200表示提交成功msg描述信息msgid你传上去的消息ID原样返回taskidMAS侧生成的任务ID回执里会带这个这里有个细节msgid是你自己生成的必须全局唯一。我建议用UUID或者业务前缀时间戳序列号的方式。为什么要唯一因为回执回来的时候你要靠msgid或者taskid去关联到具体是哪条短信。如果你重复了回执就对不上了。还有一个细节密码的加密方式。有些MAS版本要求密码明文传有些要求MD5有些要求MD5后大写。这个一定要看对接文档或者直接问移动的技术支持。我见过有人因为密码加密方式搞错一直报认证失败查了一整天。3.4 状态报告与回执处理状态报告是MAS主动推送给你的通常是一个HTTP POST请求推到你预先配置的回调地址上。推送的内容一般包含msgid你提交时的消息IDtaskidMAS侧的任务IDphone目标号码status状态比如DELIVRD、UNDELIV、EXPIRED、REJECTDreceivetime送达时间reporttime报告时间你的回调接口收到这个请求后要做的第一件事是返回一个成功的响应比如HTTP 200body里返回OK或者success。如果你不返回或者返回错误MAS可能会重推重推次数和间隔取决于配置。所以你的回调接口必须幂等同一条回执推多次你不能重复处理。我这次的回调接口是用Spring Boot写的收到回执后先写进一个Redis队列然后异步落库。为什么不在回调里直接写数据库因为回调接口的响应时间很关键如果你写库慢了MAS那边超时了它会认为推送失败然后重推。重推多了你的系统压力就大了。用Redis做缓冲回调接口只负责快速接收和入队后面的落库、对账、告警都异步做。提示回执里的status字段不同MAS版本可能不一样。有的用DELIVRD表示成功有的用0表示成功。一定要以实际对接文档为准不要想当然。3.5 限流、重试与幂等设计MAS的HTTP接口一般有QPS限制比如每秒100次。如果你超过这个限制MAS会返回限流错误比如too many requests或者特定的错误码。所以你的发送服务必须做限流。我这次用的是Guava的RateLimiter单机限流。如果有多台发送服务那就需要分布式限流可以用RedisLua实现。重试策略也很关键。不是所有失败都能重试。比如号码格式错误这种重试一万次也没用。但网络超时或者系统繁忙这种可以重试。我建议把错误码分类可重试错误和不可重试错误。可重试的错误用指数退避策略比如第一次等1秒第二次等2秒第三次等4秒最多重试3次。不可重试的错误直接标记失败并告警。幂等方面除了msgid唯一还要考虑重复提交。比如你的发送服务在提交给MAS之后还没收到响应就超时了然后你重试结果MAS其实已经收到了第一次请求。这时候如果msgid一样MAS应该做幂等处理不会重复发送。但有些MAS版本不支持幂等那就需要你在业务侧做去重。我这次的做法是在Redis里用msgid做key设置一个过期时间比如5分钟。提交之前先查Redis如果存在就跳过。4. 实操过程与核心环节实现4.1 环境准备与依赖安装我这次的技术栈是Java 8 Spring Boot 2.x Redis MySQL RabbitMQ。为什么用Java因为团队熟悉而且生态成熟。如果你用Python或者Go思路是一样的只是库不一样。依赖方面主要用到HTTP客户端OkHttp或者Apache HttpClientJSON处理Jackson或者Fastjson限流Guava RateLimiter队列Spring AMQP for RabbitMQ缓存Spring Data Redis数据库MyBatis或者JPA安装过程我就不赘述了都是标准操作。重点讲一下配置。在application.yml里我把MAS的配置单独抽出来mas: sms: url: http://mas.example.com:8080/sms/send account: your_account password: your_password callback-url: http://your-domain.com/mas/callback qps: 100 retry: max-attempts: 3 backoff: 1000这里url、account、password都是示例实际要用移动给你的。callback-url是你提供给MAS的回调地址必须是公网可访问的。4.2 发送服务的核心代码实现发送服务的核心逻辑是从队列里拿消息组装请求限流提交处理响应。先看消息的实体类public class SmsMessage { private String msgId; private String phone; private String templateId; private MapString, String variables; private String sign; private Date sendTime; // getters and setters }msgId在消息进入队列之前就生成好用UUID。phone要做格式校验必须是11位数字且以1开头。templateId是报备通过的模板ID。variables是模板变量比如验证码。发送逻辑Service public class SmsSendService { Autowired private RateLimiter rateLimiter; Autowired private OkHttpClient httpClient; Autowired private MasConfig masConfig; public void send(SmsMessage message) { // 限流 rateLimiter.acquire(); // 组装请求 MapString, Object request new HashMap(); request.put(account, masConfig.getAccount()); request.put(password, md5(masConfig.getPassword())); request.put(msgid, message.getMsgId()); request.put(phone, message.getPhone()); request.put(templateid, message.getTemplateId()); request.put(content, renderContent(message)); request.put(sign, message.getSign()); // 提交 String json objectMapper.writeValueAsString(request); Request httpRequest new Request.Builder() .url(masConfig.getUrl()) .post(RequestBody.create(json, MediaType.parse(application/json))) .build(); try (Response response httpClient.newCall(httpRequest).execute()) { String body response.body().string(); MasResponse masResponse objectMapper.readValue(body, MasResponse.class); if (masResponse.isSuccess()) { // 记录提交成功 saveSubmitLog(message, masResponse); } else { // 处理失败判断是否可重试 handleFailure(message, masResponse); } } catch (IOException e) { // 网络异常进入重试 handleNetworkError(message, e); } } private String renderContent(SmsMessage message) { String template getTemplateContent(message.getTemplateId()); for (Map.EntryString, String entry : message.getVariables().entrySet()) { template template.replace({ entry.getKey() }, entry.getValue()); } return template; } }这段代码里限流用的是Guava的RateLimiter在Bean初始化的时候创建Bean public RateLimiter rateLimiter(MasConfig masConfig) { return RateLimiter.create(masConfig.getQps()); }重试逻辑我单独抽了一个方法用递归或者循环实现。注意重试的时候要重新限流不能绕过。4.3 回执回调接口的实现回调接口是一个ControllerRestController RequestMapping(/mas) public class MasCallbackController { Autowired private RedisTemplateString, String redisTemplate; PostMapping(/callback) public String callback(RequestBody MasReport report) { // 快速入队 String json objectMapper.writeValueAsString(report); redisTemplate.opsForList().leftPush(mas:report:queue, json); return OK; } }然后有一个消费者从Redis队列里拿数据落库Component public class MasReportConsumer { Scheduled(fixedDelay 100) public void consume() { String json redisTemplate.opsForList().rightPop(mas:report:queue); if (json ! null) { MasReport report objectMapper.readValue(json, MasReport.class); // 幂等检查 if (isProcessed(report.getMsgId())) { return; } // 更新数据库 updateSmsStatus(report); // 标记已处理 markProcessed(report.getMsgId()); } } }这里用Redis的List做队列简单够用。如果量特别大可以用RabbitMQ或者Kafka。幂等检查用Redis的setnxkey是msgId过期时间设长一点比如7天。4.4 数据库表设计短信记录表CREATE TABLE sms_record ( id BIGINT AUTO_INCREMENT PRIMARY KEY, msg_id VARCHAR(64) NOT NULL UNIQUE, phone VARCHAR(20) NOT NULL, content TEXT, template_id VARCHAR(64), status VARCHAR(20) DEFAULT PENDING, submit_time DATETIME, report_time DATETIME, error_code VARCHAR(20), error_msg VARCHAR(255), retry_count INT DEFAULT 0, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_phone (phone), INDEX idx_status (status), INDEX idx_create_time (create_time) );status字段的取值PENDING待提交、SUBMITTED已提交、DELIVRD已送达、UNDELIV未送达、EXPIRED过期、REJECTD被拒、FAILED提交失败。回执记录表CREATE TABLE sms_report ( id BIGINT AUTO_INCREMENT PRIMARY KEY, msg_id VARCHAR(64) NOT NULL, task_id VARCHAR(64), phone VARCHAR(20), status VARCHAR(20), receive_time DATETIME, report_time DATETIME, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_msg_id (msg_id) );这两张表通过msg_id关联。对账的时候用sms_record左连sms_report找出没有回执的记录重点排查。4.5 参数计算与容量规划假设你的业务日均短信量是10万条峰值集中在上午9点到10点这一个小时的量占全天的30%也就是3万条。那么峰值QPS大约是30000/3600≈8.3。考虑到突发流量按3倍冗余QPS按25设计。MAS给你的通道QPS是100那完全够用。但如果你要做营销群发比如一次发50万条那就不能同步发了。我的做法是把50万条拆成小批次每批1000条丢进队列由发送服务慢慢消费。发送服务根据MAS的QPS限制控制消费速度。这样既能保证不超限又能尽快发完。存储方面一条短信记录大概占500字节10万条一天就是50MB一年不到20GB。MySQL完全扛得住。但要注意定期归档比如把3个月前的数据移到历史表避免主表太大影响查询。5. 常见问题与排查技巧实录5.1 提交失败类问题问题一认证失败现象MAS返回认证失败或者账号密码错误。排查思路先确认账号密码是否正确注意大小写和空格。然后确认密码的加密方式是明文、MD5还是MD5大写。最后确认账号是否过期有些账号有有效期。我踩过的坑密码里有个特殊字符在配置文件里被转义了导致实际传过去的密码不对。后来把密码用单引号包起来才解决。问题二IP未授权现象MAS返回IP未授权或者非法IP。排查思路确认你的出口IP是否在白名单里。如果你在云上确认是弹性IP还是NAT网关IP。如果是容器环境确认容器的出口IP。我踩过的坑测试环境用了动态IP每次重启就变后来申请了一个固定IP才稳定。问题三模板不存在现象MAS返回模板不存在或者模板未审核。排查思路确认templateid是否正确模板是否已经审核通过。有些MAS要求模板ID和签名必须匹配签名不对也会报这个错。5.2 回执异常类问题问题一回执收不到现象短信提交成功了但一直收不到状态报告。排查思路先确认回调地址是否公网可访问用Postman模拟MAS推送看你的接口能不能收到。然后确认MAS侧是否配置了回调地址有些需要手动配置。最后确认防火墙是否放行了MAS的IP。我踩过的坑回调接口用了HTTPS但证书是自签的MAS侧不信任导致推送失败。后来换成HTTP才解决。生产环境建议用正规CA签发的证书。问题二回执重复现象同一条短信收到多次回执。排查思路这是正常的MAS在没收到你的成功响应时会重推。你的接口必须幂等。用msgId做去重处理过的直接返回成功。问题三回执状态不对现象明明用户收到了短信但回执是UNDELIV。排查思路状态报告是运营商侧的最终状态有时候会有延迟或者误差。如果大量出现这种情况联系移动的技术支持查一下路由。另外有些手机设置了短信拦截也会导致状态报告不准确。5.3 性能与稳定性问题问题一发送服务被限流现象MAS返回too many requests。排查思路检查你的QPS是否超过通道限制。如果是多台发送服务检查是否做了分布式限流。我建议在发送服务前面加一个令牌桶用Redis实现所有实例共享。问题二回调接口超时现象MAS推送回执时你的接口响应太慢导致MAS重推。排查思路回调接口只做入队不做复杂逻辑。如果入队也慢检查Redis连接池是否够大。我这次把回调接口的响应时间控制在50ms以内基本没出现过重推。问题三数据库写入瓶颈现象短信量大了之后数据库写入变慢影响回执处理。排查思路批量写入代替单条写入。比如每100条回执批量insert一次。另外把回执表和记录表分开避免锁竞争。5.4 常见问题速查表问题现象可能原因排查方法解决方案认证失败账号密码错误、加密方式不对、账号过期检查配置、确认加密方式、联系移动修正配置、更新账号IP未授权出口IP不在白名单查出口IP、对比白名单添加白名单、用固定IP模板不存在模板ID错误、未审核、签名不匹配核对模板ID、确认审核状态修正模板ID、重新报备回执收不到回调地址不可达、防火墙拦截模拟推送、检查防火墙修正回调地址、放行IP回执重复MAS重推检查接口响应时间接口幂等、快速响应限流QPS超限检查发送频率限流、降速数据库慢单条写入、表太大查慢查询、看表大小批量写入、归档历史数据5.5 独家避坑技巧第一个技巧在发送服务里加一个影子模式。所谓影子模式就是短信不真正提交给MAS而是只记录日志。这个模式用于测试和压测避免测试短信真的发到用户手机上。我这次压测的时候就是用影子模式跑了10万条验证了队列和数据库的性能。第二个技巧对账任务要每天跑。用定时任务每天凌晨跑一次对账找出状态是SUBMITTED但超过24小时没有回执的记录以及回执状态是UNDELIV的记录。这些记录要人工介入排查可能是号码问题也可能是通道问题。第三个技巧监控告警要配好。关键指标包括提交成功率、回执到达率、平均延迟、队列积压量。提交成功率低于95%要告警回执到达率低于90%要告警队列积压超过1万条要告警。我这次用的是Prometheus Grafana效果不错。第四个技巧号码清洗很重要。发送之前把号码里的空格、横线、86前缀都去掉统一成11位纯数字。空号、停机号、黑名单号要过滤掉不然浪费短信费。我这次接了一个号码清洗服务把无效号码过滤掉节省了大概5%的成本。第五个技巧短信内容里不要带URL短链。运营商对短链的管控很严容易被拦截。如果一定要带链接用正规域名并且提前报备。6. 成本控制与通道选型的一点经验6.1 短信计费方式与成本构成MAS普通短信的计费一般是按条计费成功提交计费失败不计费。但不同通道的单价差别很大。验证码类短信通常比营销类短信贵因为验证码要求更高的到达率和更快的速度。营销类短信便宜但到达率低而且容易被拦截。成本构成里除了短信费还有通道费、模板报备费、以及可能的维护费。如果你是通过代理商接的代理商还会加价。我这次对比了几家代理商单价从0.03元到0.05元不等。最后选了一家0.035元的但要求月发送量不低于10万条。6.2 如何评估通道质量评估通道质量不能只看单价。要看几个指标到达率、延迟、稳定性、回执准确性。到达率是最重要的。同样发1万条A通道到达9500条B通道到达9000条那A通道的实际成本更低。延迟也很关键验证码短信如果延迟超过10秒用户可能已经放弃了。稳定性方面要看通道是否经常出故障故障恢复时间多长。我这次的做法是先小批量测试。每个通道发1000条对比到达率和延迟。测试的时候要用真实的号码覆盖移动、联通、电信。测试时间也要分散早中晚各发一批看不同时段的差异。6.3 多通道冗余与切换策略如果你的业务对短信依赖很高建议接至少两个通道。主通道和备通道。正常情况下走主通道主通道故障或者到达率下降时自动切换到备通道。切换策略可以基于实时监控数据。比如主通道的提交成功率连续5分钟低于90%就自动切换。切换的时候要注意正在队列里的消息要重新路由。我这次用了一个简单的策略在发送服务里配置多个通道每个通道有一个权重和健康状态。健康状态由定时探测任务更新。发送的时候根据权重和健康状态选择通道。注意多通道切换时msgId要保持唯一避免回执混淆。不同通道的回执格式可能不一样回调接口要能兼容。6.4 短信内容优化与成本节省短信内容越短成本越低。普通短信按70个字符一条计费超过70个字符按多条计费。所以内容要尽量精简。验证码短信一般很短问题不大。通知类短信要注意把不必要的信息去掉。另外签名也会占用字符数。签名一般放在开头比如【某某公司】占6个字符。如果签名太长也会增加成本。所以签名要简短。还有一个节省成本的技巧合并发送。如果同一个用户有多条通知可以合并成一条短信发。比如您有2条新消息请登录查看。但要注意合并后的内容不能太长否则反而更贵。7. 上线部署与运维要点7.1 部署架构与高可用发送服务和回调服务都要做高可用。至少两台实例前面挂负载均衡。数据库用主从架构主库写从库读。Redis用哨兵或者集群模式避免单点故障。我这次的部署架构是两台发送服务两台回调服务一个MySQL主从一个Redis哨兵。发送服务和回调服务都注册到Nacos通过网关暴露。MAS的回调地址配置的是网关地址网关再转发到回调服务。7.2 日志与监控日志要打全。每条短信的提交请求、响应、回执都要记录。日志里要包含msgId、phone、status、耗时。方便后面排查问题。监控方面除了前面说的业务指标还要监控系统指标CPU、内存、磁盘、网络。特别是回调服务的CPU如果回执量突然增大CPU可能会飙高。我这次用ELK做日志收集用Prometheus做指标监控用Grafana做展示。告警通过钉钉机器人发送到群里。7.3 灰度发布与回滚短信服务上线建议先灰度。先切10%的流量到新服务观察一天没问题再逐步放大。如果出问题立即回滚。灰度的时候要注意新旧服务的msgId不能冲突。我这次用了一个前缀区分新服务用NEW_旧服务用OLD_。回执处理的时候根据前缀路由到不同的处理逻辑。7.4 日常运维检查清单每天检查提交成功率是否正常回执到达率是否正常队列是否有积压数据库连接池是否正常Redis内存是否正常每周检查通道到达率对比失败短信原因分析日志是否有异常磁盘空间是否充足每月检查账号密码是否快过期模板是否需要更新成本是否超出预算备份是否正常8. 一些个人体会做短信接入这件事技术难度其实不算高但细节特别多。一个参数不对一个IP没加一个模板没报备都会导致短信发不出去。而且短信这东西用户感知很强发不出去就是发不出去没有中间状态。所以做这个系统一定要细心要把各种边界情况都考虑到。我这次最大的体会是队列和异步化是必须的。不要把短信发送和业务逻辑耦合在一起。业务系统只管把消息丢进队列后面的限流、重试、回执处理都由专门的短信服务来做。这样业务系统稳定短信服务也可以独立扩展。另外回执处理比发送更重要。发送只是提交回执才是最终结果。很多人只关注发送成功不关注回执结果对账的时候发现一堆问题。回执的幂等、去重、异步落库这些都要做好。最后再分享一个小技巧如果你不确定MAS的某个参数怎么传直接抓包看。用Wireshark或者tcpdump抓一下MAS的请求看看实际传了什么。有时候文档写得不清楚抓包最直接。当然抓包要在测试环境做生产环境注意合规。这个内容后续还可以这样扩展比如接入多个通道做智能路由根据号码归属地和通道质量动态选择比如做短信内容的A/B测试对比不同文案的到达率和点击率比如把短信和App推送、微信模板消息打通做一个统一的消息中台。这些方向都挺有意思等后面有机会再展开聊。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑