Mục lục

Không có mục lục
Tham gia kênh Telegram của CloudFly để nhận thêm ưu đãi và không bỏ lỡ bất kỳ khuyến mãi nào từ CloudFly

Cách thiết lập Website Hit Counter với Redis và PHP trên Ubuntu 20.04

Ngày đăng: 31 tháng 10 năm 2022

Ubuntu

Giới thiệu

Hit counter (Bộ đếm lượt truy cập) là một ứng dụng ghi lại và cho biết số lượt truy cập mà trang web của bạn đã nhận được. Bộ đếm bắt đầu từ 1 và được tăng dần mỗi khi một trang web được truy cập.

Để theo dõi các lượt truy cập, ứng dụng hit counter yêu cầu một dạng cơ sở dữ liệu. Trong khi các hệ quản trị cơ sở dữ liệu dựa trên đĩa (disk-based database) như MySQL có thể hoạt động, thì cơ sở dữ liệu trong bộ nhớ (in-memory database) tốt hơn về tốc độ, hiệu suất, khả năng mở rộng, tính đơn giản và dễ sử dụng. Đây là lúc máy chủ Redis hoạt động. Redis lưu trữ dữ liệu trong RAM máy tính của bạn, thay vì nhấn vào đĩa mỗi khi bạn thực hiện thao tác nhập / xuất. Điều này làm tăng thông lượng đáng kể.

Để theo dõi lượt truy cập trang web của bạn, bạn cần có Redis hash map. Đây là một cấu trúc dữ liệu thực hiện một cặp key-value. Hash map (bảng băm) cung cấp một bảng băm ánh xạ các key đến các value. Khi người dùng truy cập trang web của bạn, bạn tạo key dựa trên địa chỉ IP công khai hoặc username của họ (đối với người dùng đã xác thực), sau đó bạn khởi tạo tổng số lượt truy cập của họ thành giá trị 1. Mỗi khi người dùng truy cập lại trang web của bạn, bạn kiểm tra tổng lượt truy cập của họ từ bảng băm Redis dựa trên địa chỉ IP/username của họ và tăng giá trị.

Trong hướng dẫn này, bạn sẽ thiết lập website hit counter bằng Redis và PHP trên máy chủ Ubuntu 20.04 của mình. Các tập lệnh PHP trong hướng dẫn này sử dụng địa chỉ IP công cộng của khách truy cập để theo dõi lượt truy cập của họ.

Điều kiện

Để làm theo hướng dẫn này, hãy đảm bảo bạn có những điều sau:

  • Máy chủ Ubuntu 20.04 được thiết lập cấu hình bằng hướng dẫn Thiết lập máy chủ ban đầu với Ubuntu 20.04.
  • non-root user có đặc quyền sudo. Làm theo hướng dẫn Cách tạo Sudo-enabled User mới trên Ubuntu 20.04 của chúng tôi để thiết lập non-root sudo user.
  • Apache và PHP. Để thiết lập chúng, hãy làm theo hướng dẫn Cách cài đặt Linux, Apache, MySQL, PHP (LAMP) trên Ubuntu 20.04 của chúng tôi. Bạn có thể bỏ qua Bước 2: Cài đặt MySQLBước 4: Tạo Máy chủ ảo cho Trang web của bạn vì bạn không yêu cầu cơ sở dữ liệu MySQL hoặc máy chủ ảo để kiểm tra hướng dẫn này.
  • Máy chủ Redis. Đọc hướng dẫn Cách cài đặt và bảo mật Redis trên Ubuntu 20.04 của chúng tôi để cài đặt và bảo mật máy chủ Redis.

Bước 1: Cài đặt phần mở rộng PHP Redis

Trong bước này, bạn sẽ cài đặt một tiện ích mở rộng Redis cho phép PHP giao tiếp với máy chủ Redis. Bạn cũng sẽ tạo một trang web thử nghiệm triển khai bảng băm Redis để theo dõi lượt truy cập web.

Trước khi cài đặt tiện ích mở rộng Redis, hãy làm mới chỉ mục thông tin gói Ubuntu của bạn:

  1. sudo apt update

Sau đó, chạy lệnh sau để cài đặt php-redis. Tiện ích mở rộng cung cấp một API để giao tiếp với kho lưu trữ key-value của máy chủ Redis:

  1. sudo apt install -y php-redis

Khởi động lại Apache để tải tiện ích mở rộng mới:

  1. sudo systemctl restart apache2

Bây giờ bạn đã cài đặt một tiện ích mở rộng PHP có thể kết nối với máy chủ Redis của bạn. Tiếp theo, bạn sẽ tạo một trang web test.php trong thư mục gốc của máy chủ web Apache. Đây chỉ là một tệp mẫu mà khách truy cập yêu cầu khi họ truy cập trang web của bạn bằng trình duyệt. Bên dưới, tệp trang test.php tải tập lệnh hit_counter.php mà sau này bạn sẽ tạo để theo dõi lượt truy cập trang bằng máy chủ Redis.

