一个监控程序,调用短信接口的实现.
最近接受了一个烫手的山芋头.是公司的给一个客户做的CRM系统中的一个订单处理模块,这个模块当时考虑并发和访问量比较大所以套用SOA的思想,把订单处理模块单独成一个服务.
部署在专门的机器上并做了负载均衡,提供接口给其他模块调用. 由于本人专注数据库方面和计费结算等架构方面.所以那个订单处理模块的设计开发我没有参加. 系统测试和试运行的时候都一切正常.
但是上线不久,就出问题了. 那个订单处理模块老是挂掉.经检查发现那个服务运行一段时间(半天或者一天总之说不清楚)就使得那个服务器的cpu占用100%.直接over, 然后重新杀掉那个模块的jboss服务,启动一下jboss,又可以坚持一天半天.
检查数据库一切正常,估计是在程序里面有逻辑出现bug,时间长了吧cpu的资源耗尽了. 更让人要跳楼的是做那个模块的几个哥们儿 跳槽了. 悲剧啊!!!!(人生就好比一个大茶几,上面摆满了杯具!!).
咋办捏,系统在运行已经有不少的用户和数据,不可能系统停止让我们检查原因,然后再上线,估计这样说,Boss要吧我杀了...,看来在这个bug解决之前. 唯一的办法就是,监控这个程序,如果挂掉,马上重启服务.但不可能几页子一天到黑守到起
想到了一个可能的办法,就是写一个监控程序,如果发现那个服务挂掉,马上重启服务.但是试验只有,发现也走不通,服务挂的时候,是cpu100%没法相应了,这时候那个监控程序一并搞死在那儿...
然后又想到吧那个监控程序部署到另一个服务器上,但是在另一个服务器上没法去重启订单处理模块的服务.最后想如果发现服务挂了能通过短信通知维护人员也可以.维护人员可以通过手机上网远程桌面进入那服务器,去重启jboss.这样就不用大家都守到哪儿了.
于是马上到网上搜如何通过程序给手机发短信的东东.
首先搜到短信modem. 看到一哥们儿的blog里面写的文章http://hi.baidu.com/surelybox/blog/item/0404371bf8066afdae513360.html,说要去买一个短信modem的设备,然后再根据它提供的sdk包进行开发.
我晕死,这么个事情还要买个modem,而且那哥们儿说的用起来中间还有很多问题.不好解决,具体的情况 如果大家有兴趣可以看看他的blog.
我在想.那些电信运营商其实提供一个webserive或者http的接口出来,然后我调用一下这个接口不是就可以吧短信发出去了么.咋个搞的这么麻烦捏.真是奇怪,于是放弃该死的短信modem的想法,又继续在网上搜短线接口.
搜出来,出现很多 xxx科技提供短信接口.看了几个差不多都是短信群发的东东,提供一个群发的系统,然后让用户可以去是设置号码和短信内容,再给用户发送.但是我需要的是短信的api接口,这些又不太适合我.
继续搜索,看有没有.
正在折腾中,同事喊吃饭了,想到先把饭吃完多,再说.毕竟身体是革命的本钱! 吃饭回来,有点犯困,顺便到cnbeta上去逛逛. 看到了一篇文章:中国电信将推出“能力开放平台”http://www.cnbeta.com/articles/99098.htm
奇怪能力开放是个什玩意儿,于是继续看,开始写了什么"国家重大专项课题,该项目由王晓初挂帅".哇,投入还大哟. 再往下看,有如下一句话:
"通俗的讲,就是电信将一些核心的 资源如短信、IVR、语音通话、位置服务等功能通过该平台向普通的开发者开放,开发者可以根据自己的产品需求快捷申请和调用这些功能."
哟呵,这个短信不是我真需要的么,而且是想普通开发者开放,我的监控程序正好需要这个东东啊!!先进去看看,http://open.ctfactory.com.然后里面发现了一个短信的链接.
http://open.ctfactory.com/Portal/Supermarket/FuncDetail.aspx?funcID=10000033然后再点进去.前面的注册账号这些都不看了,里面关键的两个步骤:
第四步: 调用能力开放平台认证鉴权接口,获得认证码;
第五步: 获得认证码以后,调用短信发送接口。
基本明白了,其实就是首先用账号去申请一个验证码,然后根据验证码调用短信接口. 哇咔咔,方便.
马上注册了一个账号,然后注册成功后提示 "一元订购能力",进入界面看到其中短信是一元钱订购100次. my god 一分钱一次,电信这回真是大方了一回了.然后通过银联支付一块钱,订购了100次的短信.
哈哈,短信的问题搞定了,接下来进行监控程序的编写,其实就是用doNET写了一个客户端程序(这个部署在另外一个windows的机器上).代码很简单,启一个线程,定时访问接口,如果访问不到了,就调用发短信的接口
一下就是全部的代码,通过注释就可以看明白了. 为了赶时间,代码写的很不规范,望大家不要见笑哟
public partial class Form1 : Form
{
//定义一个线程对象的变量,全局的
Thread t;
int interval=10;//间隔10秒
delegate void delegate_getRet(string error);
bool flag = true;
//这些事doNET生成,不管他.
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
//在这个按钮按下的时候,就启动线程,每10秒执行方法getRet
private void start_Click(object sender, EventArgs e)
{
this.label1.Text = "启动时间:" + DateTime.Now.Hour + "时" + DateTime.Now.Minute + "分";
start.Enabled = false;
flag = true;
//执行方法getRet
t = new Thread(getRet);
t.Start();
}
//关闭按钮,就是停止线程的
private void stop_Click(object sender, EventArgs e)
{
try
{
flag = false;
t.Join();
t.Abort();
}
catch
{
}
start.Enabled = true;
}
void getRet()
{
while (true)
{
if (!flag) return;
try
{
//模拟一个http请求
WebRequest myRequest = null;
WebResponse myResponse = null;
//Stream resStream = null;
//StreamReader sr = null;
myRequest = WebRequest.Create("这儿是订单模块的接口,这儿就不便公开了!呵呵.如果要使用这个代码,请改成你的URL地址");
myResponse = myRequest.GetResponse();
}
catch (Exception ex)
{
//发一个短信,发短信的功能,封装在这个方法里面,在方法里面决定接受者的电话号码和短信内容.
this.sendMsg("杯具啊!!又挂了!!赶快重启...");
}
finally
{
Thread.Sleep(interval * 1000);
}
}
}
以上是程序的主体结构,下面是发送短信的方法的代码. 可能中途有写问题,但是逻辑都是一样的,代码在我的本本上,现在我写这个文章的时候又是在家里的台式机上写的
如果有什么问题,可以看open.ctfactory.com 里面有详细的开发文档和客服服务.
private sendMsg(string msgContent)
{
//1.调用能力管控认证鉴权接口,获取Token,这个是一个webservice接口,
// Authenticator = Base64(SHA1 (TimeStamp + “$” + APID+ “$” + APUserAccount + “$” + FunID + “$” + APKEY))
// 以下介绍在http://open.ctfactory.com/Portal/Supermarket/FuncDetail.aspx?funcID=10000033#KSSS 都能看到
//下面的设置分别是授权接口的URL和能力调用接口的URL,以及用户ID和能力ID以及Key.
string AuthInterfaceURL = ConfigurationManager.AppSettings["AuthInterfaceURL"];
string FuncInterfaceURL = ConfigurationManager.AppSettings["FuncInterfaceURL"];
string APID = ConfigurationManager.AppSettings["APID"];
string APKey = ConfigurationManager.AppSettings["APKey"];
string FuncID = ConfigurationManager.AppSettings["FuncID"];
string APUserID = ConfigurationManager.AppSettings["APUserID"];
// AMCPForAP这个东东是用doNET将授权接口的webservice生成的本地代理
string authResult = AMCPForAP.Auth(AuthInterfaceURL, APID, FuncID, APUserID, APKey);//AMCPForAP这儿是我通过doNET自动生成的webservice代理
string[] authResults = authResult.Split('$');
int result = Int32.Parse(authResults[0]);
2.获取验证码发送消息
if (result == 0)
{
//生成请求字符串
string sendMsgRequest = "http://118.123.249.4/ims/ghsendim.php?SendMsgRequest=" + token + "$" + 这儿是要发送短信的电话号码 + "$" + PSOCryptography.ConvertStringToBase64String(msgContent).Replace("+", "%2B").Replace("&", "%26") + "$" + "";
//发送短信.这儿的短信发送接口是一个REST接口,需要模拟一个http请求来发送
WebRequest myRequest = WebRequest.Create(sendMsgRequest);
WebResponse myResponse = myRequest.GetResponse();
resStream = myResponse.GetResponseStream();
string content = new StreamReader(resStream, System.Text.Encoding.UTF8).ReadToEnd();
if (content.IndexOf("200")>0)
{
//记录日志,发送成功
............
}
else
{
//记录日志,发送失败.
............
}
}
}