【问题标题】:Apache2 and PHP Sessions - could it be causing random slown down?Apache2 和 PHP 会话 - 它会导致随机变慢吗?
【发布时间】:2026-01-07 13:45:01
【问题描述】:

我有一个由 HTML (AngularJS) 客户端和 PHP 后端组成的应用程序。客户端和服务器之间的所有通信都是使用 XMLHTTPRequests 完成的(当然除了加载第一个 HTML 文件和静态资源 - JS/CSS ...)。服务器公开一些 API 端点,客户端向这些 URL 发出请求。一旦服务器收到请求,它会检查 $_SESSION 以检查用户是否已登录。

我的问题是,是否有可能在几乎每个请求时从 $_SESSION 读取(而不是写入)可能会导致响应出现严重挂起?例如,应用程序处理多个请求,然后发送随机请求并在几分钟后收到响应(到目前为止记录了 15 个)。似乎请求处理得太晚了(根据 dummy error_log 测试),所以减速不是由 PHP 我的代码中的操作引起的。

也许这是一个愚蠢的问题,但我已经将 apache 的 ServerLimit (1000) 翻了一番,但没有运气。我在这台服务器上还有另一个 PHP 应用程序工作正常,我能想到的唯一区别是工作应用程序几乎不检查 $_SESSION 与 XMLHTTPRequests 的组合。

PHP 版本:5.3.3

【问题讨论】:

  • 会话是如何配置的?它们是从文件、数据库中读写还是有其他机制?如果您正在基于文件存储读取/写入会话,则应用程序中将出现的第一个减速是一切都将等待硬盘驱动器返回读取信息。鉴于大多数机械驱动器每秒可以做 300 次这样的事情 - 是的,这很可能不是您的软件问题,而是硬件问题。
  • 感谢您的评论。它是基于文件的。我了解硬件限制,但这不应该导致 16 分钟的延迟(希望如此),而且没有服务器的整体负载真的很低。
  • 很难说到底是什么导致了如此巨大的减速,可能是你的代码,也可能是硬件故障,你必须检查哪个进程需要花费这么多时间才能完成并采取它从那里。祝你好运:)

标签: php apache session


【解决方案1】:

我找不到您的问题的具体原因,但是如果您使用的是 php 5.1.x,它会将所有会话数据加载到内存中 session_start() 。由于这个文件在整个服务器上的访问会被延迟。

如果您的服务器 php 版本不是 5.1,如果它是最新的 5.4 或 .5,则可能会由于创建大量会话临时文件而出现问题。

这有时会导致操作系统中的文件系统限制问题。所以你需要将会话超时设置为更短的时间。

阅读时操作系统也会有很多负载。

这可以通过使用配置参数session.gc_maxlifetime来实现

PHP 在当前会话加载后对过期会话运行垃圾收集,并使用session.gc_probabilitysession.gc_divisor 计算垃圾收集运行的概率。

所以将 session maxlife time 设置为 max 1 并查看性能。

由于这个原因,大多数 Web 应用程序都提供了一个名为记住我的选项。

如果用户在特定时间段内处于空闲状态,这些应用程序通常会替换 session_start 并强制执行超时。

希望对你有帮助

参考文献:-

Session time out best practices

Session Clustering White paper

【讨论】:

  • 大量信息需要调查,非常感谢!我会试试看。 P.S.:PHP是5.3.3,我会更新问题。
  • 如果我理解正确,我应该: - 用户登录时使用 session_start() 一次 - 将 session.gc_maxlifetime 设置为某个自定义值 - 在 session.gc_maxlifetime 之后,会话被销毁,用户将不得不重新登录?现在每个 HTTP 请求都会触发 session_start() 调用,所以这不是最佳的,对吧?
  • 哦,是的,您不需要每次都执行 session_start(),一次就足够了,我认为如果您在每次用户请求每个用户时都继续创建 session_start,那么它会创建大量会话临时文件和减慢系统速度
  • 好吧,问题是,如果用户登录,几乎每个请求都会修改响应,如果我不调用 session_start(),如果他登录,我将不会获得信息。我想我必须修改我的代码以不同的方式处理它。附言将 session.gc_maxlifetime 更改为 1 没有任何区别
  • @ladar 你能分享一下你如何为我设置最长工作时间的代码吗?还有你更改了哪个配置文件,会有多个,1 > 用于 cli 2 > apache所以你能仔细检查一下你在哪里改变了吗