【问题标题】:How to monitor bandwidth consumption of a user in PHP如何在 PHP 中监控用户的带宽消耗
【发布时间】:2016-01-01 10:07:01
【问题描述】:

好的,我知道这是一个奇怪的问题,可能不可能,因此我们将不胜感激。

无论如何,我想知道我为每个用户提供了多少带宽。当他登录网站时,我会识别用户。

所以基本上对于每个请求,我都想知道该请求使用了多少带宽。如果当时有用户登录,我会将金额添加到他的帐户中。

将使用 codeigniter,但我怀疑这会有所不同。

至少现在,一切都将与 Apache 在同一台基于 Linux 的服务器上运行。

理想情况下,我想要一个不受托管类型限制的解决方案。

将使用谷歌云或亚马逊 AWS。如果解决方案仅限于 google cloud 或 aws,它会起作用。

【问题讨论】:

  • 所有东西都在同一台服务器上吗?
  • 还有,你运行的是什么网络服务器?阿帕奇?还是另一个?
  • @Clayton 抱歉回复晚了。是的,一切都在同一台服务器上,并且将使用 Apache
  • 不要把事情复杂化。计算总带宽使用量。除以活跃用户数。您现在可以处理每个用户的平均带宽使用情况。
  • 你希望它包含 PHP/HTML 页面的请求大小 + 所有加载的 JS/CSS/images/videos/anything 吗?我发布了一个答案,我认为它可以帮助您解决问题,但有时这些事情说起来容易做起来难

标签: php codeigniter monitoring bandwidth


【解决方案1】:

既然你说你在 Apache 上,这里有 2 个想法。

第一个想法(马马虎虎,但想想很有趣……):

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 脚本路由所有内容,以便您可以对其进行任何类型的日志记录。

第二个想法(更好):

因此,创建一个可以像 /files.php?path=/blah/blah.jpg 那样调用的 PHP 文件(本示例过于简单,可以使用 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 — 获取和设置 apache 请求注释

描述:这个函数是 Apache 的 table_get 和 table_set 的包装器。它编辑请求期间存在的注释表。该表的目的是允许 Apache 模块进行通信。

Read more here

然后在您的 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

【讨论】:

  • 谢谢伙计。这些都是很棒的想法!在这些方向上进行一些探索可以解决这个问题。另一个基于 cookie 想法的想法。我们知道哪个用户在什么时间通过哪个 IP 访问网站。我们可以在解析 apache 日志文件时使用此信息(打印日志文件中与 ip 一起使用的带宽)。这将解决空 cookie 问题,但会使其他事情变得更复杂。
  • 如果您采用第二个想法,我对如何仅针对执行的 PHP 脚本的请求大小进行了编辑。缺点是它会迫使您将 PHP 作为一个可能不受欢迎的模块使用。虽然我们在之前的工作中这样做过,但效果很好。因此,+ 文件路由将使您始终拥有用户 ID。
  • aha...看起来您可以使用apache_setenv 而不是apache_note,我相信这会绕过将PHP 作为模块的需要。同样,apache_note/apache_setenv 将只能记录在会话中运行的 PHP 脚本的大小,而不能记录任何不是 PHP 脚本的外部加载文件。
  • 是否有可能多个用户可能从同一网络访问您的网站,因此他们的 IP 相同??...我认为您可以解决这个问题,但值得一提。
【解决方案2】:

您可以使用亚马逊的 API 来检查带宽使用情况,而不是 使用日志。正如您所说,您正在使用 s3 进行管理 资产,如果您为每个用户创建一个新存储桶会很好 并检查带宽使用情况,如果他/她限制帐户 超过这个限制。

Source:

可能的解决方案:

Limiting Membership By Bandwidth

Track User Bandwidth With PHP Application

【讨论】:

  • 永远的用户的新存储桶?是的。默认情况下,AWS 将您限制为 100 个存储桶。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-21
  • 1970-01-01
  • 1970-01-01
  • 2016-01-28
  • 1970-01-01
  • 2011-02-02
  • 2017-12-13
相关资源
最近更新 更多