Как настроить счетчик посещений веб-сайта с помощью Redis и PHP на Ubuntu 20.04

Автор выбрал Фонд программного обеспечения Apache для получения пожертвования в рамках программы Write for DOnations.

Введение

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 хранит данные в оперативной памяти вашего компьютера вместо того, чтобы каждый раз обращаться к диску при выполнении операции ввода/вывода. Это значительно увеличивает пропускную способность.

Для отслеживания посещений вашего сайта вам потребуется хэш-карта Redis. Это структура данных, реализующая пару ключ-значение. Хэш-карта предоставляет хэш-таблицу, которая сопоставляет ключи и значения. Когда пользователь посещает вашу веб-страницу, вы создаете ключ на основе его общедоступного IP-адреса или имени пользователя (для аутентифицированных пользователей), а затем инициализируете его общее количество посещений значением 1. Затем, каждый раз, когда пользователь снова посещает вашу веб-страницу, вы проверяете его общее количество посещений из хэш-карты Redis на основе его IP-адреса/имени пользователя и увеличиваете значение.

В этом руководстве вы настроите счетчик посещений веб-сайта с использованием Redis и PHP на вашем сервере Ubuntu 20.04. PHP-скрипты в этом руководстве используют общедоступные IP-адреса посетителей для отслеживания их посещений.

Требования

Для выполнения этого руководства убедитесь, что у вас есть следующее:

Шаг 1 — Установка расширения PHP Redis

На этом этапе вы установите расширение Redis, позволяющее PHP общаться с сервером Redis. Вы также создадите тестовую веб-страницу, которая использует хеш-карту Redis для отслеживания посещений веб-сайта.

Перед установкой расширения Redis обновите индекс информации о пакетах Ubuntu:

  1. sudo apt update

Затем выполните следующую команду для установки php-redis. Расширение предоставляет API для взаимодействия с хранилищем ключ-значение сервера Redis:

  1. sudo apt install -y php-redis

Перезапустите Apache, чтобы загрузить новое расширение:

  1. sudo systemctl restart apache2

Теперь вы установили расширение PHP, которое общается с вашим сервером Redis. Далее вы создадите веб-страницу test.php в корневом каталоге веб-сервера Apache. Это всего лишь образец файла, который посетители запрашивают при посещении вашего веб-сайта с помощью браузера. Под капотом страница test.php загружает скрипт hit_counter.php, который вы создадите позже для отслеживания посещений страниц с использованием сервера Redis.

В реальной ситуации ваш веб-сайт может иметь десятки или даже сотни веб-страниц. В этом руководстве вы настроите одну веб-страницу для демонстрационных целей.

В вашем терминальном окне используйте nano, чтобы создать новый файл test.php в корневом каталоге вашего веб-сервера /var/www/html/:

  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>

Сохраните и закройте файл после завершения редактирования. На этом этапе вы создали простую веб-страницу HTML, которая загружает файл hit_counter.php при посещении. Затем вы напишете файл hit_counter.php, чтобы отслеживать посещения тестовой страницы.

Шаг 2 — Создание сценария подсчета хитов Redis

При работе в производственной среде очень удобно разделять переиспользуемые PHP-файлы. Это позволяет вам реализовывать логику в этих файлах в различных частях проекта, просто подключая их пути, вместо того чтобы копировать и вставлять код. Это упрощает обслуживание, поскольку вам нужно редактировать только один файл в случае необходимости изменения логики. Это экономит вам много времени.

Вы будете применять ту же стратегию в данном руководстве. Вы создадите единственный файл hit_counter.php, который можно включить на любой веб-странице, требующей отслеживания посетителей.

В этом файле вы будете использовать библиотеку php-redis для подключения к серверу Redis из PHP. Затем вы создадите хэш-карту Redis для хранения количества посещений, сделанных посетителем на вашем веб-сайте. Вы будете использовать уникальные IP-адреса посетителей в качестве ключей Redis для различия количества посещений каждого посетителя на сервере Redis.

В вашем терминальном окне откройте новый файл hit_counter.php для редактирования с помощью nano:

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

