基于 Cacti 等软件的性能监控方案

作者:wiLdGoose 发布时间:January 9, 2008 分类:技术 Technology

公司的服务器组遍布伟大祖国的大江南北,操作系统也都不相同。最近使用 Cacti + RRDTool + Net-SNMP 对这些服务器实施了统一的性能监控管理。单纯的 Cacti 不是监控工具,她基于 AMP 环境和 SNMP 协议,使用 snmpget 获取流量数据,使用 RRDTool 组件绘图。并且 Cacti 有个别名,叫做“仙人掌”。她的界面非常漂亮,你根本无需明白那些 RRDTool 的复杂参数就能轻易地绘出漂亮的图形。另外,她提供了强大的数据管理和用户管理功能,可以与 LDAP 结合进行用户的验证。还提供了自定义模板的功能,让你添加自己的 snmp_query 和 script。可以说,Cacti 将 RRDTool 复杂难懂的缺点都补足了。所以,Cacti 被认识是 MRTG 的最佳替代品。

1、监控管理端配置

监控端基于 FreeBSD 6.2 操作系统、AMP(ApacheMySQLPHP)环境,其安装配置过程在此不赘述,请寻求搜索引擎的帮助。值得注意的是,PHP 最好加上 SNMP 的支持。在编译的时候,加上 -enable-snmp。另外,PHP 不能运行在安全模式下,否则 Cacti 将不正常,无法调用 /usr/local/bin/ 下面的文件。除此之外,有一种说法称 MySQL 5 以上的版本不能正常运行 Cacti,就我的个人测试,暂未发现类似的情况。

安装完 AMP 之后开始下载并安装 RRDTool。值得注意的是,RRDTool 1.2.x 版本是用 libart 和 freetype 画图,相比 1.1.x 版本,前者的绘图速度会稍稍慢一些。从 1.2.x 版本开始,RRDTool 不再自带外部的 lib 库,所以需要从这里下载这些库来安装。而 1.1.x 版本自带了 GD 库,可惜这个 GD 库不支持中文,绘中文的时候会出现乱码。

这里选用 1.2.26 版本的 RRDTool,所以需要先安装 lib 库。

安装 cgilib

#tar -zxvf cgilib-0.5.tar.gz
#cd cgilib-0.5
#vi cgi.c

去掉:

#include <malloc.h>

然后:

#vi cgitest.c

将第 116 行

printf ("<h3>Cookie "Library" set</h3>\n");

改为:

printf ("<h3>Cookie \"Library\" set</h3>\n");

因为 cgilib 版本为 linux 版本,用 make 无法安装,所以:

#gmake
#gmake install
#cp *.h /usr/include/
#cp libcgi* /usr/lib

安装 zlib

#tar -zxvf zlib-1.2.2.tar.gz
#cd zlib-1.2.2
#./configure --prefix=/usr
#make
#make install

安装 libpng

#tar -zxvf libpng-1.2.8-config.tar.gz
#cd libpng-1.2.8-config
#cp scripts/makefile.gcmmx makefile
#./configure --disable-shared --prefix=/usr
#make
#make install

安装 freetype(需事先安装 gmake):

#tar -zxvf freetype-2.1.10.tar.gz
#mv /usr/bin/make /usr/bin/make.bak
#./configure --disable-shared --prefix=/usr
#make
#make install
#mv /usr/bin/make.bak /usr/bin/make

安装 libart_lgpl

#tar -zxvf libart_lgpl-2.3.17.tar.gz
#./configure --disable-shared --prefix=/usr
#make
#make install

安装 RRDTool

#tar -zxvf rrdtool-1.2.6.tar.gz
#./configure
#make
#make install
#cp /usr/local/rrdtool/bin/* /usr/local/bin/
#ln -s /usr/local/rrdtool-1.2.6 /usr/local/rrdtool

安装 net-snmp

#tar -zxvf net-snmp-5.2.1.2.tar.gz
#cd net-snmp-5.2.1.2
#./configure
#make
#make install

安装完成后运行 snmpget、snmpwalk 测试是否安装成功。

安装 Cacti

#cp cacti-0.8.7a.tar.gz /www
#cd /www/
#tar -xzvf cacti-0.8.7a.tar.gz
#mv cacti-0.8.7a cacti
#chown -R www:www cacti/