Trong một tình huống thực tế, trang web của bạn có thể có hàng chục hoặc thậm chí hàng trăm trang web. Đối với hướng dẫn này, bạn sẽ thiết lập một trang web cho mục đích trình diễn.

Trong cửa sổ terminal của bạn, sử dụng nano để tạo tệp test.php mới trong thư mục gốc của máy chủ web /var/www/html/:

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

Sau đó, nhập thông tin sau vào tệp 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>

Lưu và đóng tệp khi bạn hoàn tất quá trình chỉnh sửa. Trong bước này, bạn đã tạo một trang web HTML đơn giản tải tệp hit_counter.php khi được truy cập. Tiếp theo, bạn sẽ viết mã tệp hit_counter.php để theo dõi lượt truy cập trang thử nghiệm.

Bước 2: Tạo Redis Hit Counter Script

Khi làm việc trong môi trường sản xuất, việc phân tách các tệp PHP có thể sử dụng lại là rất thông thường. Điều này cho phép bạn triển khai logic trong các tệp này trên các phần khác nhau của dự án chỉ bằng cách bao gồm các đường dẫn của chúng thay vì copy-pasting. Điều này làm cho việc bảo trì dễ dàng hơn, vì bạn chỉ cần chỉnh sửa một tệp duy nhất trong trường hợp bạn cần thay đổi logic. Điều này giúp bạn tiết kiệm rất nhiều thời gian.

Bạn sẽ áp dụng chiến lược tương tự trong hướng dẫn này. Bạn sẽ tạo một tệp hit_counter.php duy nhất mà bạn có thể đưa vào bất kỳ trang web nào yêu cầu theo dõi của khách truy cập.

Trong tệp này, bạn sẽ sử dụng thư viện php-redis để kết nối với máy chủ Redis từ PHP. Sau đó, bạn sẽ tạo một bảng băm Redis để lưu trữ số lượt truy cập mà khách truy cập đã thực hiện vào trang web của bạn. Bạn sẽ sử dụng địa chỉ IP duy nhất của khách truy cập làm Redis key để phân biệt số lần truy cập của mỗi khách truy cập trong máy chủ Redis.

Trong cửa sổ terminal của bạn, hãy mở một tệp hit_counter.php mới bằng cách sử dụng nano cho mục đích chỉnh sửa:

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

Với tệp hit_counter.php hiện đã được tạo, hãy mở một thẻ PHP mới <?php. Sau đó, bên trong khối try { nhập mã dưới đây để kết nối với máy chủ Redis cục bộ của bạn trên cổng 6379. Thay EXAMPLE_PASSWORD bằng mật khẩu xác thực cho máy chủ Redis:

/var/www/html/hit_counter.php
<?php

    try {

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

Tiếp theo, đặt tên cho bảng băm Redis ($siteVisitsMap) mà bạn chọn. Hướng dẫn này sử dụng siteStats cho mục đích trình diễn:

/var/www/html/hit_counter.php
  $siteVisitsMap = 'siteStats';

Sau khi xác định bảng băm Redis, bây giờ bạn sẽ khởi tạo một Redis key trống ($visitorHashKey). Sau đó, bạn sẽ điền nó với địa chỉ IP của khách truy cập. Bạn sẽ sử dụng giá trị của biến $visitorHashKey để xác định từng khách truy cập yêu cầu trang web của bạn:

/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'];
        }

Trong mã này, bạn đang sử dụng câu lệnh if PHP để xác định địa chỉ IP của khách truy cập bằng cách kiểm tra xem các biến $ _SERVER ['HTTP_CLIENT_IP'], $ _SERVER ['HTTP_X_FORWARDED_FOR'] hoặc $ _SERVER ['REMOTE_ADDR'] đã được điền hay chưa.

Sau đó, khởi tạo biến $totalVisits để lưu trữ tổng số lượt truy cập cho mỗi địa chỉ IP và gán giá trị cho nó bằng 0. Sau đó, sử dụng PHP if (...) {...} else {...}$redis->hExists($siteVisitsMap, $visitorHashKey) để kiểm tra xem địa chỉ IP có bất kỳ mục nhập nào trong máy chủ Redis hay không.

Bạn sẽ sử dụng câu lệnh if ($redis->hExists($siteVisitsMap, $visitorHashKey)) {...} để kiểm tra xem $visitorHashKey có tồn tại trong bản đồ có tên $siteVisitsMap hay không.

Trong trường hợp map và key có địa chỉ IP được đặt tên tồn tại trong máy chủ Redis, hãy truy xuất nó bằng câu lệnh $visitorData = $redis->hMget($siteVisitsMap, array($visitorHashKey)); và sử dụng $totalVisits = $visitorData[$visitorHashKey] + 1; để tăng biến $totalVisits. Bạn đang sử dụng câu lệnh $redis->hMget để nhận dữ liệu về số lần truy cập được liên kết với địa chỉ IP. Hàm hMget chấp nhận map của bạn ($siteVisitsMap) và một mảng các key mà bạn muốn lấy từ máy chủ Redis. Trong trường hợp này, bạn chỉ có một key ($visitorHashKey), nhưng bạn phải chuyển nó thành một mảng bằng cách sử dụng câu lệnh (array($visitorHashKey)).

Trong trường hợp tập lệnh của bạn gặp địa chỉ IP lần đầu tiên, hãy đặt biến $totalVisits thành 1. Cuối cùng, sử dụng $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits); để đặt giá trị của $visitorHashKey theo kết quả của câu lệnh if (...) {...} else {...} trước đó. Câu lệnh $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits) tạo một bảng băm $siteVisitsMap trong máy chủ Redis với một key có tên là $visitorHashKey với giá trị $totalVisits.

