概述
利用随机序列将原来内容相同的短信重新杂散混合,产生新的随机序列,使新的短信发送序列内容不一,从而规避电信公司的一些限制。负载均衡则将短信均匀地分配给各个设备(调制解调器),更快地分发给短信的接受者。
起因
去年(2021)十一、十二月间,发现发送短信的记录,在每天开始发送百多条后,后面的短信就发不成功了。此时,直接使用华为4G调制解调器的视窗界面,人工发送也不成功。怀疑华为4G调制解调器出问题,将原SIM卡(无限短信套餐)换到华为3G调制解调器,用AT命令控制发送,返回的代码是500,500意味发生了不知道错误。但是,从上一次发送出错十多个钟头之后,调制解调器又能发送短信了,这是个很奇怪的现象。
为了确定3G,4G调制解调器是不是正常,换用了另外一个电信公司的SIM卡,3G,4G调制解调器都能正常发送,这表明3G,4G调制解调器没有问题。
问题在哪里?我请教了短信专家,跟他谈了遇到的问题,他说那家(无限短信套餐)的电信公司有很多限制,很麻烦,先是每天限制1000条短信,不久又降到每天500条,现在我的短信服务器每天能发送成功的短信仅百余条。他建议我不要用那家电信公司,改用其他公司的服务。电信公司的服务合约一签就是两年,提前终止要赔不少钱,改用其他公司的服务不可取。
为了证实是不是电信公司的问题,我专门打电话去那家电信公司的客服查询,得到的答复是他们的系统检测到我们的短信应用于商业目的,而被暂停了短信服务。问她为何说我们用于商业目的?答曰:系统检测到很多相同的信息(信息长度一样)发给不同的人。
对策
现有五间诊所的短信是分时一次发送的,同一间诊所短信内容一样,因此电信公司很容易检测到相同的信息。
为了避免相同短信一起发送,现在诊所将要发的短信先发送到短信服务器,短信服务器收到的短信集中在一个先进先出的队列,然后将收到的五间诊所的短信所存放的地址进行杂乱重排形成一个新的随机排列的队列,利用新队列间接读取收到的短信信息,这样就就形成了长长短短杂乱不一的短信序列,从而避免了相同短信一起发的问题。
杂乱重排形成随机序列如图所示
采用杂乱序列发送短信,仍然在连续发送接近一百条时被中断了,又要隔十多个钟头才能恢复短信发送。从试验得知电信系统不但检测相同信息,也检测连续发送的短信量。如果连续发送短信量超过一定数量,即使是不同的信息,仍然会被阻断。
经过多次试验,得出每次短信发送不超过50条,每个钟头不超过100条,可以避免被阻断。
随着诊所的发展,要发送的短信越来越多,已经超出无限短信套餐每月10000条的限制,得另想办法解决。这种短信套餐每条短信的成本少过0.01新币,超出一万条的短信则每条0.0535新币。目前每月超出不多,不值得再订一条无限短信的套餐。市面上有24新币的预付卡,里面可发1000条短信,每条短信的成本是0.024新币。虽然这种预付卡的短信成本比无限短信套餐贵了一倍多,但比超过套餐限制后,每条0.0535新币便宜了一倍多,是目前折中可用的最佳方案。
因此,短信服务器采用了两个调制解调器(华为3G调制解调器和4G调制解调器),两条不同电信公司线(无限短信套餐和预付卡)。
实施
短信服务器(服务端)和诊所服务器(客户端)都是采用LAMP(Linux, Apache, Mysql, PHP)构成的网络服务器。
原来短信服务器只有一个调制解调器,诊所服务器将短信内容发给短信服务器,并且一直等到收到短信服务器的发送结果,才根据发送结果决定是否继续注册下一次的提醒,对于发送不成功的手机号码(可能是无效号码)是不会再注册的。如此重复发送,直到全部短信发完。
现在短信服务器使用两个调制解调器,诊所发来的短信信息不再马上发出,而是进入一个先进先出的队列。诊所服务器无法即时取得发送结果,发送结果需要几小时后才出来。原来同一诊所一气呵成的发送方式,现在变为两个步骤,第一步,将要发的短信信息发给短信服务器。第二步,若干钟头后再从短信服务器取回发送结果,并根据发送结果决定注册下一次的提醒。
从客户端(诊所服务器)看,原来的短信服务从请求发送到收到发送结果是联在一起完成的(类似同步完成)。而现在要分两步走,先将要发送的短信内容和接收者号码等信息发送给短信服务器,若干小时后再从短信服务器取回发送结果,是异步处理。
原来的短信服务器只记录了发送的短信内容、接收者的号码和发送的结果,供查看而已。现在改用杂散混合队列,异步处理,原来的发送记录已无法应付诊所服务器所需,需要增加诊所标识、接收者的标识、信息类型(提醒短信和紧急短信),方能鉴别出各间诊所所需类别的信息。这些信息是由客户端提供给服务端的,因此客、服两端的软件都需要相应的更改。
短信服务器和诊所服务器的关系,虚线表示通过互联网连接。
一 、短信服务器 — 服务端
硬件方面增加了一个调制解调器。现在用两个发送短信的设备,1号设备—华为4G调制解调器,型号E3372,采用基于Web服务器的HiLink协议。2号设备—华为3G调制解调器,型号E220,串行接口,利用AT命令控制。发送短信的设备可以视业务的发展而扩展。
根据诊所短信的性质,可以将短信分为若干类,例如,紧急呼叫和常规提醒短信,紧急呼叫短信需要马上发出,而常规提醒短信则可以延后。我们暂将短信分为两类,高优先级的紧急呼叫类,低优先级的常规提醒类。紧急呼叫类短信长度不一,不需要额外加工,直接发送;常规提醒短信同一间诊所内容一样,需要将五间诊所的短信经过杂散混合处理后发送。因此短信服务器端的软件增加了两个先进先出环形接收信息的队列(提醒短信和紧急短信),一个杂散混合随机序列的工作队列,队列读、写、长度控制表,设备表(标识,名字,状态,调用计数器),设备控制表。
根据试验结果,每次短信发送不能超过50条,每小时不能超过100条。因此这些短信需要分时发送,那么,队列读写控制,设备状态,设备控制等数据,需要在本次请求执行完后,继续保留给下一次请求使用。PHP在Web服务器上可以采用Session来保留数据,这个方法在浏览器上执行是有效的,但是在没有浏览器的命令行执行则无效。短信服务器上的程序基本上是配合Linux系统的任务定时调用(crontab)在命令行上执行的,因此无法使用Session来控制,我们决定采用数据库来保存状态、控制变量。
先进先出环形队列是用来暂存各间诊所发送上来的短信的,它的长度设为每日最大信息量的五至六倍,差不多可以接受一个星期的短信信息。环形队列控制的难点是如何检测缓冲区是满、或是空。有多种策略用于检测缓冲区是满、或是空,常用的有:一, 读写指针总是保持一个存储单元为空;二,使用数据计数;三,镜像指示位。我们采用第二种方式。
负载均衡分配是将要发送的短信均衡分配给每一个设备,但是实际上不同的设备发送短信的速度不一样,例如,1号设备发送速度比2号设备快几倍,如果均衡分配给每个设备,则2号设备忙不过来时,1号设备却大部分时间处于空闲等待。我们的目的是短信分配给空闲设备,尽快完成发送任务。
短信服务器的软件结构,由设备驱动程序,信息队列,短信记录和负载均衡控制组成。
考虑到紧急短信内容不一,量少,可以不设限直接发送至完成。提醒短信内容一样,量大,需要经过杂散混合处理,设定每批发送的量,以规避电信公司的限制。提醒短信量大,占用发送时间长,因此,在发送过程中,每发送完一条短信都会调用检查发送紧急短信的程序,以保证紧急短信始终优先发送。负载均衡分配程序主要由检测发送紧急短信(Check and do higher priority message_queue)和检测发送提醒短信(Check and do reminder message_queue)组成。
程序如下:
Check and do higher priority message_queue
While high priority message_queue not empty
IF any device IDEL
Distribute message to this IDEL device
Move device pointer to point to next device
Else
BREAK
ENDIF
END WHILE
Check and do reminder message_queue
IF reminder message_queue not empty
IF first time process this queue
Generate a shuffle queue
ENDIF
While shuffle queue not empty
IF any device IDEL
Distribute message to this IDEL device
Move device pointer to point to next device
Else
BREAK
ENDIF
Check and do higher priority message_queue
IF total send SMS reached batch limit
BREAK
ENDIF
END WHILE
ENDIF
实现了负载均衡分配,对我们现在情况却不是最佳方案。因为我们采用的两条线,发送成本是不一样的,假定1号设备用的是无限短信卡,每条短信成本少过0.01新币,超过一万条则变成每条0.0535新币;2号设备用到是预付卡,每条短信成本是0.024新币。从经济效益考虑,最好在一万条内用1号设备发送,超过一万条用2号设备发送。考虑了每次发送的限制和成本效益这些因素后,实际使用的负载均衡分配程序更复杂。
二 、诊所服务器 — 客户端
客户端原来的短信服务从请求发送到收到发送结果以及后续的重新注册是一气呵成的。现在因为服务端需要先将各间诊所的短信收集一起,重新杂散混合处理,客户端得将要发送的短信加上一些额外的信息(诊所ID,病人ID,短信类型)发送给服务端,然后等几个小时,待服务端将短信发送完后,才从服务器取回发送结果,根据发送结果进一步注册后半年的短信提醒。
客户端的请求发送,收取结果,重新注册三个步骤,以前一气呵成,现在则分成两步走,第一步发送,第二步收取结果,重新注册。
三、发送设备
原来短信服务器调用设备发送短信一直等到设备返回结果,并记录发送结果。现在主程序则是将短信分配给设备后不管结果,继续分配短信给下一个设备。
原来短信服务器主程序负责的记录短信发送结果的功能,现在转移到设备驱动程序,每个设备发送完短信,同时记录短信的发送结果。设备驱动程序除了记录短信发送结果外,还多了设备状态,调用计数等的控制信息。
总结
将五间诊所的短信收集一起,重新杂散混合分时发送后,除了有效地规避电信公司的限制外,也有利于各间诊所柜台处理电话预约。之前同一间诊所的提醒短信一起发,往往造成柜台来不及处理,而患者抱怨诊所电话打不通。现在在同一时段发送的限量短信包含五间诊所的患者,这就使得柜台的压力大大减轻,诊所电话打不通的抱怨也大为减少。
利用负载均衡可以控制多个设备发送短信,除了更快发出短信外,只要适当地控制,能有效地提高经济效益,并且多设备比单一设备大大地提高了短信服务器的可靠性。