如何在 PHP 中监控用户的带宽消耗
How to monitor bandwidth consumption of a user in PHP
好的,我知道这是一个奇怪的问题,可能无法解决,所以我们将不胜感激。
无论如何,我想知道我给每个用户提供了多少带宽。我在他登录网站时识别用户。
基本上对于每个请求,我想知道该请求使用了多少带宽。如果当时有用户登录,我会将金额添加到他的帐户中。
将使用 codeigniter,但我怀疑这会有所不同。
一切都将与 Apache 在同一个 Linux 的服务器上,至少现在是这样。
理想情况下,我想要一个不受托管类型限制的解决方案。
将使用 Google 云或亚马逊 AWS。如果解决方案仅限于 google cloud 或 aws,它会起作用。
You can use the amazon's API to check the bandwidth usage , instead of
using the logs . as you have said that you are using s3 for managing
the assets , it will be good if you create a new bucket for every user
and check the bandwidth usage and then limit the account if he/she
exceeds that limit.
Source:
可能的解决方案:
Limiting Membership By Bandwidth
Track User Bandwidth With PHP Application
既然你说你在 Apache 上,这里有 2 个想法。
第一个想法(so-so 想法但想想很有趣...):
Cookie 随服务器上的每个请求一起发送(包括对所有图像等)。当用户登录时,使用 PHP 设置一个 cookie 并将其命名为 USERTOKEN
然后将其值设置为该用户 ID 的 md5+salt。
将 %{USERTOKEN}C
和 %B
插入到自定义 LogFormat
指令中。
%{Foobar}C The contents of cookie Foobar in the request sent to the server.
Only version 0 cookies are fully supported.
%B Size of response in bytes, excluding HTTP headers.
现在,您创建一个如下所示的自定义日志格式:
LogFormat "%B %{USERTOKEN}C" php_bandwidth_log
CustomLog "logs/php_bandwidth_log" php_bandwidth_log
然后,您创建一个脚本来解析 php_bandwidth_log 并将其映射到原始用户的 ID。
不幸的是,这个想法并非万无一失,因为假设有人仍然可以通过不传递 cookie(可能)来访问网站内容。无论如何,根据您的情况,这可能对您有用,如果不行,另一种更好的想法是基本上通过 PHP 脚本路由所有内容,这样您就可以在上面进行任何类型的日志记录。
第二个想法(更好):
所以,创建一个 PHP 文件,可以像这样调用 /files.php?path=/blah/blah.jpg
(对于这个例子来说过于简单,可以用 mod_rewrite 规则来美化)然后在里面你您可以记录该用户的 ID 并跟踪访问的文件。这是假设您只想跟踪文件。这不会跟踪页面上生成的 HTML - 您可能会使用前面提到的自定义 Apache 日志记录想法,但稍微修改一下以获取该信息。
这里有一些伪代码可以帮助您理解:
if (!$hasSession) {
die("Invalid session");
}
$size = filesize($path);
insert_into_bandwidth_table($userId, $size);
header("Content-Type: ...");
readfile($path);
以下是如何跟踪已执行的 PHP 脚本的响应大小,但只有当您是 运行 PHP 作为模块时它才有效。
在您的 PHP 中添加类似这样的内容。基本上这允许 Apache 读取此变量以用于日志写入目的:
apache_note("PHP_USER_ID", 1234);
apache_note — apache_note — Get and set apache request notes
Description: This function is a wrapper for Apache's table_get and table_set. It edits the table of notes that exists during a request. The table's purpose is to allow Apache modules to communicate.
然后在您的 httpd.conf 日志配置中执行如下操作:
LogFormat "%B %{PHP_USER_ID}n" php_bandwidth_log
CustomLog "logs/php_bandwidth_log" php_bandwidth_log
来自文档的注释信息:
%{Foobar}n The contents of note Foobar from another module.
并且...刚刚意识到有一个 apache_note 的替代方案,以防您不 运行 它作为一个模块。您的 PHP 代码会改为这样做:
apache_setenv('PHP_USER_ID', $userId, TRUE);
然后要记录您将使用此 LogFormat 指令:
LogFormat "%B %{PHP_USER_ID}e" php_bandwidth_log
好的,我知道这是一个奇怪的问题,可能无法解决,所以我们将不胜感激。
无论如何,我想知道我给每个用户提供了多少带宽。我在他登录网站时识别用户。
基本上对于每个请求,我想知道该请求使用了多少带宽。如果当时有用户登录,我会将金额添加到他的帐户中。
将使用 codeigniter,但我怀疑这会有所不同。
一切都将与 Apache 在同一个 Linux 的服务器上,至少现在是这样。
理想情况下,我想要一个不受托管类型限制的解决方案。
将使用 Google 云或亚马逊 AWS。如果解决方案仅限于 google cloud 或 aws,它会起作用。
You can use the amazon's API to check the bandwidth usage , instead of using the logs . as you have said that you are using s3 for managing the assets , it will be good if you create a new bucket for every user and check the bandwidth usage and then limit the account if he/she exceeds that limit.
Source:
可能的解决方案:
Limiting Membership By Bandwidth
Track User Bandwidth With PHP Application
既然你说你在 Apache 上,这里有 2 个想法。
第一个想法(so-so 想法但想想很有趣...):
Cookie 随服务器上的每个请求一起发送(包括对所有图像等)。当用户登录时,使用 PHP 设置一个 cookie 并将其命名为 USERTOKEN
然后将其值设置为该用户 ID 的 md5+salt。
将 %{USERTOKEN}C
和 %B
插入到自定义 LogFormat
指令中。
%{Foobar}C The contents of cookie Foobar in the request sent to the server.
Only version 0 cookies are fully supported.
%B Size of response in bytes, excluding HTTP headers.
现在,您创建一个如下所示的自定义日志格式:
LogFormat "%B %{USERTOKEN}C" php_bandwidth_log
CustomLog "logs/php_bandwidth_log" php_bandwidth_log
然后,您创建一个脚本来解析 php_bandwidth_log 并将其映射到原始用户的 ID。
不幸的是,这个想法并非万无一失,因为假设有人仍然可以通过不传递 cookie(可能)来访问网站内容。无论如何,根据您的情况,这可能对您有用,如果不行,另一种更好的想法是基本上通过 PHP 脚本路由所有内容,这样您就可以在上面进行任何类型的日志记录。
第二个想法(更好):
所以,创建一个 PHP 文件,可以像这样调用 /files.php?path=/blah/blah.jpg
(对于这个例子来说过于简单,可以用 mod_rewrite 规则来美化)然后在里面你您可以记录该用户的 ID 并跟踪访问的文件。这是假设您只想跟踪文件。这不会跟踪页面上生成的 HTML - 您可能会使用前面提到的自定义 Apache 日志记录想法,但稍微修改一下以获取该信息。
这里有一些伪代码可以帮助您理解:
if (!$hasSession) {
die("Invalid session");
}
$size = filesize($path);
insert_into_bandwidth_table($userId, $size);
header("Content-Type: ...");
readfile($path);
以下是如何跟踪已执行的 PHP 脚本的响应大小,但只有当您是 运行 PHP 作为模块时它才有效。
在您的 PHP 中添加类似这样的内容。基本上这允许 Apache 读取此变量以用于日志写入目的:
apache_note("PHP_USER_ID", 1234);
apache_note — apache_note — Get and set apache request notes
Description: This function is a wrapper for Apache's table_get and table_set. It edits the table of notes that exists during a request. The table's purpose is to allow Apache modules to communicate.
然后在您的 httpd.conf 日志配置中执行如下操作:
LogFormat "%B %{PHP_USER_ID}n" php_bandwidth_log
CustomLog "logs/php_bandwidth_log" php_bandwidth_log
来自文档的注释信息:
%{Foobar}n The contents of note Foobar from another module.
并且...刚刚意识到有一个 apache_note 的替代方案,以防您不 运行 它作为一个模块。您的 PHP 代码会改为这样做:
apache_setenv('PHP_USER_ID', $userId, TRUE);
然后要记录您将使用此 LogFormat 指令:
LogFormat "%B %{PHP_USER_ID}e" php_bandwidth_log