分配数据库权限:

#mysql -u root -p
mysql>create database cacti;
mysql>grant all privileges on cacti.* to cactiuser@localhost 
identified by 'password';
mysql>quit;

修改 Cacti 配置文件:

#vi /www/cacti/include/config.php
$database_type = "mysql";
$database_default = "cacti";
$database_hostname = "localhost";
$database_username = "cactiuser";
$database_password = "password";

导入数据库:

/usr/local/mysql/bin/mysql -u root -p cactidb < /www/cacti/cacti.sql

设置刷新时间:

#crontab -e
*/1 * * * * /usr/local/php/bin/php /www/cacti/poller.php > /dev/null 2>&1

这里的 */1 代表每一分钟执行一次。

2、被监控端配置

2.1、FreeBSD 系统

未完待续。

2.2、Windows 2003 系统

未完待续。

SQL Server 数据库异地备份策略优化

作者:wiLdGoose 发布时间:January 8, 2008 分类:技术 Technology

前段时间折腾了一个 SQL Server 数据库异地备份解决方案,使用了一些不够完美不够和谐的方法完成了设计需求。昨天看到一款软件叫做 NcFTP,经过思考,有了下面的优化方案。

原先的方案需要在双方服务器上安置批处理并加入计划任务,他们之间的先后顺序是没有握手联系的,只能依靠时间来排序。最佳途径应该还是只在一台服务器上安置批处理。原先需要在备份服务器上通过 curl 来 pull 当天的备份,现在有了 NcFTP,我们可以让数据库服务器主动 push 备份文件到备份服务器上。

@set ftp_ip=0.0.0.0
@set ftp_port=1234
@set ftp_user=this_is_ftp_user
@set ftp_passwd=this_is_ftp_passwd
@set ncftp_path=C:/Program Files/NcFTP

"%ncftp_path%ncftpput.exe" -u %ftp_user% -p %ftp_passwd% -P %ftp_port% %ftp_ip%/tmp.rar

而删除备份服务器上的旧备份文件,也可以抛弃 Henry Xu 同学用 C++ 写的程序了,可以使用 Resource kit 里的命令 FORFILES。

阅读剩余部分...

SQL Server 数据库异地备份解决方案

作者:wiLdGoose 发布时间:December 30, 2007 分类:技术 Technology

一直以来,公司某游戏平台使用 SQL Server 作为数据存储解决方案。为了数据的安全,每天凌晨在本机上做一次备份。但随着时间的推移,原先并没有设计到备份需求的硬件配置,尤其是外部存储这块,已经快不能满足 SQL Server 备份文件日益丰满的身姿。(这句话好像谁说过?)

为了彻底解决这个病痛,我打算为其实施远程异地备份。但查阅无数资料,均找不到较好的解决之道。大部分方案都是在备份目的地建共享目录,新增一个用户并赋权。然后在数据库端写个存储过程,添加数据库维护计划并使用这个存储过程。这样做有太多弊端:对于操作系统来说,很不安全;对于硬件架构设计来说,必须满足同一内网的条件。于是乎,放弃这样的方案。

经过几天的折腾测试,最后我采用了这样的方案。虽然比较老土,但至少 DIY 出来了,也暂时性满足了需求,缓解了阶级矛盾:

1、打开 SQL Server 企业管理器,找到数据库维护计划。

2、添加一个数据库维护计划,为其设置一个优美而和谐的名字,并选择需要操作的数据库对象。

阅读剩余部分...

MySQL 时区相关问题

作者:wiLdGoose 发布时间:December 28, 2007 分类:技术 Technology

昨晚,是一个愉快的、有意义的、充实的夜晚;昨晚,对于我的一生来说都是十分重要的一晚;昨晚,虽然是夜晚,但却是明媚、阳光的一晚。这一切,都是因为有了你,feelinglucky

lucky 兄已在 gracecode.com 上面概述了昨夜我们之间发生的故事,这里做一个全面的流水记录。让花花草草都来羡慕我们这天上的一对、地上的一双吧。

