Ubuntu 20.04에서 Redis와 PHP로 웹사이트 히트 카운터 설정하는 방법

저자는 아파치 소프트웨어 재단을(를) 기부 쓰기 프로그램의 일환으로 선정했습니다.

소개

A hit counter is an application that records and indicates the number of visits your web page has received. The counter starts from 1 and is incremented once every time a web page is visited.

방문을 추적하기 위해 히트 카운터 응용 프로그램은 데이터베이스 형태를 필요로 합니다. MySQL과 같은 디스크 기반 데이터베이스 관리 시스템은 작동할 수 있지만, 인메모리 데이터베이스는 속도, 성능, 확장 가능성, 단순성 및 사용 편의성 측면에서 더 나은 선택입니다. 이것이 Redis 서버가 등장하는 곳입니다. Redis는 입력/출력 작업을 수행할 때마다 디스크에 접근하는 대신 컴퓨터의 RAM에 데이터를 저장합니다. 이는 처리량을 크게 증가시킵니다.

사이트 방문을 추적하려면 Redis 해시 맵이 필요합니다. 이는 키-값 쌍을 구현하는 데이터 구조입니다. 해시 맵은 키를 값에 매핑하는 해시 테이블을 제공합니다. 사용자가 웹 페이지를 방문할 때마다 사용자의 공용 IP 주소 또는 사용자 이름(인증된 사용자의 경우)을 기반으로 키를 생성한 다음 그들의 총 방문 횟수를 1로 초기화합니다. 그런 다음 사용자가 웹 페이지를 다시 방문할 때마다 Redis 해시 맵에서 그들의 IP 주소/사용자 이름을 기반으로 총 방문 횟수를 확인하고 값을 증가시킵니다.

이 가이드에서는 Ubuntu 20.04 서버에 Redis와 PHP를 사용하여 웹 사이트 히트 카운터를 설정합니다. 이 가이드의 PHP 스크립트는 방문자의 공용 IP 주소를 사용하여 방문을 추적합니다.

전제 조건

이 안내서를 따르려면 다음 사항이 있는지 확인하십시오:

단계 1 — PHP Redis 확장 설치하기

이 단계에서는 PHP가 Redis 서버와 통신할 수 있게 해주는 Redis 확장을 설치합니다. 또한 웹 방문을 추적하기 위해 Redis 해시 맵을 구현하는 테스트 웹 페이지를 만듭니다.

Redis 확장을 설치하기 전에 우분투 패키지 정보 색인을 새로 고칩니다:

  1. sudo apt update

다음 명령을 실행하여 php-redis를 설치하십시오. 이 확장은 Redis 서버 키-값 저장소와 통신하는 API를 제공합니다:

  1. sudo apt install -y php-redis

새로운 확장을 로드하려면 Apache를 다시 시작하십시오:

  1. sudo systemctl restart apache2

이제 Redis 서버와 통신하는 PHP 확장을 설치했습니다. 다음으로, Apache 웹 서버의 루트 디렉토리 아래에 test.php 웹 페이지를 만들겠습니다. 이는 방문자가 브라우저로 웹 사이트를 방문할 때 요청하는 샘플 파일입니다. test.php 페이지 파일은 Redis 서버를 사용하여 페이지 방문을 추적하기 위해 나중에 만들 hit_counter.php 스크립트를 로드합니다:

실제 시나리오에서는 웹 사이트가 수십 개 또는 수백 개의 웹 페이지를 가질 수 있습니다. 이 가이드에서는 데모 목적으로 단일 웹 페이지를 설정합니다:

터미널 창에서 다음 명령을 사용하여 웹 서버의 루트 디렉토리 /var/www/html/에 새 test.php 파일을 만듭니다:

  1. sudo nano /var/www/html/test.php

그런 다음 test.php 파일에 다음 정보를 입력하십시오:

/var/www/html/test.php
<?php
  require_once 'hit_counter.php';
?>

