客户发来一张截图,白底黑字写着Internal Server Error,下面还有一行小字说Additionally, a 500 error was encountered。他问这是不是服务器崩了。直译过来就是内部服务器错误,意思是服务端处理请求时出了没预料到的问题,跟访问者的网络、浏览器都没关系,刷新多少次都一样。

这句话到底指什么

它是HTTP状态码500的标准描述。5开头代表服务端错误,而500是个笼统的兜底码:PHP脚本语法错误、数据库连不上、文件权限不对、内存超限、磁盘写满,最后都可能返回它。所以看到500不能直接下结论,必须去翻日志。容易混的是502和504,502是网关从上游拿到无效响应,504是网关等上游超时,这两个通常说明后端进程挂了或者太慢。

先找到真正的报错

tail -n 50 /var/log/nginx/error.log  tail -n 50 /www/wwwroot/站点目录/error_log

Nginx的error.log里会写具体原因,比如FastCGI sent in stderr,后面跟着PHP的Fatal error和文件行号。PHP-FPM自己的日志一般在/var/log/php-fpm/下面。如果日志里只有一行upstream timed out,说明问题在PHP那边,再去php-fpm的slowlog里找执行超过10秒的脚本,基本一抓一个准。

最常见的三个原因

  • 语法错误:刚改过配置或者模板,少个分号就是500。php -l 文件路径 可以先把语法查一遍。
  • 目录权限:属主被改成root,php-fpm以www用户运行,读不了模板文件。chown -R www:www 站点目录 能救回来。
  • .htaccess写错:Apache下规则里一个拼写错误整站直接500,把文件临时改名再访问就能验证。

别急着打开错误显示

网上很多答案让人把display_errors打开。生产环境这么干,报错信息会直接吐给访客,绝对路径、SQL语句甚至数据库账号都可能露出来。正确做法是log_errors设为On,error_log指到具体文件,前台挂一个自定义的500页面。调试完记得把这些改动撤掉,别留在生产配置里。

还有一种情况:只有某个页面500,其他都正常。那基本可以锁定这个页面的代码,或者它调用的那个接口,不用去查服务器环境。