问题
I am programming a REST API with Zend framework.
When calling the url several times (e.g. 1000 times with 1 request per second), in about 0.2 % of the cases instead of getting 200 OK as a response I get 302 Found - so a redirect to a different page.
Here is the entire server response:
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
So Zend redirects to the error 500 (internal server error) page. The question is why - and I just can't figure it out...
The php page that is called inserts one row into a MySQL database and returns a JSON string - that's all.
Apache2 has about 20 concurrent connections open and the server load is <<1 so I really do not understand why the requests cause problems.
I know this is a really difficult problem to remote diagnose, but good guesses and recommendations how to solve this are more than welcome! Thanks.
This is the apache vhost config as requested by @chris:
<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>
回答1:
This looks pretty simple and straight forward to me. This is a 302 redirect and I can't think of anything in ZF that redirects by itself; especially not to a 500 error page. A 500 Error (internal server error) must always return a 500 error and should never ever be 302 redirect. So you are sort of lucky here because you must have some error handling in your RETS API that causes a redirect somewhere (instead of a regular error page).
Search your code for redirects. It could be done with the ZF redirector helper (inside a controller) or manually (anywhere) with header() and exit(). When you found the redirect either show (exit) with a debug_backtrace or dump that into a log file. And also fix the return code or the way the error is handled.
回答2:
Note that when you specify an ErrorDocument that points to a remote URL (ie. anything with a method such as http in front of it), Apache will send a redirect to the client to tell it where to find the document, even if the document ends up being on the same server.
http://httpd.apache.org/docs/2.2/mod/core.html#errordocument
I assume your're using the ErrorDocument directive in your Apache HTTP server configuration that will then do as configured for 500 errors.
500 errors can be triggered by PHP itself. To find out what happens you need to take a look into both the server error log as well as into php error log (and naturally enable PHP error logging for that).
Or as I commonly write:
A 500 Internal Sever Error is always an invitation to look into the servers error log. It contains more information. As this is PHP, it's also highly likely that it is because of a Fatal Error in PHP, so ensuring that PHP error logging is enabled and looking into the PHP error log is very useful, too. More about the 500 Internal Server Error
回答3:
Without more details about your application it's quite hard to guess. My guess is one of your services (most likely a database) slows down under increased traffic and I/O. As a result it might timeout for some PHP connections. That results in a application error and redirects to the error page.
Depends on how good is your application with logging internal problems look into logs/application.log but by default it's not very good with logging things.
回答4:
Wow - that was a totally unexpected problem and really hard to figure out...
@AdrianWorld helped me get on the right track. In the Zend ErrorController I output the error message and found the following exception:
ps_files_cleanup_dir: opendir(/var/lib/php5) failed: Permission denied (13) Array
That apparently is a pretty common problem as described and solved here.
The variable session.gc_probability was set to 1 in the php.ini which means there is a 1% probability for the garbage collector to run and clean up the directory /var/lib/php5 where the php sessions are stored. Apparently this folder is not writable by www-data resulting in the mentioned error and throwing the Zend exception.
Since session.gc_probability sets only a probability the error occured randomly making debugging pretty difficult.
Anyways, I'm happy it is solved - thanks for all the hints and guesses :)
来源:https://stackoverflow.com/questions/15201741/zend-apache2-getting-302-found-when-requesting-url-several-times