Теперь, когда файл hit_counter.php создан, откройте новый тег PHP <?php. Затем внутри блока try { введите следующий код для подключения к вашему локальному серверу Redis на порту 6379. Замените EXAMPLE_PASSWORD на пароль аутентификации для сервера Redis:

/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 для определения IP-адреса посетителя, проверяя, заполнены ли переменные $_SERVER['HTTP_CLIENT_IP'], $_SERVER['HTTP_X_FORWARDED_FOR'] или $_SERVER['REMOTE_ADDR'].

Затем инициализируйте переменную $totalVisits для хранения общего количества посещений для каждого IP-адреса и присвойте ей значение 0. Затем используйте операторы PHP if (...) {...} else {...} и $redis->hExists($siteVisitsMap, $visitorHashKey) для проверки наличия записей об IP-адресе на сервере Redis.

Вы будете использовать оператор if ($redis->hExists($siteVisitsMap, $visitorHashKey)) {...} для проверки существования $visitorHashKey в карте с именем $siteVisitsMap.

Если на сервере Redis существуют карта и ключ с именем IP-адреса, получите их с помощью оператора $visitorData = $redis->hMget($siteVisitsMap, array($visitorHashKey)); и используйте $totalVisits = $visitorData[$visitorHashKey] + 1; для увеличения переменной $totalVisits. Вы используете оператор $redis->hMget для получения данных о количестве посещений, связанных с IP-адресом. Функция hMget принимает имя вашей карты ($siteVisitsMap) и массив ключей, которые вы хотите получить с сервера Redis. В данном случае у вас есть только один ключ ($visitorHashKey), но его необходимо преобразовать в массив с помощью оператора array($visitorHashKey).

Если ваш скрипт встречает IP-адрес впервые, установите переменную $totalVisits в 1. Наконец, используйте $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits); для установки значения $visitorHashKey в соответствии с результатами предыдущего оператора if (...) {...} else {...}. Оператор $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits) создает карту хэшей $siteVisitsMap на сервере Redis с ключом $visitorHashKey и значением $totalVisits.

Затем приветствуйте посетителя, выведя общее количество посещений, и закройте блок } 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. Затем создайте еще один PHP-скрипт, который генерирует отчет на основе данных, собранных в хэш-карте Redis.

Шаг 3 — Создание скрипта отчета о статистике сайта

Когда данные собраны в хэш-карте Redis, они могут оказаться бесполезными, если вы не сможете извлечь и представить информацию в виде отчета. В этом шаге вы создадите отчет о журнале, чтобы показать различных посетителей сайта и общее количество посещений, сделанных на тестовой веб-странице.

Чтобы создать скрипт отчета о журнале, выполните nano в вашем терминальном окне и создайте новый файл /var/www/html/log_report.php:

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

Затем введите следующую информацию в файл. Замените EXAMPLE_PASSWORD на правильный пароль для сервера Redis:

/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 для извлечения всех полей (IP-адресов) и значений (общее количество посещений для каждого IP-адреса) из карты siteVisitsMap.

У вас теперь есть тестовая страница, счетчик хитов и страница отчета для проверки статистики вашего сайта. Далее вы протестируете функциональность вашего счетчика хитов и проверите, все ли работает.

Шаг 4 — Тестирование счетчика хитов Redis

На этом шаге вы протестируете всю логику вашего счетчика хитов. Перейдите по следующему URL в вашем веб-браузере. Замените your-server-IP на публичный IP-адрес или доменное имя вашего сервера.

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

Несколько раз обновите страницу, используя разные устройства, чтобы сгенерировать достаточное количество статистики. После каждого посещения вы должны получить следующий вывод.

Затем посетите следующий URL, чтобы получить отчет о посещениях вашего сайта, отображенный в виде HTML-таблицы

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

Теперь вы должны увидеть отчет, аналогичный следующему выводу.

Счетчик посещений теперь работает как ожидалось.

Заключение

В этом руководстве вы настроили счетчик посещений веб-сайта с помощью Redis и PHP на вашем сервере Ubuntu 20.04.

Как видно из примера исходного кода в этом руководстве, 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