<!DOCTYPE html>
<html>

  <head>
    <title>Sample Test Page</title>
  </head>

  <body>
    <h1>Sample test page</h1>
    <p>This is a sample test page.</p>
  </body>

</html>

편집이 완료되면 파일을 저장하고 닫으십시오. 이 단계에서는 방문 시 hit_counter.php 파일을 로드하는 간단한 HTML 웹 페이지를 만들었습니다. 다음으로, 테스트 페이지 방문을 추적하기 위해 hit_counter.php 파일을 작성하겠습니다:

단계 2 — Redis 히트 카운터 스크립트 생성

제작 환경에서 작업할 때, 재사용 가능한 PHP 파일을 분리하는 것이 매우 전통적입니다. 이를 통해 코드를 복사하여 붙여넣는 대신에 이러한 파일의 로직을 프로젝트의 다른 부분에 포함시켜 구현할 수 있습니다. 이렇게 하면 로직을 변경해야 할 경우 하나의 파일만 편집하면 되므로 유지보수가 더 쉬워집니다. 이렇게 하면 많은 시간을 절약할 수 있습니다.

이 가이드에서도 동일한 전략을 적용할 것입니다. 방문자 추적이 필요한 모든 웹 페이지에 포함할 수 있는 단일 hit_counter.php 파일을 만들 것입니다.

이 파일에서는 PHP에서 Redis 서버에 연결하기 위해 php-redis 라이브러리를 사용할 것입니다. 그런 다음, 웹 사이트 방문자의 방문 횟수를 저장하기 위한 Redis 해시 맵을 생성할 것입니다. Redis 키로 방문자의 고유한 IP 주소를 사용하여 Redis 서버에서 각 방문자의 방문 횟수를 구별할 것입니다.

터미널 창에서 편집을 위해 새로운 hit_counter.php 파일을 엽니다:

  1. sudo nano /var/www/html/hit_counter.php

이제 hit_counter.php 파일을 생성했으므로 새 PHP 태그 <?php를 엽니다. 그런 다음, try { 블록 내에 다음 코드를 입력하여 로컬 Redis 서버의 포트 6379에 연결합니다. Redis 서버의 인증 비밀번호로 EXAMPLE_PASSWORD를 대체하세요:

/var/www/html/hit_counter.php

<?php

    try {

        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
        $redis->auth('EXAMPLE_PASSWORD');

다음으로 Redis 해시 맵($siteVisitsMap)에 선택한 이름을 지정합니다. 이 가이드에서는 데모 목적으로 siteStats를 사용합니다:

/var/www/html/hit_counter.php

        $siteVisitsMap = 'siteStats';

Redis 해시 맵을 정의 한 후, 빈 Redis 키 ($visitorHashKey)를 초기화합니다. 그런 다음 방문자의 IP 주소로 채웁니다. 웹 페이지를 요청하는 각 방문자를 고유하게 식별하기 위해 $visitorHashKey 변수의 값을 사용할 것입니다:

/var/www/html/hit_counter.php


        $visitorHashKey = '';           

        if (!empty($_SERVER['HTTP_CLIENT_IP'])) {

            $visitorHashKey = $_SERVER['HTTP_CLIENT_IP'];

        } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {

            $visitorHashKey = $_SERVER['HTTP_X_FORWARDED_FOR'];

        } else {

            $visitorHashKey = $_SERVER['REMOTE_ADDR'];
        }

이 코드에서는 PHP if 문을 사용하여 $_SERVER['HTTP_CLIENT_IP'], $_SERVER['HTTP_X_FORWARDED_FOR'] 또는 $_SERVER['REMOTE_ADDR'] 변수가 채워져 있는지 확인하여 방문자의 IP 주소를 결정합니다.

이후, 각 IP 주소의 총 방문 수를 저장할 $totalVisits 변수를 초기화하고 값으로 0을 할당합니다. 그런 다음, PHP if (...) {...} else {...}$redis->hExists($siteVisitsMap, $visitorHashKey) 문을 사용하여 IP 주소가 Redis 서버에 어떤 항목이 있는지 확인합니다.

$redis->hExists($siteVisitsMap, $visitorHashKey) 문을 사용하여 $siteVisitsMap이라는 맵에서 $visitorHashKey가 있는지 확인합니다.

Redis 서버에 이름이 지정된 IP 주소와 키가 있는 경우, 다음 문장을 사용하여 검색합니다. $visitorData = $redis->hMget($siteVisitsMap, array($visitorHashKey)); 그리고 $totalVisits = $visitorData[$visitorHashKey] + 1; 문을 사용하여 $totalVisits 변수를 증가시킵니다. IP 주소와 관련된 히트 카운트 데이터를 가져 오기 위해 $redis->hMget 문을 사용합니다. hMget 함수는 맵의 이름($siteVisitsMap)과 Redis 서버에서 검색하려는 키의 배열을 허용합니다. 이 경우 하나의 키만 있지만, 문장 array($visitorHashKey)을 사용하여 배열로 변환해야 합니다.

스크립트가 IP 주소를 처음 만나는 경우, $totalVisits 변수를 1로 설정합니다. 마지막으로, 이전의 if (...) {...} else {...} 문의 결과에 따라 $visitorHashKey의 값을 설정하기 위해 $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits);를 사용합니다. $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits) 문은 Redis 서버에 $visitorHashKey라는 키와 $totalVisits의 값이 있는 $siteVisitsMap 해시 맵을 만듭니다.

