并發(fā)小工具
其實(shí)就是多線程構(gòu)造多個(gè)請(qǐng)求,請(qǐng)求同一個(gè)地址,在網(wǎng)站測(cè)試的時(shí)候還是能用上的,有的時(shí)候方法在同一時(shí)間只能被一個(gè)線程訪問(wèn),用這個(gè)工具就可以測(cè)試的方法是不是真的是在同一時(shí)間只能被一個(gè)線程訪問(wèn),在處理訂單的時(shí)候用處就大了,如銀行訂單,支付寶訂單,駿卡訂單等,我們都知道一個(gè)訂單只能被處理一次,也就是說(shuō)在同一時(shí)間只能有一個(gè)線程處理這個(gè)訂單,等這個(gè)線程處理完之后,才能讓其他線程訪問(wèn),等這個(gè)線程處理完之后,其他線程在來(lái)訪問(wèn),就直接提示訂單的處理結(jié)果,用這個(gè)工具測(cè)試就很方便了,因?yàn)樗嵌鄠€(gè)線程同時(shí)訪問(wèn)的嗎!
前段時(shí)間CSDN泄密的原因,大家都說(shuō)CSDN的技術(shù)很爛,我當(dāng)時(shí)就做了個(gè)很簡(jiǎn)單的工具,就是不停的請(qǐng)求CSDN的網(wǎng)站,響應(yīng)速度還行,不過(guò)跟百度的響應(yīng)速度比起來(lái)還是很有距離,同時(shí)發(fā)現(xiàn)CSDN統(tǒng)計(jì)博客的瀏覽數(shù)量有點(diǎn)坑爹,下圖中的那篇博客是我寫得最開(kāi)心的,因?yàn)樗伎己头治龅眠^(guò)程讓我很爽。但在CSDN的瀏覽量也就1000左右,用這個(gè)小工具這么一測(cè),訪問(wèn)量就變成26299,要實(shí)現(xiàn)這個(gè)訪問(wèn)量也就幾分鐘。頁(yè)面刷新一次訪問(wèn)量就增加一次,當(dāng)然他至少有點(diǎn)真實(shí)性,為了增加自己博客的訪問(wèn)量的朋友就不用自己刷新了,用我這個(gè)小工具吧,但這個(gè)工具對(duì)博客園不起作用,博客園用了緩存,而且緩存時(shí)間還蠻長(zhǎng),在緩存指定的時(shí)間內(nèi)程序的后臺(tái)代碼是不會(huì)執(zhí)行的,所有的顯示信息都來(lái)自你本地緩存的內(nèi)容。所以不停的訪問(wèn)博客園的頁(yè)面也沒(méi)有用。

開(kāi)始的時(shí)候只是一個(gè)刷博客的工具,沒(méi)什么用,但是最近做的一個(gè)東西涉及到訂單處理問(wèn)題,保證一個(gè)訂單只能被處理一次,然而有的時(shí)候,一個(gè)訂單可能同時(shí)有多個(gè)請(qǐng)求,當(dāng)然不能一個(gè)訂單處理多次啦,于是自己就改造了一下那個(gè)刷博客的小工具,讓他能實(shí)現(xiàn)并發(fā)請(qǐng)求,經(jīng)過(guò)這個(gè)小工具的測(cè)試,程序還Ok。并發(fā)小工具截圖如下:

并發(fā)小工具的源碼就很簡(jiǎn)單了,下面隨便貼出部分代碼,源碼下載。本博客作者:陳太漢
//發(fā)送請(qǐng)求
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;
}
}
//啟動(dòng)所有線程
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();
}
}
//發(fā)送請(qǐng)求
private void Post(int timeout, string url)
{
using (Stream s = GetPostStream(timeout, url))
{
if (s == null)
{
++FailCount;
}
else
{
++SucCount;
}
--requestCount;
}
}
//獲取存儲(chǔ)指定頁(yè)面數(shù)據(jù)的流
private Stream GetPostStream(int timeout, string url)
{
try
{
if (!url.StartsWith("http://", StringComparison.OrdinalIgnoreCase))
{
url = "http://" + url;
}
HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(url);//如果地址不存在或是不能訪問(wèn),會(huì)報(bào)異常
myReq.Timeout = timeout;
HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
return HttpWResp.GetResponseStream();
}
catch
{
return null;
}
}
//url驗(yàn)證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;
}
}
看云風(fēng)博客關(guān)于解決12306并發(fā)問(wèn)題的啟發(fā):我現(xiàn)在做駿卡接口,可能出現(xiàn)并發(fā)問(wèn)題,就是一個(gè)訂單可能向我們的接口發(fā)送多個(gè)請(qǐng)求,而我現(xiàn)在做的方法是去數(shù)據(jù)庫(kù)中對(duì)應(yīng)的表驗(yàn)證,看訂單是否存在,如果存在就提示一下,如果不存在按流程走,但是這個(gè)樣每來(lái)一個(gè)訂單我都需要去數(shù)據(jù)庫(kù)查,如果我在內(nèi)存中維護(hù)一個(gè)訂單集合,這樣就能很快解決判斷訂單是否存在的問(wèn)題,慣性思維太嚴(yán)重了,什么都去數(shù)據(jù)庫(kù)查,這樣的性能是最差的,其實(shí)很多問(wèn)題在內(nèi)存中就可以搞定的,最近還有一個(gè)特別感受,不要做井底之蛙,多看牛人的東西收獲真的比自己埋頭寫代碼進(jìn)步快很多,其實(shí)很多時(shí)候我寫的程序性能差,效率低都是因?yàn)榉椒ǖ脑颍瑳](méi)有找到好的方法,沒(méi)有靈光一閃的感覺(jué),用了最爛的方法解決問(wèn)題(這段文字是前些天寫的,跟博客的主題關(guān)系不大)
作者:陳太漢
浙公網(wǎng)安備 33010602011771號(hào)