并发小工具
其实就是多线程构造多个请求,请求同一个地址,在网站测试的时候还是能用上的,有的时候方法在同一时间只能被一个线程访问,用这个工具就可以测试的方法是不是真的是在同一时间只能被一个线程访问,在处理订单的时候用处就大了,如银行订单,支付宝订单,骏卡订单等,我们都知道一个订单只能被处理一次,也就是说在同一时间只能有一个线程处理这个订单,等这个线程处理完之后,才能让其他线程访问,等这个线程处理完之后,其他线程在来访问,就直接提示订单的处理结果,用这个工具测试就很方便了,因为他是多个线程同时访问的吗!
前段时间CSDN泄密的原因,大家都说CSDN的技术很烂,我当时就做了个很简单的工具,就是不停的请求CSDN的网站,响应速度还行,不过跟百度的响应速度比起来还是很有距离,同时发现CSDN统计博客的浏览数量有点坑爹,下图中的那篇博客是我写得最开心的,因为思考和分析得过程让我很爽。但在CSDN的浏览量也就1000左右,用这个小工具这么一测,访问量就变成26299,要实现这个访问量也就几分钟。页面刷新一次访问量就增加一次,当然他至少有点真实性,为了增加自己博客的访问量的朋友就不用自己刷新了,用我这个小工具吧,但这个工具对博客园不起作用,博客园用了缓存,而且缓存时间还蛮长,在缓存指定的时间内程序的后台代码是不会执行的,所有的显示信息都来自你本地缓存的内容。所以不停的访问博客园的页面也没有用。
开始的时候只是一个刷博客的工具,没什么用,但是最近做的一个东西涉及到订单处理问题,保证一个订单只能被处理一次,然而有的时候,一个订单可能同时有多个请求,当然不能一个订单处理多次啦,于是自己就改造了一下那个刷博客的小工具,让他能实现并发请求,经过这个小工具的测试,程序还Ok。并发小工具截图如下:
并发小工具的源码就很简单了,下面随便贴出部分代码,源码下载。本博客作者:陈太汉
//发送请求
private void Action()
{
while (requestCount > 0)
{
if (!IsOK)
{
return;
}
Post(2500, txtUrl.Text.Trim());
}
}
//终止所有子线程
private void AbortThread()
{
if (threadList != null && threadList.Count > 0)
{
foreach (Thread t in threadList)
{
t.Abort();
}
threadList.Clear();
threadList = null;
}
}
//启动所有线程
private void Start()
{
AbortThread();//清理线程列表
int count = int.Parse(txtThreadCount.Text.Trim());
threadList = new List<Thread>(count);
for (int i = 0; i < count; i++)
{
Thread thread = new Thread(Action);
thread.IsBackground = true;
threadList.Add(thread);
thread.Start();
}
}
//发送请求
private void Post(int timeout, string url)
{
using (Stream s = GetPostStream(timeout, url))
{
if (s == null)
{
++FailCount;
}
else
{
++SucCount;
}
--requestCount;
}
}
//获取存储指定页面数据的流
private Stream GetPostStream(int timeout, string url)
{
try
{
if (!url.StartsWith("http://", StringComparison.OrdinalIgnoreCase))
{
url = "http://" + url;
}
HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(url);//如果地址不存在或是不能访问,会报异常
myReq.Timeout = timeout;
HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
return HttpWResp.GetResponseStream();
}
catch
{
return null;
}
}
//url验证url是否存在
private bool CheckUrl(string url)
{
using (Stream myStream = GetPostStream(1200, url))
{
if (myStream == null)
{
return false;
}
using (StreamReader sr = new StreamReader(myStream, Encoding.Default))
{
if (sr.Peek() > -1)
{
return true;
}
}
return false;
}
}
看云风博客关于解决12306并发问题的启发:我现在做骏卡接口,可能出现并发问题,就是一个订单可能向我们的接口发送多个请求,而我现在做的方法是去数据库中对应的表验证,看订单是否存在,如果存在就提示一下,如果不存在按流程走,但是这个样每来一个订单我都需要去数据库查,如果我在内存中维护一个订单集合,这样就能很快解决判断订单是否存在的问题,惯性思维太严重了,什么都去数据库查,这样的性能是最差的,其实很多问题在内存中就可以搞定的,最近还有一个特别感受,不要做井底之蛙,多看牛人的东西收获真的比自己埋头写代码进步快很多,其实很多时候我写的程序性能差,效率低都是因为方法的原因,没有找到好的方法,没有灵光一闪的感觉,用了最烂的方法解决问题(这段文字是前些天写的,跟博客的主题关系不大)
作者:陈太汉
博客:http://www.cnblogs.com/hlxs/