1. 程式人生 > >Web併發頁面訪問量統計實現

Web併發頁面訪問量統計實現

頁面訪問量統計,可能在上學的時候就講過如何簡單實現,例如在servletContext中儲存一個頁頁面訪問次數,然後每訪問一次加1;或者每訪問一次就把操作記錄儲存到資料庫,這樣的處理方式,做做實驗就算了,在實際應用中這樣應用對系統性能影響特別大。

第一種方式,因為頁面訪問次數屬於一個公共變數,在對公共變數進行修改的時候,往往需要加上同步鎖;同步鎖會導致訪問速度明顯變慢;第二種方式也一樣,而且頻繁訪問資料庫也不是一種合理的方式。

前不久,我一個朋友要我幫他們寫一個簡單的頁面統計程式碼。1、需求是儲存頁面訪問IP、時間、以及其他一些可用的資訊,以後需要儲存的訪問資訊可擴充套件 2、不能影響當前的訪問速度 3、能支援一定量的併發訪問


接到朋友給的這個需求,我想到了一下幾點:1、如何篩選我們需要統計的頁面;2、需要將訪問和統計分離,不在訪問的執行緒中來儲存訪問資訊,另外起一個執行緒將訪問資訊儲存到資料庫;3、可以使用一個公共的佇列來儲存這個訪問資訊;4、可以批量的儲存一定量的訪問資訊
  

解決方案:

1、針對第一個問題,我給出了兩個方法。1、使用一個集合儲存所有的需要統計的頁面,然後再在Filter裡面判斷當前請求是否在在統計之列;2、在JSP頁面中引入一段公共程式碼,在程式碼中使用類似這種CounterUtils.addCounter(request);這種方法有一個好處,維護需要統計的頁面比較方便,而且感覺上更加高效,不需要Filter攔截。但是朋友堅決用第一種方式,也是沒有辦法。

2、每訪問一次,我們將需要儲存的資訊儲存成一個物件,然後放入到隊列當中,然後另起一個執行緒定期進行儲存。

於是我就寫了一個簡單的demo給朋友,沒過多久,就被退貨了。經過測試併發還沒到200就突然不儲存資料庫了,訪問也變得特慢,最後竟然堆記憶體溢位了。


沒有辦法只能再在本機用loadRunner進行測試,同時通過jconsole java自帶工具來檢測記憶體變化情況。測試情況與朋友說的一樣,剛開始能夠正常執行,當併發達到一定量,就開始出現儲存緩慢,最後不知道怎麼整的儲存執行緒不再執行,就這樣佇列越來越大,自然堆記憶體大到溢位了。


從上面的情況也可以想到,一個佇列有可能無法支援這麼大的併發訪問,於是就想使用多個佇列來進行儲存,使用類似分表分庫的方法,將不同請求分配到不同的佇列中去,於是就變成了下面這種方式:


部分程式碼如下:(尾部有相關原始碼獲取方式)
1、初始化生成linkedList集合列表


將請求封裝成統計所需物件

3、輪詢LinkedList佇列集合

4、ExecuteThread執行緒用於批量儲存訪問日誌

  // 批量儲存資料庫

   這個分兩種方式

1、儲存詳細的訪問記錄,例如,某某時候某個IP對某個頁面進行了訪問  

2、只儲存某天每個頁面訪問的總數

  對於第一種方式,使用批量儲存即可。對於第二種方式可以使用一個hashTable來維護所有頁面某個時間段內的對應頁面的訪問增量,具體維護方式可以如下:

  將reqestStc資訊維護進HashTable當中,其中維護過程省略;再寫一個定時器,定時將HashTable中的增量資料flush到資料庫中;

5、如何攔截需要統計的訪問請求
方法一:通過判斷uri是否在需要統計之列
方法二:在需要統計的jsp中新增JAVA程式碼例如:CounterUtils.addCounter(request);

方法三:JS非同步訪問,類似百度統計的這種方式,這種方式有個好處,就是不影響頁面載入速度。

經過修改,在loadRunner和tomcat的測試下,基本上能夠達到tomcat最大的併發以上使用者,並且佔用少量資源。

還有一種方式就是百度統計那種方式,在js端使用非同步統計程式碼,這樣做的好處是不影響頁面的載入速度,程式碼如下圖,具體實現沒有去深究:

(轉:http://blog.csdn.net/wushuchu/article/details/52036753)

公眾號回覆"page"獲取相關原始碼