【问题标题】:Zend / Apache2: Getting 302 Found when requesting url several timesZend / Apache2:多次请求url时发现302
【发布时间】:2013-03-04 12:35:08
【问题描述】:

我正在使用 Zend 框架编写一个 REST API
当多次调用 url 时(例如每秒 1 个请求 1000 次),在大约 0.2 % 的情况下,而不是得到 200 OK 作为响应,我得到 302 Found - 所以重定向到不同的页面。
这是整个服务器响应:

302 Found Date: Mon, 04 Mar 2013 11:56:04 GMT
Server: Apache/2.2.17 (Ubuntu)
X-Powered-By: PHP/5.3.5-1ubuntu7.11
Set-Cookie: PHPSESSID=ui9r8jqa63dbom8osknso6eea5; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Location: /de/default/index/index/error/500
Vary: Accept-Encoding
Content-Length: 0
Content-Type: text/html; charset=utf-8

所以 Zend 重定向到 error 500(内部服务器错误)页面。问题是为什么 - 我就是想不通...
被调用的 php 页面将 一行插入 MySQL 数据库 并返回一个 JSON 字符串 - 仅此而已。

Apache2 打开了大约 20 个并发连接,服务器负载为

我知道这是一个很难远程诊断的问题,但我们非常欢迎您对如何解决这个问题提出好的猜测和建议!谢谢。

这是@chris 要求的 apache vhost 配置:

<IfModule mod_ssl.c>
<VirtualHost mydomain.tld:443>
    ServerAdmin webmaster@localhost

    DocumentRoot /var/www
    ServerName www.mydomain.tld
    ServerAlias mydomain.tld *.mydomain.tld
    <Directory />
        Options FollowSymLinks
        AllowOverride All
    </Directory>
    <Directory /var/www/>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Order allow,deny
        allow from all
    </Directory>

    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
    </Directory>

    ErrorLog /var/log/apache2/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog /var/log/apache2/ssl_access.log combined

#   RewriteLog "/var/log/htaccess.log"
#   RewriteLogLevel 5

    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>

    #   SSL Engine Switch:
    #   Enable/Disable SSL for this virtual host.
    SSLEngine on
    SSLOptions +StrictRequire
    SSLCertificateFile /etc/apache2/ssl/cert_2013_2014.crt
    SSLCertificateKeyFile /etc/apache2/ssl/www.mydomain.tld.key
    SSLCACertificateFile /etc/apache2/ssl/intermediate.crt

</VirtualHost>
</IfModule>

【问题讨论】:

  • 你点击哪个 URL 来测试这个?您的 API 是否正常进行任何重定向?
  • 通常不进行重定向。回复通常是200 OK。即使调用 url 的脚本保持完全相同,也会发生错误。
  • 最后一个标题行之后的文本是什么 (Content-Type: ...) ?响应体?这是一个奇怪的语法......不是 json,不是 php 转储......否则,有 X-Powered-By: PHP 表示重定向来自 php(而不是来自 apache)。
  • 我假设 apache 错误日志什么也没说?
  • ZF 永远不应重定向 到错误页面,这就是为什么我询问您的 API 是否在其他地方进行了任何重定向。似乎正在生成错误,但没有正确处理错误。您的 API 中是否有任何错误处理代码?你在使用 Zend_Rest_Server 吗?

标签: php mysql api zend-framework apache2


【解决方案1】:

这在我看来非常简单直接。这是一个 302 重定向,我想不出 ZF 中有任何东西可以自行重定向;特别是不要出现 500 错误页面。 500 错误(内部服务器错误)必须始终返回 500 错误,并且永远不应该是 302 重定向。所以你在这里有点幸运,因为你必须在你的 RETS API 中有一些错误处理,这会导致某个地方的重定向(而不是常规的错误页面)。

在您的代码中搜索重定向。可以使用 ZF 重定向器助手(在控制器内)或手动(在任何地方)使用 header() 和 exit() 来完成。当您找到重定向时,显示(退出)带有 debug_backtrace 或将其转储到日志文件中。并且还修复了返回码或者错误的处理方式。

【讨论】:

  • 谢谢,您的评论帮助我找到了问题所在。原因是完全出乎意料的(见我的回答)
  • @Horen 利用所提供的信息我能做的就是这些,但很高兴能提供帮助。
【解决方案2】:

请注意,当您指定一个指向远程 URL 的 ErrorDocument(即前面带有 http 等方法的任何内容)时,Apache 将向客户端发送重定向以告诉它在哪里可以找到该文档,甚至如果文档最终位于同一台服务器上。

http://httpd.apache.org/docs/2.2/mod/core.html#errordocument

我假设您在您的 Apache HTTP 服务器配置中使用 ErrorDocument 指令,该指令将按照 500 错误的配置执行。

500 错误可以由 PHP 本身触发。要了解发生了什么,您需要同时查看服务器错误日志和 php 错误日志(并为此启用 PHP 错误日志)。

或者像我通常写的那样:

500 内部服务器错误始终邀请查看服务器错误日志。它包含更多信息。由于这是 PHP,也很有可能是因为 PHP 中的致命错误,因此确保启用 PHP 错误日志并查看 PHP 错误日志也非常有用。 More about the 500 Internal Server Error

【讨论】:

    【解决方案3】:

    如果没有关于您的应用程序的更多详细信息,很难猜测。我的猜测是您的一项服务(很可能是数据库)在流量和 I/O 增加的情况下会变慢。因此,某些 PHP 连接可能会超时。这会导致应用程序错误并重定向到错误页面。

    取决于您的应用程序在记录内部问题方面的表现如何,请查看logs/application.log,但默认情况下,记录内部问题并不是很好。

    【讨论】:

    • MySQL 数据库可能是瓶颈。你知道我如何证明这一点吗?
    • 您知道代码中的哪个位置负责错误重定向吗?重定向不是默认的 ZF 行为,所以我认为您有一个自定义错误插件。您必须在此处记录错误消息。无论如何它不会转到日志/应用程序日志吗?也许模拟 MySQL 超时并观察行为?
    【解决方案4】:

    哇 - 这是一个完全出乎意料的问题,真的很难弄清楚......

    @AdrianWorld 帮助我走上了正轨。在 Zend ErrorController 中输出错误信息,发现异常如下:

    ps_files_cleanup_dir: opendir(/var/lib/php5) failed: Permission denied (13) Array
    

    这显然是一个很常见的问题,正如here 所描述和解决的那样。
    变量session.gc_probabilityphp.ini 中设置为1,这意味着垃圾收集器有1% 的概率运行并清理存储php 会话的目录/var/lib/php5。显然,www-data 无法写入此文件夹,从而导致上述错误并引发 Zend 异常。

    由于session.gc_probability 仅设置错误随机发生的概率,因此调试非常困难。

    无论如何,我很高兴它已解决 - 感谢所有提示和猜测 :)

    【讨论】:

      猜你喜欢
      • 2021-07-25
      • 1970-01-01
      • 2011-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-11
      相关资源
      最近更新 更多