; ;

基于CMPP协议集成短信测试桩全流程实践分享

以下是我投稿到公司的文章,有做一些更改

前言:

短信业务最底层是真实对对接运营商,使用的cmpp协议发送短信,而在测试环境中,不可能对真实环境来验证短信功能,原因:
1.测试需要发送大量的短信,费用会很高
2.需要模拟各种异常的消息 ,真实运营商有很多规则才能触发异常
3.需要对运营商快速返回各种错误,真实运营商可能会延迟,不利于测试
4.还需要针对大量数据时进行限速设置等各种场景
所以针对以上4点的考虑,最终我们选择自己“创建”一个运营商来处理数据客户端发来的数据,满足日常的短信业务测试
在模拟之前,我们需要对运营商使用的底层协议,交互方式,数据处理方式进行确认,才能更好的建立一个自己的“运营商”。


术语解释

英文缩写英文全称说明
CMPP China Mobile Peer to Peer 中国移动点对点协议
SP Service Provider 业务提供者,即信息资源站实体
ISMG Internet Short Message Gateway 互联网短信网关
SMC Short Message Center 短消息中心
gevent   python的一个并发框架,以微线程greenlet为核心
struct   Python的模块对字节进行打包和解包

1.认识cmpp协议

1.1网络结构

11ebb23a4be4dfe07df01997e1c30f02.png11ebb23a4be4dfe07df01997e1c30f02.png

如图1所示,互联网短信网关(ISMG)是外部信息资源站实体(SP)与移动网内短信中心之间的中介实体,互联网短信网关一方面负责接收SP发送给移动用户的信息和提交给短信中心。另一方面,移动用户点播SP业务的信息将由短信中心通过互联网短信网关发给SP。
1.2. CMPP功能概述
以下内容来自cmpp2.0文档的的介绍

短信接收(Short Message Mobile Terminated,SM MT)
典型的业务操作举例如图3所示:

d4ce08dea9e7e81660a194418948edc1.pngd4ce08dea9e7e81660a194418948edc1.png

图3  需要前转的MT示意图

  1. SP发出数据请求(可能是短信通知或手机铃声等),被源ISMG接收;
  2. 源ISMG对接收到的信息返回响应;
  3. 源ISMG在本地数据库中找不到手机号段所对应网关代码,向GNS(汇接网关)发路由请求信息;
  4. 汇接网关将路由信息返回;
  5. 源ISMG根据路由信息将请求转给目的ISMG;
  6. 目的ISMG对接收到的信息返回响应;
  7. 目的ISMG将请求信息发送至SMC;
  8. SMC向目的ISMG返回响应;

1.2协议栈

CMPP协议以TCP/IP作为底层通信承载,具体结构由图2所示:
266dfd21246f38c69836d9ff7e3c6895.png266dfd21246f38c69836d9ff7e3c6895.png

图1.2.1CMPP协议栈

ICP与ISMG以Clientmdash;Server方式建立TCP连接,用于双方信息的相互提交。
TCP/IP连接建立后,由Client发起建立应用层的连接,这时如果ICP或ISMG认为需要建立TLS连接,则在传输的数据包中置TLS字段,从而在双方建立TLS连接。
在应用层连接建立后的数据传输过程中,如果ICP或ISMG需要向对端发送加密信息,也可建立TLS连接,这时只需要置相应的消息体中Tls_available(是否使用TLS层)属性字段,本条消息的消息体中的其他属性不发送。
消息采用并发方式发送,加以滑动窗口流量控制,即接收方在应答前一次收到的消息多于窗口大小条将予以拒绝。流程图如图3所示:

4482b1fc33aa9b451aa2784f2cb90712.png4482b1fc33aa9b451aa2784f2cb90712.png

图1.2.2 长连接方式

1.2 .消息定义
消息定义是客户端与服务端之间“沟通的方式” 以下是cmpp协议内容的定义 (其中的一个鉴权协议)

基本数据类型

字节类型字节解释说明
Unsigned Integer 无符号整数
Integer 整数,可为正整数、负整数或零
Octet String 定长字符串,位数不足时,如果左补0则补ASCII表示的零,如果右补0则补二进制的零

消息结构

项目说明
Message Header 消息头(所有消息公共包头)
Octet String 定长字符串,位数不足时,如果左补0则补ASCII表示的零,如果右补0则补二进制的零

消息头格式(Message Header)

字段名字节数类型描述
Total_Length 4 Unsigned  Integer 消息总长度(含消息头及消息体)
Command_Id 4 Unsigned Integer 命令或响应类型
Sequence_Id 4 Unsigned Integer 消息流水号,顺序累加,步长为1,循环使用(一对请求和应答消息的流水号必须相同)

CMPP_CONNECT消息定义(SPàISMG)

字段名字节数类型描述
Source_Addr 6 Octet String 源地址,此处为SP_Id,即SP的企业代码。
Command_Id 4 Unsigned Integer 命令或响应类型
Sequence_Id 4 Unsigned Integer 消息流水号,顺序累加,步长为1,循环使用(一对请求和应答消息的流水号必须相同)

