gpt4 book ai didi

php - 事件源的性能

转载 作者:可可西里 更新时间:2023-11-01 00:32:51 25 4
gpt4 key购买 nike

我目前正在从事一个大型项目,该项目需要实现服务器发送的事件。我决定为此使用事件源传输,并从简单的聊天开始。目前客户端只监听一个新的聊天消息事件,但项目将来会有更多的事件。首先,我真的很关心服务器端脚本和其中的循环,其次,我不确定使用 mySQL 数据库作为存储(在本例中,用于聊天消息)是否可行实际上是一个很好的做法。当前循环在新消息出现在数据库中时泄露它们:

$statement = $connect->prepare("SELECT id, event, user, message FROM chat WHERE id > :last_event_id");
while(TRUE) {
try {
$statement->execute(array(':last_event_id' => $lastEventId));
$result = $statement->fetchAll();
foreach($result as $row) {
echo "id: " . $row['id'] . "\n";
echo "event: " . $row['event'] . "\n";
echo "data: |" . $row['user'] . "| >>> \n";
echo "data: " . $row['message'] . "\n\n";
$lastEventId++;
}
} catch(PDOException $PDOEX) {
echo $PDOEX->getMessage();
}
ob_flush();
flush();
usleep(10000);
}

据我所知,这样的循环是不可避免的,我的任务是优化它的性能。目前我在 while() 和 reasonable(?) usleep() 之外使用准备好的语句。

所以,对于那些有服务器端事件经验的人的问题:

  1. 这种技术在中等负载的网站(1000-5000 在线用户)中使用是否合理?
  2. 如果是,有什么方法可以提高性能吗?
  3. 在这种情况下,mySQL 数据库会不会成为瓶颈?

感谢任何帮助,因为问题非常复杂,搜索信息不会给我任何提示或测试方法。

最佳答案

是否会同时连接所有 1000 多个用户?您是否将 Apache 与 PHP 一起使用?如果是这样,我认为您真正应该关心的是内存:每个用户都持有一个打开的套接字、一个 Apache 进程和一个 PHP 实例。您需要针对自己的设置自行衡量,但如果我们说每个 20MB,那么 1000 个用户需要 20GB 的内存。如果你收紧事情,那么每个进程都是 12MB,每 1000 个用户仍然是 12GB。 (一个 m2.xlarge EC2 实例有 17GB 的内存,所以如果你预算每 500-1000 个用户一个,我认为你会没问题。)

相比之下,对于 10 秒的轮询时间,CPU 使用率非常低。出于同样的原因,我不认为轮询 MySQL 数据库会成为瓶颈,但在这种使用级别上,我会考虑让每个数据库写入也对 memcached 进行写入。基本上,如果您不介意投入一些硬件,您的方法看起来是可行的。它不是最有效的内存使用方式,但如果您熟悉 PHP,它可能是最有效地使用程序员时间的方式。


更新:刚看到 OP 的评论,意识到 usleep(10000) 是 0.01s,而不是 10s。哎呀!这改变了一切:

  • 您的 CPU 使用率现在很高!
  • 你需要一个 set_time_limit(0)在你的脚本的顶部:你将很快达到默认的 30 秒 CPU 使用率,并且有这么严格的限制。
  • 您应该使用通知队列服务而不是轮询数据库。

我会使用队列服务而不是 memcached,您可以找到现成的东西,或者很容易地用 PHP 编写自定义的东西。您仍然可以将 MySQL 作为主数据库并让您的队列服务轮询 MySQL;这里的区别是你只有一个进程集中轮询它,而不是一千个。队列服务是一个简单的套接字服务器,它接受来自每个前端 PHP 脚本的连接。每次轮询发现一条新消息时,它都会将其广播给所有连接到它的客户端。 (有不同的方法来构建它,但我希望这能给你一个大概的想法。)

在面向前端的 PHP 脚本中,您使用了具有 15 秒超时的 socket_select() 调用。它仅在没有数据时唤醒,其余时间使用零 CPU。 (15 秒超时是为了让您可以发送 SSE keep-alives。)


( Source for the 20MB and 12MB figures )

关于php - 事件源的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20471034/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com