1. 程式人生 > >OSS庫對頻率訪問的控制

OSS庫對頻率訪問的控制

         通過學習,讓我們留下點什麼,知其然,知其所以然。

         綜述,採用共享記憶體的方法,記錄每個IP、QQ號的超時前的訪問時間、次數,然後定時更新記錄,從而達到控制。原始碼在local_access_limit.h 與 local_access_limint.cpp的類LocalAccessLimit中。

記憶體資料圖:

預設桶的數量:

DEFAULT_BUCKET_NUM = 999983,    //至於這個數字具體怎麼選定,我不清楚,請高人指點。我感覺的一個原則應該是比較大的素數,這樣,在下面求模的時候可以減少碰撞。

DEFAULT_NODE_NUM = 1       

 /*!\brief node結構 */

 typedef struct _NODE

 {

       int iKey;          節點主鍵

       int iTimeStamp;    訪問時間戳

       int iAccess;        訪問次數

} Node;

單個桶的大小、

_iBucketSize = sizeof(Node) * _iNodeNum;

Hash表的大小

_iHashTableSize = _iBucketSize *_iBucketNum; 

具體流程:

1、建立檔案(_sFilePath)目錄,

   開啟/建立檔案,

   比較檔案大小是否小於_iHashTableSize+1,

       如果小於,通過寫入一位元組“”改變檔案檔案大小到iHashTableSize;

2、建立共享記憶體對映檔案mmap(NULL, _iHashTableSize, PROT_READ | PROT_WRITE, MAP_SHARED, iFd,0)

   通過這個共享記憶體檔案中來記錄每個IP結點、QQ號結點在一定時間內的訪問次數,從而進行頻率控制。

3、Hash表維護流程:

    1、將iKey(IP、qq轉化為整數值後的值)雜湊到不同的桶中間。

     int iBucketIndex = (unsignedint)iKey % _iBucketNum;

     HASH到某一個桶中間去。

    2、鎖檔案。

   FileMutex cFileMutex(_sFilePath.c_str(), iOffset);

   FileMutex::CommLock cFileLock(cFileMutex);   

cFileLock.Acquire();

關於檔案鎖,我們另附檔案分析。

    3、最後是重點,維護桶檔案來記錄訪問次數。

    預設_iNodeNum = 1;並且採用先進先出的方法將最早的記錄換出去。

    遍歷桶內的每個結點。              

       a 判斷當前結點是否為當前訪問IP\qq,

           不相等:判斷當前結點時間是否早於最早的結點時間,如果是,則記錄該結點。

           相等:

                判斷當前時間是否在規定的訪問時間間隔內,

                    不是:記錄該結點,並且退出,後面更新時間記錄。

                    是:

                        判斷是否超出規定次數。

                            是:返回false,超出限制。

                            否:更新訪問次數。

         當找到該結點並且超時、或者沒有找到需要的訪問的結點,那麼採用先進先去的原則,將同一個桶內最早的結點記錄更新為當前結點記錄,即更新結點訪問時間、次數。