CMPP_CONNECT消息定义

字段名字节数类型描述
Source_Addr 6 Octet String 源地址,此处为SP_Id,即SP的企业代码。
  16 Unsigned Integer 用于鉴别源地址。其值通过单向MD5 hash计算得出,表示如下:AuthenticatorSource =MD5(Source_Addr+9 字节的0 +shared secret+timestamp)Shared secret 由中国移动与源地址实体事先商定,timestamp格为MMDDHHMMSS,即月日时分秒,10位。
Version 1 Unsigned Integer 双方协商的版本号(高位4bit表示主版本号,低位4bit表示次版本号)
Timestamp 4 Unsigned Integer 时间戳的明文,由客户端产生,格式为MMDDHHMMSS,即月日时分秒,10位数字的整型,右对齐

CMPP_CONNECT_RESP消息定义(ISMG à SP)

字段名字节数类型描述
Status 1 Unsigned Integer 状态0:正确1:消息结构错2:非法源地址3:认证错4:版本太高5~ :其他错误
AuthenticatorISMG 16 Octet String ISMG认证码,用于鉴别ISMG。其值通过单向MD5 hash计算得出,表示如下:AuthenticatorISMG =MD5(Status+AuthenticatorSource+shared secret),Shared secret 由中国移动与源地址实体事先商定AuthenticatorSource为源地址实体发送给ISMG的对应消息CMPP_Connect中的值。认证出错时,此项为空
Version 1 Unsigned Integer 服务器支持的最高版本号

3.构建服务端

3.1短信测试桩架构分析

如图3.1
bdb7086edc7377fbd64a8ae1269558fc.pngbdb7086edc7377fbd64a8ae1269558fc.png

图3.1
业务处理流程。
如图3.2所示
705f9242bbf35d828a3b5bd2691d4dd0.jpeg705f9242bbf35d828a3b5bd2691d4dd0.jpeg

图3.2

处理流程说明

  1. 服务端收到一条为39个字节的长度的请求数据,由于头部固定为12字节,剩余为27个字节
  2. 根据以上的协议27个字节长度判断是需要建立连接
  3. 获取客户端的连接的用户名与密码,解析AuthenticatorISMG字段验证是否鉴权成功
  4. 成功进行下一步操作 (需要回应 鉴权成功),在根据建立的连接后,对获取的数据进行处理,返回内容

我们以鉴权部分提取它的主要代码:

取出头部数据包
78989e40a40ed82ec6a9f479e6ec78a1.png78989e40a40ed82ec6a9f479e6ec78a1.png

获取主体内容,鉴权内容
2012de39e0b5679c6c98ef7a81133df7.png2012de39e0b5679c6c98ef7a81133df7.png

日志展示
b9a387d85c6837373046405a2c149713.pngb9a387d85c6837373046405a2c149713.png

3.2效果展示

短信测试桩目前已在测试环境中运行了2年多,帮助公司节省了一大笔测试费用,以下是它展示的效果内容

在iportal上展示,发送成功状态。
caedce5ac01be32ed7690667690ce0cb.pngcaedce5ac01be32ed7690667690ce0cb.png

在iportal上展示,发送失败状态。
9312ae4eb95726b7f55cb620548130d1.png9312ae4eb95726b7f55cb620548130d1.png

在iportal上展示,已发送的状态。
e989c12da6c6dd3dffabad4a3c4d5ed2.pnge989c12da6c6dd3dffabad4a3c4d5ed2.png

Iportal上展示,余额不足的状态
4d7396c33ec0d4ccd26965d90b6311c8.png4d7396c33ec0d4ccd26965d90b6311c8.png

3.3短信模拟桩遇到的问题

  1. 发送的请求数据量已经超过窗口大小

    当客户端发送的数量超过了大小处理大小,服务端进行限流,让任务进行排队处理并对它返回响应的code,以减轻服务端压力

  2. 代码建立无效的链接,浪费资源

    建立一个连接,就存储一个连接,当无效链接时,需要删除连接,如何判定无效,心跳连接不在建立,或建立连接后,20分钟内都没有发送消息(测试环境),服务端对断链进行处理

  3. 语言的选项,以及方案设计

    可选择java以及Python语言都可以,考虑Python在公司的使用程度较高,选择Python
    选择Python的类有struct模块,用户解析字节数据,使用gevent来解决协程,或者是Python提供的多进程

  4. 消息粘包
    读取数据时,根据头部的长度信息,按序读取ioArgs缓冲区中的数据,若没有达到长度要求,继续读下一个ioArgs解决粘包、半包问题。

我们逐步完善测试桩,它不仅具有解析数据的功能,发送报告,保持心跳、处理不同错误code,我们也提升了处理速度,以前是1分钟处理10个,现在1分钟能处理300个,满足我们大批量数据速度的一个提升,完善了我们各种场景的测试。

posted @ 2021-12-31 10:38  做梦的人-  阅读(581)  评论(1编辑  收藏  举报