그런 다음 방문자를 환영하고 } catch (...) {...} 블록을 닫습니다:

/var/www/html/hit_counter.php

        $totalVisits = 0;

        if ($redis->hExists($siteVisitsMap, $visitorHashKey)) {

            $visitorData = $redis->hMget($siteVisitsMap, array($visitorHashKey));
            $totalVisits = $visitorData[$visitorHashKey] + 1;

        } else {

            $totalVisits = 1;

        }

        $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits);

        echo "Welcome, you've visited this page " .  $totalVisits . " times\n";

    } catch (Exception $e) {
        echo $e->getMessage();
    }

작업을 완료하면 /var/www/html/hit_counter.php 파일은 다음 코드와 유사해야 합니다:

/var/www/html/hit_counter.php

<?php

    try {

        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
        $redis->auth('EXAMPLE_PASSWORD');

        $siteVisitsMap  = 'siteStats';
        $visitorHashKey = '';           

        if (!empty($_SERVER['HTTP_CLIENT_IP'])) {

           $visitorHashKey = $_SERVER['HTTP_CLIENT_IP'];

        } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {

           $visitorHashKey = $_SERVER['HTTP_X_FORWARDED_FOR'];

        } else {

           $visitorHashKey = $_SERVER['REMOTE_ADDR'];
        }
      
        $totalVisits = 0;

        if ($redis->hExists($siteVisitsMap, $visitorHashKey)) {

            $visitorData = $redis->hMget($siteVisitsMap,  array($visitorHashKey));
            $totalVisits = $visitorData[$visitorHashKey] + 1;

        } else {

            $totalVisits = 1;

        }

        $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits);

        echo "Welcome, you've visited this page " .  $totalVisits . " times\n";

    } catch (Exception $e) {
        echo $e->getMessage();
    }

파일 편집을 마치면 저장하고 닫으십시오. 이제 hit_counter.php 스크립트를 작성했습니다. 다음으로 Redis 해시 맵에서 수집된 데이터를 기반으로 보고서를 생성하는 다른 PHP 스크립트를 만들 것입니다.

단계 3 — 사이트 통계 보고서 스크립트 생성

Redis 해시 맵에 데이터를 수집한 후에는 보고서에서 정보를 검색하고 표현할 수 없으면 의미가 없을 수 있습니다. 이 단계에서는 테스트 웹 페이지에서 서로 다른 사이트 방문자와 그들이 한 총 방문 수를 보여주는 로그 보고서를 만듭니다.

로그 보고서 스크립트를 만들려면 터미널 창에서 nano를 실행하고 새로운 /var/www/html/log_report.php 파일을 만듭니다:

  1. sudo nano /var/www/html/log_report.php

