1.概述
最近,公司服務器需要做一個壓力測試,公司的服務器,是基于Socket的連接,然后去進行數據的傳輸。
2.然而,壓測程序的書寫卻讓我吃力。(以下是我走過的方案)
- 1 . 最開始,我是直接用傳統的Socket作為連接,然后,一個程序創建N個Socket,因為普通的Socket是一個阻塞式的Socket,所以呢,每個Socket必須對應著一條線程!這樣,從一開始的10線程并發(慢慢壓上去)到后面的1000線程并發,邏輯上,測試程序很直觀,一個線程發送了請求包,就阻塞等待回包,然后繼續,到最后的1000個,2000個,結果發現超出JVM的限制了。所以,這條路,走不通了。
- 2 . 然后,我就到處找資料,看到網上有一些專業的壓測程序:例如,JMeter,LoadRunner等等。然后我就開始研究了。LoadRunner非常專業,但是專業,就很難短時間入手了,所以我選擇了比較容易入門的JMeter。
這里介紹一下我入門推介的文章(后期我會親手寫一下遇到的坑):
JMeter學習(十六)JMeter函數學習
JMeter學習(十七)JMeter測試Java
JMeter學習(十八)JMeter測試Java(二)
這一系列文章能很好的帶你入門!
在這個方案上,我掙扎了一天!到了晚上,終于出來的壓測程序!但是,結果卻不如人意!(這里我想罵人)不過是我自己沒先弄清楚。我以為這個壓測軟件是通過別的方法,大概是線程復用啥的,結果跑起來,發現還是跟方案一一樣!跑到了2K個并發后,就報JVM達到線程數上限了。(欲哭無淚)大概經過了:懷疑自己-懷疑人生-自暴自棄-重新站起來,我繼續站了起來,不哭繼續擼!
- 3 . 繼續上網扒資料。普通的Socket因為是阻塞當前線程的,所以壓測量一上去,其弊端就出來了,所以,不能是線程阻塞的!于是我就找到了不阻塞的Socket,使用異步回調的Socket,嗯,很棒!在這里我粗略介紹一下這個異步的Socket,其位于:
java.nio.channels.AsynchronousSocketChannel
NIO包:
AsynchronousSocketChannel異步Socket,其連接,發送,接收,都是異步的,其異步回調的接口如下:(代碼來了,大家不要怕)
public interface CompletionHandler<V,A>
{
void completed(V result, A attachment);
void failed(Throwable exc, A attachment);
}
這不是一個函數式接口,而且也沒有提供者接口的閉包,嗯,有點桑心。
從函數的名稱看,completed就是完成時的回調,failed就是失敗的回調。
成功的回調,有V result,這個東西,在AsynchronousSocketChannel的讀取函數,規定了V必須是Integer,這個就是告訴你讀到了多少個字符。
而,其他沒規定,然后呢,A這個泛型我們就可以自定義啦,一般來說,是傳入AsynchronousSocketChannel的對象,到如果,你需要給Socket加上一些自定義的屬性,你可以去DIY一個SocketBean類去包裝。嗯,好像說的有點多了,就先這樣,后期這個方案我也會寫篇文章紀念一下。又過了快一天(腦子笨+網上資料有點少),我又弄出了一個異步Socket的壓測,然后,我想到一個問題,它這個回調回是在哪里回調呢?在原線程嗎?還是在新開線程?如果是新開線程中回調,就又GG了。。。結果,很悲劇...我竟然忽略這個問題,TMD在新線程中回調...如果,我壓測量又上了2000,那,2K個發包,2K個回包,且在新開線程中!!!好了,瓶頸又回到了方案一二的瓶頸....
- 4 .哎,這次真的心累了。不過我這次慢慢地從JAVA AIP文檔查起來,結果發現有個很棒的東西:
Java NIO系列教程(六) Selector
這個NIO中的Selector,引用一下別人的話:
Selector(選擇器)是Java NIO中能夠檢測一到多個NIO通道,并能夠知曉通道是否為諸如讀寫事件做好準備的組件。這樣,一個單獨的線程可以管理多個channel,從而管理多個網絡連接。
我...我...欣喜若狂,這就是我要找的Socket。
- 這種Socket位于:
java.nio.channels.SocketChannel
,看來NIO包很重要有木有!這個網上也是很少資料,坑也是一個一個的,弄得我不要不要的!(后面會出文章說明) - 通過Selector,去管理N個Socket,注意,這個Selector是跑在一條阻塞的線程上,而其就只需要一條線程!就能管理N個連接。
- 通過這個東西,進過1半天的努力,我終于弄粗了一個壓測4.0版本,然后隨便改改一個參數,就上千上萬了嘻嘻。
3 .總結
這幾天的經歷很棒,從一次一次的期望到失望,到一次一次懷疑人生,我都熬過來了,其實也沒什么了不起的大事情。加油!寫這篇文章,主要是紀念一下這幾天,和預告一下我要寫一下幾篇技術文章(其實很水),因為這方面網上很少資料!
- 希望有人期待。(我自己就很期待)