Internal Server Error中文名称内部服务器错误,对应的HTTP状态码是500。浏览器弹出这个提示,代表服务器端发生故障,不是本地网络断开或者电脑硬件问题。但服务器不会展示详细故障原因,500属于兜底错误码,相当于服务器提示自身存在故障,不会披露具体细节。它和404错误不一样,404代表请求资源不存在,500是服务器处理请求过程程序异常,无法返回正常响应。
这类错误基本都产生在网站或者应用服务端,一般和用户操作无关。用户点击页面按钮,前端发送请求给到后端,后端代码运行抛出未捕获异常,或是数据库连接失败、配置文件编写错误、内存耗尽、磁盘空间占满、第三方接口超时,最终都会返回500错误。有时候是代码本身存在漏洞,有时候是运行环境异常,也有可能是新版本上线引入故障。不同开发技术栈报错诱因不同,PHP大概率是脚本执行超时或者内存超限,Node.js常见未捕获Promise异常,Java多是空指针或者数据库连接池耗尽,Python有可能是依赖包版本冲突。服务器不会直接向用户展示这类详细堆栈信息,一方面出于安全防护,另一方面普通用户也无法看懂。

普通用户遇到500错误,可操作手段不多。优先刷新页面,部分情况只是服务器瞬时波动,刷新之后就能恢复。更换浏览器或者打开无痕窗口访问,排除本地缓存、浏览器插件干扰。如果仅仅单个页面提示500,网站其余页面访问正常,基本就是该页面功能故障,等待网站修复即可。如果整个网站全部返回500,网站管理员大概率已经收到告警,正在排查修复,也有可能还没有发现故障。可以间隔几分钟再次尝试访问,或者联系网站客服、管理员反馈问题,反馈时附上访问地址、点击操作、大致时间,比单纯告知网站打不开更有助于排查。不要持续反复提交请求,会加重服务器负载压力。
如果你是开发或者运维人员,看到500错误第一件事查看日志。Apache有error log,Nginx有error log,PHP查看php-fpm慢日志与错误日志,Node.js借助pm2或者systemd journal,Java查看catalina.out或者应用logback日志,Python看gunicorn、uwsgi日志。日志里面一般会保留堆栈信息和错误描述,定位出错文件与代码行。如果刚刚完成版本发布,可以优先回滚版本,很多故障回滚之后恢复正常,之后再排查新版本问题。检查数据库连通性,账号密码是否变更,数据库连接数是否打满,慢查询是否耗尽线程池资源。查看磁盘空间,执行df -h检查,日志写满磁盘引发500是很常见的故障。核对文件权限,上传目录、缓存目录、日志目录权限不足无法写入,就会触发报错。检查.htaccess或者nginx重写规则,一个字符书写错误,就会造成全站500。云服务器场景还要核查安全组、SELinux、防火墙是否拦截本地回环或者数据库端口。资源限制同样需要检查,ulimit配置过小,容器内存limit设置偏低,进程被OOM终止之后,页面就返回500。
500很容易和502、503、504混淆,简单区分。502 Bad Gateway是网关、代理从上游服务器收到无效响应,大多上游服务宕机或者协议不匹配。503 Service Unavailable代表服务暂时不可用,可能服务器过载或者正在维护,响应头一般携带Retry-After。504 Gateway Timeout指网关等待上游服务响应超时,请求已经发出,但在规定时间没有收到返回结果。500是服务器内部错误,覆盖范围最广,部分场景网关层无法处理故障,也会统一包装返回500。所以出现500不一定就是应用代码bug,也可能代理配置、负载均衡引发问题。
还有一类间歇性500,刷新几次页面可以正常访问,过段时间故障复现。这类故障大多由资源竞争、连接池耗尽造成,比如数据库最大连接数上限,新请求排队超时。也有可能负载均衡后端挂载多台服务器实例,其中一台存在故障,请求命中故障实例就返回500,分配到正常机器访问就没问题。这类故障排查难度更高,需要结合监控与日志,查看500报错是否集中在某台实例或者特定时间段。还有一种情况是第三方服务故障,应用调用第三方接口,对方返回异常,代码没有做异常处理,直接抛出错误,返回500。遇到这类场景,查看日志有没有外部API报错,可以对第三方接口调用增加熔断、降级策略,避免第三方故障拖垮自身应用。
WordPress这类CMS系统经常出现500报错,插件冲突、主题函数代码错误、.htaccess文件损坏、PHP版本升级不兼容,都可以触发故障。排查可以先全部禁用插件,切换回默认主题,查看站点能否恢复,之后逐个启用插件定位冲突来源。数据库表损坏也会造成500,使用repair命令修复数据表有时可以解决。如果调用第三方API接口收到500返回,查看响应体是否包含request-id追踪标识,拿着这个编号检索日志,排查效率更高。如果对接别人提供的API出现500,整理请求参数、发生时间、返回内容,提交工单或者邮件给到对方技术支持。
总的来说,Internal Server Error只是一个故障信号,代表问题出在服务器端,不是用户本地设备问题。普通用户能做的操作有限,刷新、等待、反馈问题,多次尝试无效就暂时放弃访问。开发运维人员排查手段更多,查看日志、版本回滚、资源检查、核对配置、排查依赖,这套流程基本可以定位大部分500故障根源。最难处理的是偶发故障,和特定请求参数、并发量关联,需要依靠监控和链路追踪慢慢定位。遇到500不用慌乱,它只是服务器提示出现故障,剩下工作就是定位责任人以及修复方案。