그런 다음 아래의 정보를 파일에 입력하십시오. Redis 서버의 올바른 비밀번호로 EXAMPLE_PASSWORD를 교체하십시오:

/var/www/html/log.php

<!DOCTYPE html>
<html>

  <head>
    <title>Site Visits Report</title>
  </head>

  <body>

      <h1>Site Visits Report</h1>

      <table border = '1'>
        <tr>
          <th>No.</th>
          <th>Visitor</th>
          <th>Total Visits</th>
        </tr>

        <?php

            try {

                $redis = new Redis();
                $redis->connect('127.0.0.1', 6379);
                $redis->auth('EXAMPLE_PASSWORD');

                $siteVisitsMap = 'siteStats';                          

                $siteStats = $redis->HGETALL($siteVisitsMap);

                $i = 1; 

                foreach ($siteStats as $visitor => $totalVisits) {

                    echo "<tr>";
                      echo "<td align = 'left'>"   . $i . "."     . "</td>";
                      echo "<td align = 'left'>"   . $visitor     . "</td>";
                      echo "<td align = 'right'>"  . $totalVisits . "</td>";
                    echo "</tr>";
                    
                    $i++;
                }

            } catch (Exception $e) {
                echo $e->getMessage();
            }

        ?>

      </table>
  </body>

</html>

편집이 끝나면 파일을 저장하고 닫습니다. 위의 스크립트에서는 Redis 서버에 연결하고 웹 페이지 방문 해시 맵을 검색하기 위해 $redis->HGETALL($siteVisitsMap); 문을 사용합니다. 그런 다음 PHP foreach ($siteStats as $visitor => $totalVisits) { 문을 사용하여 방문자의 IP 주소와 사이트 방문 횟수를 루프하고 표시합니다. Redis HGETALL 명령을 사용하여 siteVisitsMap 맵에서 모든 필드 (IP 주소) 및 값 (각 IP 주소의 총 방문 횟수)을 검색합니다.

이제 테스트 페이지, 히트 카운터 스크립트 및 사이트 통계를 확인할 수 있는 보고서 페이지가 있습니다. 다음으로 히트 카운터의 기능을 테스트하고 모든 것이 작동하는지 확인하겠습니다.

단계 4 — Redis 히트 카운터 테스트

이 단계에서는 히트 카운터의 전체 논리를 테스트합니다. 웹 브라우저에서 다음 URL로 이동하십시오. your-server-IP를 서버의 공용 IP 주소 또는 도메인 이름으로 대체하십시오.

http://your-server-IP/test.php

충분한 통계를 생성하기 위해 다양한 장치를 사용하여 페이지를 여러 번 새로 고칩니다. 각 방문 후 다음 출력을 받아야 합니다.

다음 URL을 방문하여 HTML 테이블에 사이트 방문 보고서가 표시되는지 확인하십시오

http://your-server-IP/log_report.php

이제 다음과 유사한 보고서가 표시되어야 합니다.

당신의 히트 카운터가 예상대로 작동합니다.

결론

이 안내서에서는 우분투 20.04 서버에서 Redis와 PHP를 사용하여 웹사이트 히트 카운터를 설정했습니다.

이 안내서의 샘플 소스 코드에서 볼 수 있듯이, Redis는 해시 맵을 만들고 업데이트하는 더 깔끔한 방법을 제공합니다.

이 안내서의 시작 부분에서 언급한 대로, 관계형 데이터베이스 관리 시스템을 사용하는 것은 여전히 가능하지만 기본 테이블에 데이터를 삽입하고 업데이트하기 위해 많은 양의 코드를 작성해야 합니다. 또한 디스크 기반 데이터베이스는 사이트가 성장함에 따라 확장성 문제를 겪을 수 있습니다.

Redis 인메모리 데이터베이스 사용에 대한 자세한 정보는 아래 안내서를 참고하세요:

Source:
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-website-hit-counter-with-redis-and-php-on-ubuntu-20-04