sql >> Databasteknik >  >> RDS >> Mysql

Ett bärbart sätt att tillhandahålla en IP-baserad nedkylningsperiod?

Så här löste jag det för nu, med hjälp av en fil.

Procedur

  1. Hämta klientens IP och hasha den (för att förhindra filläsning).
  2. Öppna IP-filen och skanna varje rad
  3. Jämför tiden för den aktuella posten med den aktuella tiden
  4. Om skillnaden är större än inställd timeout, gå till 5., annars 7.
  5. Om IP matchar klient, skapa uppdaterad post, annars
  6. släpp post.
  7. Om IP matchar klienten, ange ett felmeddelande, annars kopiera posten.

Exempelkod

<?php

$sIPHash    = md5($_SERVER[REMOTE_ADDR]);
$iSecDelay  = 10;
$sPath      = "bucket.cache";
$bReqAllow  = false;
$iWait      = -1;
$sContent   = "";

if ($nFileHandle = fopen($sPath, "c+")) {
    flock($nFileHandle, LOCK_EX);
    $iCurLine = 0;
    while (($sCurLine = fgets($nFileHandle, 4096)) !== FALSE) {
        $iCurLine++;
        $bIsIPRec = strpos($sCurLine, $sIPHash);
        $iLastReq = strtok($sCurLine, '|');
        // this record expired anyway:
        if ( (time() - $iLastReq) > $iSecDelay ) {
            // is it also our IP?
            if ($bIsIPRec !== FALSE) {
                $sContent .= time()."|".$sIPHash.PHP_EOL;
                $bReqAllow = true;
            }
        } else {
            if ($bIsIPRec !== FALSE) $iWait = ($iSecDelay-(time()-$iLastReq));
            $sContent .= $sCurLine.PHP_EOL;
        }
    }
}

if ($iWait == -1 && $bReqAllow == false) {
    // no record yet, create one
    $sContent .= time()."|".$sIPHash.PHP_EOL;
    echo "Request from new user successful!";
} elseif ($bReqAllow == true) {
    echo "Request from old user successful!";
} else {
    echo "Request failed! Wait " . $iWait . " seconds!";
}

ftruncate($nFileHandle, 0);
rewind($nFileHandle);
fwrite($nFileHandle, $sContent);
flock($nFileHandle, LOCK_UN);
fclose($nFileHandle);
?>

Anmärkningar

Nya användare

Om IP-hash inte matchar någon post skapas en ny post. Observera:Åtkomst kan misslyckas om du inte har rättigheter att göra det.

Minne

Om du förväntar dig mycket trafik, byt till en databaslösning som detta alla tillsammans.

Redundant kod

"Men minxomat", kan du säga, "nu går varje klient igenom hela filen!". Ja, verkligen, och det är så jag vill ha det för min lösning. På så sätt är varje klient ansvarig för städningen av hela filen. Trots det hålls prestandapåverkan låg, för om varje klient städar kommer filstorleken att hållas på ett absolut minimum. Ändra detta om det här sättet inte fungerar för dig.




  1. MySQL:Hur använder jag avgränsare i triggers?

  2. Skapar trigger i mysql för generation UUID

  3. ScaleGrid nu tillgängligt i Sydney AWS-regionen

  4. Utveckling av feltolerans i PostgreSQL:Synchronous Commit