昨晚接到一个工单,要给一个客户对帐。我和同事 Henry Xu 分别在 MySQL 和 SQL Server 做了一次查询,结果显示的时间正好相差八小时。Henry 说:“肯定是你 MySQL 的时区有问题,慢了八个小时”。我看看是啊,想起 lucky 的一篇文章,于是到 phpmyadmin 中查询:

SELECT UNIX_TIMESTAMP();

结果显示的时间戳,通过 PHP 的 date 函数转换出来,确实与那时的北京时间相差八个小时。我继续在 phpmyadmin 中查询:

SELECT NOW();

这次结果居然是正确的。暂时糊涂了,看看时间,北京时间21点多,一通电话直接找到 lucky。这里插播一则广告,本人专业出售 lucky 手机号码,有需要的 MM 请直接在下面留言,谢谢。

我们一边谈一边查资料,后来在 MySQL 手册上看到:UNIX_TIMESTAMP() 是返回世界协调时 UTC 的时间,不参照本机系统时区。网上也有一种说法:使用 UNIX_TIMESTAMP() 函数是获取不到正确的当地时间的时间戳,除非当前系统时区就在 0 时区。后来 lucky 提示使用 CURRENT_TIMESTAMP() 代替,但是由于我目前的数据库设计习惯,暂时不能接收非时间戳的值。

后面 lucky 就在说服我使用 datetime 的数据库类型。我一边写了一个小脚本:

<?php
$a 
0000000000//从 phpmyadmin 中查询 SELECT UNIX_TIMESTAMP(); 后复制过来的 10 位数字
$b time();
echo 
date('Y-m-d H:i:s'$a) . "<br>" date('Y-m-d H:i:s'$b);
?>

并把这个脚本放到服务器上跑了一下,结果发现两行输出居然是一样的。我纳闷,然后将脚本复制到 Zend Studio 里面,F5…… My god,原来是 Zend Studio 的问题……

下面复制一些与 lucky 的交流记录,谨作这一夜的纪念。

