事件源的性能

2023-12-03

我目前正在开发一个大型项目,需要实现服务器发送的事件。我决定使用事件源传输,并从简单的聊天开始。目前客户端仅监听新的聊天消息事件,但项目将来会有更多事件。首先,我真的很关心服务器端脚本及其循环,其次,我不确定使用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()且合理(?)usleep().

因此,对于那些有服务器端事件经验的人来说,问题是:

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

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


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

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


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

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

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

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


(20MB 和 12MB 数据的来源)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

事件源的性能 的相关文章

  • Laravel 从 5.6 升级到 Laravel 6

    我有一个项目https github com javedbaloch4 Laravel Booking https github com javedbaloch4 Laravel Booking发展于Laravel 5 6现在我想将其升级到
  • 通过 Ajax 加载内容时,WORDPRESS 音频播放器未加载,MediaElement.js 未应用

    我正在创建一个 WordPress 主题 当我使用 ajax 加载内容时 它不会将 MediaElements js 应用于我的音频播放器 因此不会显示音频 我认为这是因为 MediaElement js 加载了 wp footer 并且此
  • 删除PHP字符串中所有不匹配的字符?

    我有一个文本 我想从中删除所有不属于以下字符的字符 所需字符 0123456789 abcdefghijklmnopqrstuvwxyz n 最后一个是我确实想保留的 n 换行符 要匹配除列出的字符之外的所有字符 请使用反转字符集 http
  • Yii 使用 ajax 进行分页

    我需要使用ajax启用分页 我的代码 控制器 更新内容ajax function actionIndex dataProvider new CActiveDataProvider News array pagination gt array
  • 提高第一个查询的性能

    如果执行以下数据库 postgres 查询 则第二次调用要快得多 我猜第一个查询很慢 因为操作系统 linux 需要从磁盘获取数据 第二个查询受益于文件系统级别和 postgres 中的缓存 有没有一种方法可以优化数据库以快速获得结果fir
  • 检查 PHP 中“@”字符后面的单词

    我现在正在制作一个新闻和评论系统 但是我已经在一个部分上停留了一段时间了 我希望用户能够在 Twitter 上引用其他玩家的风格 例如 用户名 该脚本看起来像这样 不是真正的 PHP 只是想象脚本 3 string I loved the
  • Woocommerce 让产品显示在存档页面中

    我正在尝试让所有产品显示在我商店的存档页面中 我想知道他们的id我正在使用我的一个钩子 它在 wp head 上运行并检查 if is product category 我想以某种方式访问 产品的查询并获取它们的 ID if is prod
  • 使用 preg_replace 仅替换第一个匹配项

    我有一个结构类似于以下的字符串 aba aaa cba sbd dga gad aaa cbz 该字符串每次都可能有点不同 因为它来自外部源 我只想替换第一次出现的 aaa 但其他人则不然 是否可以 可选的第四个参数预替换 http php
  • preg_match_all 查询仅显示有问题的外部组

    我无法弄清楚如何只显示 preg 查询的外部组级别 我会给你一个例子 preg match all start end input matches 这个输入start1 start2 2end 1end产生这个输出start1 start2
  • 交换关联数组中的两个项目

    Example arr array apple gt sweet grapefruit gt bitter pear gt tasty banana gt yellow 我想调换一下柚子和梨的位置 这样数组就变成了 arr array ap
  • 在 PHP 中撤销 Google 访问令牌

    正如标题所示 我想以编程方式撤销授予的访问令牌 即在 PHP 中 我发现这个他们的网站 https developers google com identity protocols OAuth2WebServer tokenrevoke 但
  • 是否可以使用“git gc”来打包引用日志对象?

    正如答案所暗示的https stackoverflow com a 32025729 https stackoverflow com a 32025729我已经配置了远程裸仓库 git config gc pruneExpire never
  • jQuery Mobile 表单验证

    我有一个移动网站 除了验证之外一切都工作正常 基本上我希望从用户那里获取值 然后在单独的页面 process php 上处理它们 但是 在这样做之前 我需要检查以确保字段已填充 我已经研究了几种方法来做到这一点 但似乎没有一种有效 我现在有
  • 在 apache docker 容器中运行虚拟主机

    我在同一个 apache 容器中有两个 php 应用程序 我试图在端口上运行其中一个应用程序 因为它需要通过根域而不是子文件夹进行访问 我想在端口 8060 上运行应用程序 我尝试使用 apache 虚拟主机执行此操作 但它不会加载页面 h
  • 跟踪用户何时点击浏览器上的后退按钮

    是否可以检测用户何时单击浏览器的后退按钮 我有一个 Ajax 应用程序 如果我可以检测到用户何时单击后退按钮 我可以显示适当的数据 任何使用 PHP JavaScript 的解决方案都是优选的 任何语言的解决方案都可以 只需要我可以翻译成
  • 表单计算器脚本基本价格未加载 OnLoad

    我的表单中有一个计算器来计算我的下拉选项选择 function select calculate on change calc input type checkbox calculate on click calc function cal
  • 如果 PyPy 快 6.3 倍,为什么我不应该使用 PyPy 而不是 CPython?

    我已经听到很多关于PyPy http en wikipedia org wiki PyPy项目 他们声称它比现有技术快 6 3 倍CPython http en wikipedia org wiki CPython口译员开启他们的网站 ht
  • 内部 while 循环不工作

    这是我项目网页上的代码片段 这里我想显示用户选择的类别 然后想显示属于该类别的主题 在那里 用户可以拥有多个类别 这没有问题 我可以在第一个 while 循环中打印所有这些类别 问题是当我尝试打印主题时 结果只显示一行 但每个类别中有更多主
  • 使用正则表达式提取两个短语之间的所有单词[重复]

    这个问题在这里已经有答案了 我正在尝试使用以下正则表达式提取两个短语之间的所有单词 b item W w W 0 2 1 one W w W 0 3 business b b item W w W 0 2 3 three W w W 0 3
  • 如何使用 PHPExcel 库从 Excel 获取日期

    我正在尝试使用 PHPExcel 从 Excel 获取日期 但我没有得到日期 我得到的字符串值不是 1970 以来的秒数 我尝试过的代码是 InvDate trim excel gt getActiveSheet gt getCell B