Sau đó, chào mừng khách truy cập bằng cách lặp lại tổng số lượt truy cập và đóng khối } 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();
    }

Sau khi hoàn tất, tệp /var/www/html/hit_counter.php của bạn sẽ tương tự như mã sau:

/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();
    }

Lưu và đóng tệp khi bạn hoàn tất quá trình chỉnh sửa. Bây giờ bạn đã viết mã một tập lệnh hit_counter.php. Tiếp theo, bạn sẽ tạo một tập lệnh PHP khác để tạo báo cáo từ dữ liệu được thu thập trong bảng băm Redis.

Bước 3: Tạo Tập lệnh Báo cáo Thống kê Trang web

Khi bạn đã thu thập dữ liệu trong bảng băm Redis, sẽ không có ý nghĩa gì nếu bạn không thể truy xuất và trình bày thông tin trong báo cáo. Trong bước này, bạn sẽ tạo một báo cáo nhật ký để hiển thị các khách truy cập trang web khác nhau và tổng số lượt truy cập mà họ đã thực hiện trên trang web thử nghiệm.

Để tạo tập lệnh báo cáo nhật ký, hãy chạy nano trên cửa sổ terminal của bạn và tạo tệp /var/www/html/log_report.php mới:

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

Sau đó, nhập thông tin bên dưới vào tệp. Thay thế EXAMPLE_PASSWORD bằng mật khẩu chính xác cho máy chủ 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>

Lưu và đóng tệp khi bạn hoàn tất quá trình chỉnh sửa. Trong tập lệnh trên, bạn đang kết nối với máy chủ Redis và bạn đang sử dụng câu lệnh $redis->HGETALL($siteVisitsMap); để truy xuất bảng băm của lượt truy cập trang web của bạn. Sau đó, bạn đang sử dụng câu lệnh PHP foreach ($siteStats as $visitor => $totalVisits) { để lặp lại và hiển thị địa chỉ IP của khách truy cập và số lượt truy cập họ đã thực hiện vào trang web của bạn. Bạn đang sử dụng lệnh Redis HGETALL để truy xuất tất cả các trường (địa chỉ IP) và giá trị (tổng số lượt truy cập trên mỗi địa chỉ IP) từ bản đồ siteVisitsMap.

Bây giờ bạn có một trang thử nghiệm, một tập lệnh truy cập lần truy cập và một trang báo cáo để kiểm tra thống kê trang web của bạn. Tiếp theo, bạn sẽ kiểm tra các chức năng của bộ đếm lượt truy cập và xem mọi thứ có hoạt động hay không.

Bước 4: Kiểm tra Redis Hit Counter

Trong bước này, bạn sẽ kiểm tra toàn bộ logic cho bộ đếm lượt truy cập của mình. Điều hướng đến URL sau trên trình duyệt web của bạn. Thay thế your-server-IP bằng địa chỉ IP công cộng hoặc tên miền của máy chủ của bạn.

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

Làm mới trang nhiều lần bằng các thiết bị khác nhau để tạo đủ số liệu thống kê.

Tiếp theo, hãy truy cập URL dưới đây để hiển thị báo cáo lượt truy cập trang web của bạn trong bảng HTML.

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

Bộ đếm lượt truy cập của bạn hiện đang hoạt động như mong đợi.

Kết luận

Trong hướng dẫn này, bạn đã thiết lập bộ đếm lượt truy cập trang web bằng Redis và PHP trên máy chủ Ubuntu 20.04 của mình.

Như bạn có thể thấy từ mã nguồn mẫu trong hướng dẫn này, Redis cung cấp các phương pháp tốt hơn để tạo và cập nhật bảng băm.

Như đã đề cập ở phần đầu của hướng dẫn này, việc sử dụng hệ thống quản lý cơ sở dữ liệu quan hệ có thể vẫn hoạt động nhưng bạn sẽ viết rất nhiều mã để chèn và cập nhật dữ liệu trong các bảng bên dưới. Ngoài ra, disk-based database có thể gặp vấn đề về khả năng mở rộng khi trang web của bạn phát triển.

Tham gia kênh Telegram của CloudFly để nhận thêm ưu đãi và không bỏ lỡ bất kỳ khuyến mãi nào từ CloudFly
Chia sẻ

0 câu trả lời