Ubuntu20.04でRedisとPHPを使用してWebサイトのヒットカウンターを設定する方法
著者は、 Apache Software Foundation を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。
序章
ヒットカウンターは、Webページが受信した訪問数を記録および表示するアプリケーションです。 カウンターは1から始まり、Webページにアクセスするたびに1つずつ増加します。
訪問を追跡するために、ヒットカウンターアプリケーションにはデータベースの形式が必要です。 MySQLのようなディスクベースのデータベース管理システムは機能しますが、インメモリデータベースは、速度、パフォーマンス、スケーラビリティ、シンプルさ、および使いやすさの点で優れています。 ここで、Redisサーバーが機能します。 Redisは、入出力操作を実行するたびにディスクにアクセスするのではなく、コンピューターのRAMにデータを保存します。 これにより、スループットが大幅に向上します。
サイトへのアクセスを追跡するには、Redisハッシュマップが必要です。 これは、キーと値のペアを実装するデータ構造です。 ハッシュマップは、キーを値にマップするハッシュテーブルを提供します。 ユーザーがWebページにアクセスしたら、パブリックIPアドレスまたはユーザー名(認証されたユーザーの場合)に基づいてキーを作成し、合計アクセス数を値1に初期化します。 次に、ユーザーがWebページに再度アクセスするたびに、IPアドレス/ユーザー名に基づいてRedisハッシュマップから合計アクセス数を確認し、値をインクリメントします。
このガイドでは、Ubuntu20.04サーバーでRedisとPHPを使用してWebサイトのヒットカウンターを設定します。 このガイドのPHPスクリプトは、訪問者のパブリックIPアドレスを使用して訪問を追跡します。
前提条件
このガイドに従うには、次のものがあることを確認してください。
-
Ubuntu20.04ガイドを使用した初期サーバーセットアップを使用して構成されたUbuntu20.04サーバー。
-
sudo
権限を持つroot以外のユーザー。 Ubuntu 20.04で新しいSudo対応ユーザーを作成する方法[クイックスタート]ガイドに従って、root以外のsudoユーザーを設定します。 -
ApacheとPHP。 これらを設定するには、 Linux、Apache、MySQL、PHP(LAMP)スタックをUbuntu20.04チュートリアルにインストールする方法を使用します。 このガイドをテストするためにMySQLデータベースまたは仮想ホストを必要としないため、ステップ2 — MySQLおよびステップ4—Webサイトの仮想ホストの作成をスキップできます。
-
Redisサーバー。 Ubuntu 20.04にRedisをインストールして保護する方法[クイックスタート]チュートリアルを読んで、Redisサーバーをインストールして保護します。
ステップ1—PHPRedis拡張機能をインストールする
このステップでは、PHPがRedisサーバーと通信できるようにするRedis拡張機能をインストールします。 また、Web訪問を追跡するためにRedisハッシュマップを実装するテストWebページを作成します。
Redis拡張機能をインストールする前に、Ubuntuパッケージ情報インデックスを更新してください。
- sudo apt update
次に、次のコマンドを実行してphp-redis
をインストールします。 この拡張機能は、RedisサーバーのKey-Valueストアと通信するためのAPIを提供します。
- sudo apt install -y php-redis
Apacheを再起動して、新しい拡張機能をロードします。
- sudo systemctl restart apache2
これで、Redisサーバーと通信するPHP拡張機能がインストールされました。 次に、ApacheWebサーバーのルートディレクトリの下にtest.php
Webページを作成します。 これは、訪問者がブラウザを使用してWebサイトにアクセスしたときに要求するサンプルファイルです。 内部的には、test.php
ページファイルはhit_counter.php
スクリプトをロードします。このスクリプトは、後でRedisサーバーを使用してページアクセスを追跡するために作成します。
実際のシナリオでは、Webサイトに数十または数百のWebページが含まれる場合があります。 このガイドでは、デモンストレーション用に1つのWebページを設定します。
ターミナルウィンドウで、nano
を使用して、Webサーバー/var/www/html/
のルートディレクトリの下に新しいtest.php
ファイルを作成します。
- sudo nano /var/www/html/test.php
次に、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
ファイルをロードする単純なHTMLWebページを作成しました。 次に、hit_counter.php
ファイルをコーディングして、テストページへのアクセスを追跡します。
ステップ2—Redisヒットカウンタースクリプトを作成する
実稼働環境で作業する場合、再利用可能なPHPファイルを分離することは非常に一般的です。 これにより、コードをコピーして貼り付ける代わりに、パスを含めるだけで、プロジェクトのさまざまな部分にこれらのファイルのロジックを実装できます。 これにより、ロジックを変更する必要がある場合に1つのファイルを編集するだけで済むため、メンテナンスが容易になります。 これにより、時間を大幅に節約できます。
このガイドでも同じ戦略を適用します。 訪問者の追跡が必要な任意のWebページに含めることができる単一のhit_counter.php
ファイルを作成します。
このファイルでは、php-redis
ライブラリを使用して、PHPからRedisサーバーに接続します。 次に、Redisハッシュマップを作成して、訪問者がWebサイトにアクセスした回数を保存します。 訪問者の一意のIPアドレスをRedisキーとして使用して、Redisサーバーでの各訪問者のヒット数を区別します。
ターミナルウィンドウで、編集目的でnano
を使用して新しいhit_counter.php
ファイルを開きます。
- sudo nano /var/www/html/hit_counter.php
hit_counter.php
ファイルが作成されたら、新しいPHPタグ<?php
を開きます。 次に、try {
ブロック内に次のコードを入力して、ポート6379
でローカルRedisサーバーに接続します。 EXAMPLE_PASSWORD
をRedisサーバーの認証パスワードに置き換えます。
<?php
try {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('EXAMPLE_PASSWORD');
次に、Redisハッシュマップ($siteVisitsMap
)に任意の名前を付けます。 このガイドでは、デモンストレーションの目的でsiteStats
を使用しています。
$siteVisitsMap = 'siteStats';
Redisハッシュマップを定義した後、空のRedisキー($visitorHashKey
)を初期化します。 次に、訪問者のIPアドレスを入力します。 $visitorHashKey
変数の値を使用して、Webページを要求している各訪問者を一意に識別します。
$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']
変数がポピュレート。
これに続いて、$totalVisits
変数を初期化して、各IPアドレスの合計訪問数を保存し、それに0の値を割り当てます。 次に、PHPのif (...) {...} else {...}
および$redis->hExists($siteVisitsMap, $visitorHashKey)
ステートメントを使用して、IPアドレスにRedisサーバーにエントリがあるかどうかを確認します。
ステートメントif ($redis->hExists($siteVisitsMap, $visitorHashKey)) {...}
を使用して、$visitorHashKey
が$siteVisitsMap
という名前のマップに存在するかどうかを確認します。
指定されたIPアドレスを持つマップとキーがRedisサーバーに存在する場合は、ステートメント$visitorData = $redis->hMget($siteVisitsMap, array($visitorHashKey));
でそれを取得し、$totalVisits = $visitorData[$visitorHashKey] + 1;
を使用して$totalVisits
変数をインクリメントします。 $redis->hMget
ステートメントを使用して、IPアドレスに関連付けられたヒットカウントデータを取得しています。 hMget
関数は、マップの名前($siteVisitsMap
)とRedisサーバーから取得するキーの配列を受け入れます。 この場合、キーは1つ($visitorHashKey
)しかありませんが、ステートメントarray($visitorHashKey)
を使用して配列に変換する必要があります。
スクリプトが初めてIPアドレスに遭遇した場合は、$totalVisits
変数を1に設定します。 最後に、$redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits);
を使用して、前のif (...) {...} else {...}
ステートメントの結果に従って$visitorHashKey
の値を設定します。 $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits)
ステートメントは、$totalVisits
の値を持つ$visitorHashKey
という名前のキーを使用して、Redisサーバーに$siteVisitsMap
ハッシュマップを作成します。
次に、合計訪問数をエコーして訪問者を歓迎し、} catch (...) {...}
ブロックを閉じます。
$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
ファイルは次のコードのようになります。
<?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ハッシュマップにデータを収集した後、レポートで情報を取得して表すことができない場合は、意味がない可能性があります。 このステップでは、ログレポートを作成して、さまざまなサイト訪問者と、テストWebページでの合計訪問数を示します。
ログレポートスクリプトを作成するには、ターミナルウィンドウでnano
を実行し、新しい/var/www/html/log_report.php
ファイルを作成します。
- sudo nano /var/www/html/log_report.php
次に、以下の情報をファイルに入力します。 EXAMPLE_PASSWORD
をRedisサーバーの正しいパスワードに置き換えます。
<!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);
を使用して、Webページの訪問のハッシュマップを取得しています。 次に、PHP foreach ($siteStats as $visitor => $totalVisits) {
ステートメントを使用して、訪問者のIPアドレスとサイトへの訪問数をループして表示します。 Redis HGETALL
コマンドを使用して、siteVisitsMap
マップからすべてのフィールド(IPアドレス)と値(各IPアドレスあたりの合計訪問数)を取得しています。
これで、サイトの統計を確認するためのテストページ、ヒットカウンタースクリプト、およびレポートページができました。 次に、ヒットカウンターの機能をテストし、すべてが機能するかどうかを確認します。
ステップ4—Redisヒットカウンターをテストする
このステップでは、ヒットカウンターのロジック全体をテストします。 Webブラウザで次のURLに移動します。 your-server-IP
をサーバーのパブリックIPアドレスまたはドメイン名に置き換えます。
http://your-server-IP/test.php
十分な統計を生成するために、さまざまなデバイスを使用してページを数回更新します。 訪問するたびに、次の出力が表示されます。
次に、次のURLにアクセスして、サイト訪問レポートをHTMLテーブルに表示します。
http://your-server-IP/log_report.php
次の出力のようなレポートが表示されます。
これで、ヒットカウンターが期待どおりに機能しています。
結論
このガイドでは、Ubuntu20.04サーバーでRedisとPHPを使用してWebサイトのヒットカウンターを設定しました。
このガイドのサンプルソースコードからわかるように、Redisはハッシュマップを作成および更新するためのよりクリーンなメソッドを提供します。
このガイドの冒頭で述べたように、リレーショナルデータベース管理システムの使用は引き続き機能する可能性がありますが、基になるテーブルにデータを挿入および更新するための大量のコードを記述します。 さらに、ディスクベースのデータベースでは、サイトが大きくなるとスケーラビリティの問題が発生する可能性があります。
Redisインメモリデータベースの使用の詳細については、以下のガイドに従ってください。