随机推荐

  • A -> B、B -> A 类关联

    这段代码没有做任何特别的事情 这只是一个显示前向声明问题的片段 只是一个简短的问题 为什么它不起作用以及如何强制它起作用 class A class B A obj public int getB const return 0 void d
  • MySQL SELECT 从多个表、多个 GROUP BY 和 group_concat?

    我想在 MySQL 中查询三个表 如下 Table Leaderboard Name Score James 1 Steve 2 Dave 5 Table Actions Name Action Time James Ate an appl
  • 努力点击 htmlunit 中的链接

    我在点击 htmlunit 中的链接时遇到问题 我浏览了网站上的 api 我不太理解 并查看了我能找到的所有示例代码 但在单击链接时仍然遇到问题 这是错误消息的顶部 它很大 如果你愿意我可以全部提交 page2 link2 click Ex
  • 制作跨所有用户的单例应用程序

    我正在尝试创建一个仅允许所有 Windows 用户使用单个实例的应用程序 我目前正在通过打开一个要写入的文件并将其保持打开状态来完成此操作 这种方法安全吗 您知道使用 C 的替代方法吗 标准解决方案是创建一个全球性的mutex在应用程序启动
  • 使用 Pinterest 登录

    我可以在iPhone上轻松实现facebook登录 但我听说 pinterest 没有官方 API 所以我想知道是否有办法实现Pinterest登录 所以我的应用程序可以在用户使用 pinterest 登录后识别用户 没有官方 Pinter
  • 如何在 ASP.Net Core 1.1 中 Response.Cookies.Append()?

    我正在尝试将全球化添加到 Intranet 应用程序中 使用 cookie 来允许用户选择文化偏好 中间件已设置并正在运行 但我遇到了根据 UI 选择附加到 cookie 的问题 该方法直接来自 Asp Net Core 文档 如下所示 p
  • PHPExcel setCellValueByColumnAndRow 不将数据写入电子表格

    我正在使用 PHPExcel 将数据从 mysql 数据库输出到 Excel 工作簿 我的工作簿有 3 张纸 其中大部分工作正常 我在第三张纸的最后一部分输出时遇到问题 我想做的是输出一个带有行标题和列标题的表 其值取自mysql表 然后根
  • pip install --upgrade sqlalchemy 给出超出最大递归深度

    我试过了pip install upgrade sqlalchemy python2 7 setup py install 并在删除站点包中的 sqlalchemy 文件夹后 我尝试过pip install sqlalchemy 它们都给出
  • CSS 中“::”选择器的含义是什么

    我看到一篇博客文章 其中 在他们的 CSS 代码中使用了 这是他们的部分代码 webkit scrollbar width 10px 该代码对于滚动条工作正常 但我找不到定义此选择器的位置 这正式意味着什么 表示一个伪元素 而不是伪类 他们
  • 任务取消和任务继续选项

    昨天我刚刚了解了任务 TPL 因此我尝试做一个小示例项目 以便了解如何使用它们 我的示例项目设置了一个开始按钮 该按钮开始递增进度条 第二个按钮用于取消任务 用于报告何时调用使用 TaskContinuationOptions OnlyOn
  • 发出具有与声明发出类型相同类型的属性的类

    我已经找到了如何发出一个类 如下所示 class MyClass String MyProperty get set 无法弄清楚如何发出以下内容 class MyClass MyClass MyProperty get set 我面临的问题
  • 如何在使用 Netbeans 的构建过程中将文件夹包含到 dist JAR 中?

    我正在使用 Netbeans 6 9 并且我已研究过编辑 build xml 文件 以便可以将目录和文件包含在构建项目所产生的 jar 文件中 所以我的问题是如何修改 build xml 文件以将其他文件夹放入 jar 中 我的项目有以下目
  • 从 Java 方法返回时 BigDecimal 不保留实际值

    我正在用 Java 制作一个货币转换应用程序 其他一些很棒的 StackOverflow 专家建议我阅读 BigDecimal 以替换 double 来解决任何精度问题 我有两种方法系统 它将起始货币转换为美元 然后将美元价值转换为目标货币
  • 使用名称访问工作表上的自定义属性

    我正在尝试使用属性名称来访问工作表上的自定义属性 但似乎不支持此功能 至少在 C 中不支持 我看到其他人报告它可以在 VB 中工作 并且文档也这么说 有人可以确认这在 C 中不起作用吗 这是示例代码 activeWorkSheet Cust
  • 如何使用 javascript 将时间(上午 12:30)转换为时间戳?

    谁能告诉我该怎么做 我想比较2次 看看哪一次更大 比如中午 12 30 和下午 5 30 使用 Date parse Date parse 24 09 2011 15 21 41
  • Visual Studios Express - 更改调试输出目录

    有没有办法让 VS 项目将调试 EXE 构建到 bin debug 以外的目录 我找到了这个 http msdn microsoft com en us library ms165410 28v vs 80 29 aspx 但是 这仅适用于
  • 更改存储在基于哈希的集合中的对象的哈希代码

    我有一个基于哈希的对象集合 例如HashSet or HashMap 实施过程中会遇到哪些问题hashCode 因为它是根据一些可变字段计算的 所以它可以随着时间而变化 它如何影响休眠 有什么理由让hashCode 默认返回对象的ID是坏的
  • 如何将类及其成员函数分离到头文件和源文件中

    我对如何将简单类的实现和声明代码分离到新的头文件和 cpp 文件中感到困惑 例如 我如何分离以下类的代码 class A2DD private int gx int gy public A2DD int x int y gx x gy y
  • gitlab:调用 gitlab-shell

    我一直在浏览代码gitlab shell 我无法理解它是如何被调用的 如果我对我的服务器 安装了 gitlab shell 进行了拉取 那么 gitlab shell 如何知道它 bin gitlab shell有这一行作为评论 GitLa
  • 事件源的性能

    我目前正在开发一个大型项目 需要实现服务器发送的事件 我决定使用事件源传输 并从简单的聊天开始 目前客户端仅监听新的聊天消息事件 但项目将来会有更多事件 首先 我真的很关心服务器端脚本及其循环 其次 我不确定使用mySQL数据库作为存储 在