feelinglucky: http://www.modwest.com/help/kb6-256.html
feelinglucky: -_- 我搜索 “mysql 时区”竟然都是我的文章……
wiLdGoose: 是的
feelinglucky: http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html
NOW 是正确的是吧?
用 CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP 看看
Synonyms for NOW()
wiLdGoose: ..........
feelinglucky: CURRENT_TIMESTAMP and CURRENT_TIMESTAMP() are synonyms for NOW().
feelinglucky: http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_current-date
http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_current-timestamp
wiLdGoose: 我知道的
他和 NOW() 一样的
我不要字符串的
我要整数
feelinglucky: Returns the current date and time as a value in 'YYYY-MM-DD HH:MM:SS' or YYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is used in a string or numeric context. The value is expressed in the current time zone.
这个是 NOW() 的,注意最后一句
wiLdGoose: yep
NOW 是对的啊
那 UNIX_TIMESTAMP() 就乱来了?
不根据当前时区了?
feelinglucky: UTC_TIMESTAMP()(v4.1.1) Return the current UTC date and time
是 return UTC 时间
当前 UTC 时间
feelinglucky: 应该用 UNIX_TIMESTAMP
wiLdGoose: http://www.linuxrpm.com/forums/viewtopic.php?t=232
看这个
他的意思是放弃 unix_timestamp
feelinglucky: 这种说法是不对的
wiLdGoose: ?
feelinglucky: 返回 UTC 时间是有用处的,不能更改的
打个比方,两台服务器之间如果跨时区的话,时间保证会统一到 UTC 时间的
CCTV 不是经常说的嘛“格林威治时间 XXX”嫦娥一号升空
wiLdGoose: 是不是 unix_timestamp() 返回的时间和 now() 就是不一样的
先不论格式
feelinglucky: 用 CURRENT_TIMESTAMP 不行吗
wiLdGoose: 那还是一样要改代码
feelinglucky: 至少可以确定它是根据时区选项来的
wiLdGoose: 再说 CURRENT_TIMESTAMP 返回的是 datetime 格式
feelinglucky: :( 搞不懂为什么一定要时间戳
wiLdGoose: i like it
:D
feelinglucky: 你不会吧数据库都用时间戳设计的吧。。。
wiLdGoose: 是的
feelinglucky: 然后用 INT(10) ?
wiLdGoose: 是啊
你喜欢 datetime?
feelinglucky: 天啊
:(
wiLdGoose: 来吧 说服我
我听着
feelinglucky: 这样快不了多少的
直观方面先不说,这个都清楚
然后就是计算问题
比如获得最近一周的所有数据,你怎么办?
在一个表里面
wiLdGoose: 你是不是想说, 用 datetime 类型的数据, 可以直接用mysql的函数比较日期
feelinglucky: 或者获得星期一我要的所有打卡记录
wiLdGoose: 时间戳也有时间戳的好处嘛
datetime的话, 遇到特殊情况, 还是要 strtotime
多不完美
feelinglucky: 如果按照你的,保证会有一个 xxxx < monday and xxxx > monday 这样的 WHERE 条件
想象一下,这个不是日期的比较哦,是整形对整形的比较
wiLdGoose: 是的
feelinglucky: PHP 方面你首先要知道星期一的时间戳,然后再让数据库 WHERE 计算
wiLdGoose: 数字与数字比较, 不是比字符串与字符串比较方便么?
feelinglucky: 相比 MYSQL 一条语句就 OK,哪个完美呢
时间类型不是字符串类型 :(
时间对于用户来看很直观,会“误认为”是字符串,但是在 mysql 内部存储还是长整型的
feelinglucky: 这个亲爱的可以 Google 一下
我以前也这样认为的,和你的做法一样,后来看了 wordpress 的数据库设计方面的一篇文章,谈到日期的数据库设计,才转变回观念来的
退一步讲,就算时间计算比整形的要低,但是毕竟用这个能方便很多
wiLdGoose: 我空了去研究一下, 先去改代码了
feelinglucky: OK,长篇大论留到 Blog 让亲爱的欣赏 :D
wiLdGoose: 好的.
Thx.
wiLdGoose: 我晕死了
feelinglucky: ?
wiLdGoose: 我发现我用php写一个 echo time() 输出都错的
但是php配置文件已经修改的了啊.
[Date]
; Defines the default timezone used by the date functions
date.timezone = PRC
feelinglucky: ?!
ft
wiLdGoose: 我吐血了, 刚才写了一个 test.php
你看看 www.xxxx.com/test.php
feelinglucky: 对的啊
wiLdGoose: 我被忽悠了
feelinglucky: ?
wiLdGoose: 我电话你, ok?
feelinglucky: ok

关于坚持使用时间戳还是转投 datetime 的环抱,我目前还没有想好。花点时间研究一下吧。

另外有一则好消息吧,Perl 5.10.0 终于释出了。

SP通用网关接口协议初探

作者:wiLdGoose 发布时间:December 18, 2007 分类:技术 Technology

因为某种需要,也不得不试着了解一下未知领域。首先介绍两个术语:

IVR:交互式语音应答模块,解释和运行应用业务流程的软硬件。
SP:业务提供商。

一、概述

1、功能简介

总的来说,通用网关是IVR和SP应用服务器之间进行消息交互的中间协议转换程序。通用网关的位置如下图所示:

IVR和通用网关之间采用内部协议,通用网关和外部SP应用服务程序之间采用TCP/IP协议,通用网关作为客户端,SP应用服务程序作为服务器端,可以采用长接连或者短连接两个连接方式。

对于一个通用网关,可以连接若干个SP的应用服务器,每个连接可以采用不同的连接方式和连接协议。

为了实现冗余备份和负载均衡,对于一个SP服务器,有时采用两个通用网关作为客户端与之进行连接。一般的,一个SP所有的业务交互接口都在一台应用服务器上。

按照TCP协议长连接和短连接的连接方式,以及业务数据否需要加密等业务需求,通用网关对外提供了四种方式的连接协议,分别是:短连接不加密的字符串传输方式,短连接根据密钥加密的传输方式,长连接不加密的字符串传输方式,以及长连接根据密钥加密传输协议。

下面根据一个业务流程的例子,对相关的IVR业务过程和接口协议的四种方式的做一个详细的描述。

2、业务举例

考虑如下一个IVR节目流程,该节目在增值声讯业务平台上,利用电信运营商代收费方式,为电话用户进行SP有关业务的帐号的充值。

假设该节目的接入号为12345,一个主叫为057188880000的用户,拨打该节目号,进入语音IVR流程;在流程中,根据IVR的语音提示,用户输入自己的在SP处的充值帐号 10001,以及要充值的金额10元,这10元的消费费用将由电信运营商在计费月末向当前主叫话机057188880000的帐户进行收费。IVR流程收集完相关的信息后,首先会让用户再次确认,然后将这些信息组合为一个字符串,各信息字段之间用一个分隔符隔开,如$等,譬如约定生成的字符串格式为“操作代码$主叫号码$被叫$充值帐号$充值金额(分)$时间戳$”,那么这里组合成的字符串最后就是“10$057188880000$12345$10001$10000$20071115165500$”,一共是50个字符。

这里需要说明的是,IVR业务流程能够发送、接收和处理的数据信息,就是这些文本字符串,IVR能对这些字符串进行解析:如分解、组合和判断,但不能处理其他如二进制字节流等方式的数据结构。

至于如何组织这些具体信息字段,字段间究竟采用什么字符进行分隔,字符串定长还是不定长,这些属于业务流程的具体应用协议,是由SP流程开发人员和SP应用服务程序开发人员之间进行协商约定的。同样,对最终返回给IVR的结果信息字符串,也是由他们进行协商约定的。

通用网关是不关心这些业务格式信息的,通用网关和SP应用服务程序之间,需要约定的是通信连接方式,字符串是否加密,如何完整的发送和接收每次交互的信息包等。

二、协议描述

通用网关对外提供了四种方式的连接协议,分别是:短连接不加密的字符串传输方式,短连接根据密钥加密的传输方式,长连接不加密的字符串传输方式,以及长连接根据密钥加密传输协议。

1、直接传输字符串的包格式

对于不加密的字符串短连接传输协议方式,由于传输的数据以“\0”为结束符,控制简单,因此数据是直接传输的,传输的包为以”\0”结尾的字符串数据。

2、需要包头信息的包格式

对于其他三种方式,包括根据密钥加密的短连接传输协议、不加密的字符串长连接传输协议、根据密钥加密的长连接传输协议,都需要在数据之前加上包头通信控制信息。

数据包格式如下图所示,所包含的内容从左到右进行传输:

这里值得注意的是包头中的信息全部为网络字节顺序。

包头的各字段说明如下:

包头信息中,除了包体长度(length)以外,其他的字段,包括开始标识(head),版本信息(version),任务流水号(taskid),发送方标识1(sender),发送方标识2(sessionid),时间戳(timestamp),以及数据加密标识(flag),需要在响应包中原样返回;否则通用网关接收返回消息后,可能解析出错,最终导致IVR业务处理错误。

再次说明:包头中的字段信息全部为网络字节顺序;短连接不加密方式不需要包头信息。

3、不加密字符串的短连接传输协议

这种方式并发性好,开发实现起来简单,程序配置方便,容易排除错误,适合于安全性要求不高,或要求高安全性但通过专线网络连接的业务;除了在公网上开展小额支付的业务以外,其他的业务都建议采用这种方式。

对于这种方式,系统消息交互的过程,大概分如下几个步骤,见下图所示:

(1)、IVR流程中收集完用户的相关信息之后,发送一个字符串给通用网关,在上述的那个例子中,这个字符串是” 10$057188880000$12345$10001$1000$20071115165500$”;

(2)、通用网关收到IVR流程业务应用请求之后,向SP服务器程序启动一个连接(Connect)请求;

(3)、SP应用服务程序此时应处于监听(Listen)状态,监听到有客户端请求连接;

(4)、SP应用服务程序根据此连接请求的IP地址等信息进行身份验证,如果验证通过则接受(Accept)连接请求,双方建立一个Socket连接;

(5)、通用网关在连接建立之后,立即开始发送(Send)刚才从IVR处接收到字符串数据(包括最后的’\0’),发送的字节数为字符串自身的长度加1,即strlen(发送字符串)+1;在上述的例子中,这里是strlen(“10$057188880000$12345$10001$1000$20071115165500$”)+1=51;

(6)、SP应用服务程序接收(Recv)该业务字符串,然后根据流程开发人员与之协商好的格式对接收的字符串进行解析,然后进行响应的处理;譬如例子中,分解出操作码10为充值操作,分解主叫为057188880000,帐号为10001,充值金额为10元等,然后查询该帐号是否存在和帐号状态是否合法,如果满足条件后,对该卡进行充值等操作;

(7)、SP应用服务程序处理对应的业务后,把处理后的结果数据进行加工,组合成字符串,发送(Send)给通用网关,同样的,该字符串格式是事先和流程开发人员进行协商确定的;如在例子中,充值成功后,返回”11$2$10001$1000$”的字符串,表示充值10元失败,11是充值操作响应码,2表示卡号不存在,10001表示卡号,1000表示刚才要充值的金额,以分为单位;

(8)、通用网关接收到(Recv)返回业务数据后,主动关闭(Close)和SP服务器的这次Socket连接,将返回的字符串信息原封不动的发送给IVR;

(9)、IVR收到该返回字符串” 11$2$10001$1000$”,然后根据业务流程对之进行解析,做进一步的处理,譬如提示用户说,该帐户不存在等;

(10)、如果SP应用服务程序在5秒钟中时间内,没有返回处理结果,通用网关会自动断开该Socket连接,然后向IVR报告处理超时消息。

4、根据密钥加密的短连接传输协议

这种方式并发性好,安全性高,但实现起来相对较难,联调出现错误不容易排除。在公网上实现的并发性高的电子商务类交互业务,建议采用这种方式。

本方式采用DES加密,双方需要约定一个密钥(Key),目前约定密钥为长度额为8位的字符串,一般由SP服务器端来指定,提供给通用网关的维护人员,由维护人员在本地对通用网关进行配置。

在发送数据给对方之前,通信的双方根据本地配置的密钥对数据进行DES加密处理;在收到数据后,同样根据本地配置的密匙进行解密处理;通信连接方式上和上述第一种完全一样。

具体过程详细说明如下,如图所示:

(1)、IVR流程中收集完用户的相关信息之后,发送一个字符串给通用网关;在上述的那个例子中,这个字符串是”10$057188880000$12345$10001$1000$20071115165500$”;

(2)、通用网关收到IVR流程业务应用请求之后,根据配置的8位密钥(这里假设为” SuntekD6”)进行加密处理,得到加密后的字节流,假设为32f69fce6dca6ace576b08115c099975817e2b3b68f9eafd6ca55dfec83816739b7152375
e09872b31acb888b4f4b83e6aee7d1bb8c5c41a39(57字节的二进制字节流)存储在本地;

(3)、通用网关向SP服务器程序启动一个连接(Connect)请求;

(4)、SP应用服务程序此时应处于监听(Listen)状态,监听到有客户端请求连接;

(5)、SP应用服务程序根据此连接请求的IP地址等信息进行身份验证,如果验证通过则接受(Accept)连接请求,双方建立一个Socket连接;

(6)、通用网关在连接建立之后,根据刚才加密的字节流,加上信息包头,组合成信息包,然后发送(Send)信息包,发送的字节数为加密后的字节流字节数+24(24信息包头的字节长度);在上述的例子中,信息包大约如ffff0200 00001100 00004e5f 00114b3f 00000000 0100 0038 2fd65329e2770074791503c2dab1d209fe0225636dd07f7277bd291209e1a498df28f7af2
f0eb4f1be2831f0fa8987b7f9;其中业务加密字节流的长度这里是56,体现在网络字节中是0x0038,如果是x86系列的PC,需要做主机到网络(ntohs)字节顺序转换;

(7)、SP应用服务程序接收(Recv)该信息包,根据包头信息截取对应的字节流,然后进行解密处理,得到加密前的业务字符串,另外还需要把其他的包头标识、两个包头保留字,存储在本地;

(8)、SP应用服务程序根据流程开发人员与之协商好的格式对接收的字符串进行解析,然后进行响应的处理;譬如例子中,分解出操作码10为充值操作,分解主叫为057188880000,帐号为10001,充值金额为10元等,然后查询该帐号是否存在和帐号状态是否合法,如果满足条件后,对该卡进行充值等操作;

(9)、SP应用服务程序处理对应的业务后,把处理后的结果数据进行加工,组合成字符串,同样,该字符串格式是事先和流程开发人员进行协商确定的;如在例子中,充值成功后,返回”11$2$10001$1000$”的字符串,表示充值10元失败,11是充值操作响应码,2表示卡号不存在,10001表示卡号,1000表示刚才要充值的金额,以分为单位;

(10)、SP应用服务程序在发送之前,同样根据密匙对该返回字符串进行加密处理,然后对加密字节流长度进行计算,加上刚才发送过来的包头标识和版本号以及保留字等,组合成信息包;注意这时,字节流的长度是返回加密字节流的长度,而且是网络字节的;

(11)、通用网关接收到(Recv)返回业务数据后,主动关闭(Close)和SP服务器的这次Socket连接,将返回的加密字节流进行解密处理之后,还原原有的信息字符串,发送给IVR;

(12)、IVR收到该返回字符串” 11$2$10001$1000$”,然后根据业务流程对之进行解析,做进一步的处理,譬如提示用户说,该帐户不存在等;

(13)、如果SP应用服务程序在5秒钟中时间内,没有返回处理结果,通用网关会自动断开该Socket连接,然后向IVR报告处理超时消息。

5、不加密的字符串长连接传输协议

这种方式可靠性高,能够保持持续的连接,但对于资源的消耗比较高,并发性不太好,调试跟踪不太方便,一般不建议采用这种方式。

具体过程详细说明如下,如图所示:

(1)、通用网关启动服务模块时向SP服务器程序启动一个连接(Connect)请求;

(2)、SP应用服务程序此时应处于监听(Listen)状态,监听到有客户端请求连接;

(3)、SP应用服务程序根据此连接请求的IP地址等信息进行身份验证,如果验证通过则接受(Accept)连接请求,双方建立一个Socket连接;

(4)、IVR流程中收集完用户的相关信息之后,发送一个字符串给通用网关;在上述的那个例子中,这个字符串是”10$057188880000$12345$10001$1000$20071115165500$”;

(5)、通用网关根据IVR流程发送的字节流,加上信息包头,组合成信息包,然后发送(Send)信息包,发送的字节数为加密后的字节流字节数+24(24信息包头的字节长度);在上述的例子中,信息包大约如ffff0200 00001100 00004e5f 00114b3f 00000000 0100 0033 10$057188880000$12345$10001$1000$20071115165500$;发送的字节数为字符串自身的长度加1,即strlen(发送字符串)+1;在上述的例子中,这里是strlen(“10$057188880000$12345$10001$1000$20071115165500$”)+1=51,即0X33;

(6)、SP应用服务程序接收(Recv)该信息包,根据包头信息截取对应的字节流,然后得到业务字符串,另外还需要把其他的包头标识、两个包头保留字,存储在本地;

(7)、SP应用服务程序根据流程开发人员与之协商好的格式对接收的字符串进行解析,然后进行响应的处理;譬如例子中,分解出操作码10为充值操作,分解主叫为057188880000,帐号为10001,充值金额为10元等,然后查询该帐号是否存在和帐号状态是否合法,如果满足条件后,对该卡进行充值等操作;

(8)、SP应用服务程序处理对应的业务后,把处理后的结果数据进行加工,组合成字符串,同样,该字符串格式是事先和流程开发人员进行协商确定的;如在例子中,充值成功后,返回”11$2$10001$1000$”的字符串,表示充值10元失败,11是充值操作响应码,2表示卡号不存在,10001表示卡号,1000表示刚才要充值的金额,以分为单位;

(9)、SP应用服务程序然后对字节流长度进行计算,加上刚才发送过来的包头标识和版本号以及保留字等,组合成信息包;注意这时,字节流的长度是是网络字节的;

(10)、通用网关接收到(Recv)返回业务数据后,将返回的字节流发送给IVR;

(11)、IVR收到该返回字符串” 11$2$10001$1000$”,然后根据业务流程对之进行解析,做进一步的处理,譬如提示用户说,该帐户不存在等;

(12)、如果SP应用服务程序在5秒钟中时间内,没有返回处理结果,通用网关会向IVR报告处理超时消息;

(13)、通用网关服务模块退出或停止的时候断开和SP应用服务器的连接。

6、根据密钥加密的长连接传输协议

这种方式可靠性高,安全性高,能够保持持续的连接,但对于资源的消耗比较高,并发性不太好,调试跟踪不太方便,一般不建议采用这种方式。

本方式采用DES加密,双方需要约定一个密钥(Key),目前约定密钥为长度额为8位的字符串,一般由SP服务器端来指定,提供给通用网关的维护人员,由维护人员在本地对通用网关进行配置。

在发送数据给对方之前,通信的双方根据本地配置的密钥对数据进行DES加密处理;在收到数据后,同样根据本地配置的密匙进行解密处理;通信连接方式上和上述第三种完全一样。

具体过程详细说明如下,如图所示:

(1)、通用网关启动服务模块时向SP服务器程序启动一个连接(Connect)请求;

(2)、SP应用服务程序此时应处于监听(Listen)状态,监听到有客户端请求连接;

(3)、SP应用服务程序根据此连接请求的IP地址等信息进行身份验证,如果验证通过则接受(Accept)连接请求,双方建立一个Socket连接;

(4)、IVR流程中收集完用户的相关信息之后,发送一个字符串给通用网关;在上述的那个例子中,这个字符串是”10$057188880000$12345$10001$1000$20071115165500$”;

(5)、通用网关收到IVR流程业务应用请求之后,根据配置的8位密钥(这里假设为” SuntekD6”)进行加密处理,得到加密后的字节流,假设为32f69fce6dca6ace576b08115c099975817e2b3b68f9eafd6ca55dfe(56字节的二进制字节流)存储在本地;

(6)、通用网关在连接建立之后,根据刚才加密的字节流,加上信息包头,组合成信息包,然后发送(Send)信息包,发送的字节数为加密后的字节流字节数+24(24信息包头的字节长度);在上述的例子中,信息包大约如ffff0200 00001100 00004e5f 00114b3f 00000000 0100 0038 2fd65329e2770074791503c2dab1d209fe0225636dd07f7277bd291209e1a498df28f7af
2f0eb4f1be2831f0fa8987b7f9;其中业务加密字节流的长度这里是56,体现在网络字节中是0x0038,如果是x86系列的PC,需要做主机到网络(ntohs)字节顺序转换;

(7)、SP应用服务程序接收(Recv)该信息包,根据包头信息截取对应的字节流,然后进行解密处理,得到加密前的业务字符串,另外还需要把其他的包头标识、两个包头保留字,存储在本地;

(8)、SP应用服务程序根据流程开发人员与之协商好的格式对接收的字符串进行解析,然后进行响应的处理;譬如例子中,分解出操作码10为充值操作,分解主叫为057188880000,帐号为10001,充值金额为10元等,然后查询该帐号是否存在和帐号状态是否合法,如果满足条件后,对该卡进行充值等操作;

(9)、SP应用服务程序处理对应的业务后,把处理后的结果数据进行加工,组合成字符串,同样,该字符串格式是事先和流程开发人员进行协商确定的;如在例子中,充值成功后,返回”11$2$10001$1000$”的字符串,表示充值10元失败,11是充值操作响应码,2表示卡号不存在,10001表示卡号,1000表示刚才要充值的金额,以分为单位;

(10)、SP应用服务程序在发送之前,同样根据密匙对该返回字符串进行加密处理,然后对加密字节流长度进行计算,加上刚才发送过来的包头标识和版本号以及保留字等,组合成信息包;注意这时,字节流的长度是返回加密字节流的长度,而且是网络字节的;

(11)、通用网关接收到(Recv)返回业务数据后,主动关闭(Close)和SP服务器的这次Socket连接,将返回的加密字节流进行解密处理之后,还原原有的信息字符串,发送给IVR;

(12)、IVR收到该返回字符串” 11$2$10001$1000$”,然后根据业务流程对之进行解析,做进一步的处理,譬如提示用户说,该帐户不存在等;

(13)、如果SP应用服务程序在5秒钟中时间内,没有返回处理结果,通用网关会向IVR报告处理超时消息。

(14)、通用网关服务模块退出或停止的时候断开和SP应用服务器的连接。

  1. 1
  2. ...
  3. 9
  4. 10
  5. 11
  6. 12
  7. 13