前言

在日常开发与运维中,HTTP 状态码是我们最常打交道的一类信号。其中,404 与 500 两类错误几乎占据了线上问题的一半以上。

你是否遇到过:用户反馈页面打不开,浏览器提示 404 Not Found,但实际上资源明明存在?或者服务器突然返回 500 Internal Server Error,却没有任何具体错误信息?

本文将从底层原理、常见场景、排查手段到优雅处理实践,帮你彻底搞懂这两大经典状态码。


一、快速回顾 HTTP 状态码分类

分类 范围 含义
1xx 100-199 信息响应,请求正在处理
2xx 200-299 成功响应
3xx 300-399 重定向
4xx 400-499 客户端错误
5xx 500-599 服务端错误

404 属于 4xx(客户端错误),500 属于 5xx(服务端错误)。
本质区别:是你(客户端)的问题,还是我(服务器)的问题


二、404 Not Found — 资源未找到

1. 定义

服务器无法找到请求的资源。这是最常见的客户端错误。

RFC 7231 中明确定义:404 状态码表示源服务器没有找到目标资源的当前表示,且不希望透露该资源是临时还是永久缺失。

2. 典型场景

  • 用户输入了错误的 URL

  • 资源已被删除或移动(且未做 301/302 跳转)

  • 路由配置错误(例如 Nginx location 写错)

  • 后端接口路径写错(拼写大小写敏感问题)

  • 静态资源部署遗漏(例如图片、CSS、JS 文件缺失)

3. 搜索引擎与 SEO 影响

  • 大量 404 会降低搜索引擎对网站的信任度

  • 建议针对永久删除的资源返回 410 Gone 更语义化

  • 404 页面应友好引导用户返回首页或搜索,不要直接关闭连接

4. 如何排查 404

步骤 操作
1 检查浏览器 DevTools → Network,确认请求 URL 是否符合预期
2 查看 Web 服务器访问日志(nginx/apache),确认是否请求到达
3 检查路由配置与文件路径、大小写、后缀名
4 如果使用框架(如 Spring Boot、Express),检查 @RequestMapping 或路由注册
5 确认是否有反向代理规则导致 URL 被重写

5. 优雅处理 404

3. 为什么 500 比 404 更危险

4. 如何排查 500

步骤 操作
1 查看后端应用日志(error.logstdout、ELK 等)
2 检查最近部署变更(代码、配置、依赖升级)
3 检查资源状态(数据库、Redis、磁盘、内存)
4 复现请求(利用 Postman 或单元测试)
5 针对框架查看统一异常处理逻辑是否被覆盖

5. 优雅处理 500

java

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleGenericException(Exception e) {
        log.error("Unexpected error", e);
        ErrorResponse error = new ErrorResponse(500, "Internal Server Error");
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
    }
}


四、404 vs 500 对比总结

维度 404 500
责任方 客户端(或客户端输入/路径) 服务端
可恢复性 用户修改请求后可恢复 通常需运维/开发介入修复
日志严重级别 INFO / WARN ERROR / FATAL
典型返回体 简短说明或自定义页面 通常无详细说明(安全考虑)
SEO 影响 中等(需处理软 404) 较低(爬虫会很快重试)
发生频率 高(用户误输入、链接失效) 较低(但有重大影响)

五、进阶思考:当 404 和 500 同时出现

1. 代理/网关场景

如果你使用 Nginx 反代后端服务,当后端服务完全不可用(如进程崩溃),Nginx 可能返回 502 Bad Gateway
但若后端运行正常但业务逻辑返回 500,Nginx 会透传 500 给客户端。

2. 如何让 404 和 500 更有用


六、最佳实践清单

✅ 针对 404

✅ 针对 500


七、一道常见的面试题

问:用户访问某个链接时看到「500 Internal Server Error」,作为后端开发,你的排查思路是什么?

答:


结语

404 和 500 是 HTTP 世界里最“常驻”的两个错误状态。对它们的深刻理解,不仅能帮你快速定位线上问题,也能在设计 API 或 Web 应用时写出更健壮、更友好的代码。

  • 前端 SPA:使用 fallback 路由(如 Vue Router history 模式配合 nginx try_files)

  • 后端 API:返回标准错误结构体,例如:

  • 自定义 404 页面

  • 三、500 Internal Server Error — 服务器内部错误

    1. 定义

    服务器遇到了意外情况,导致无法完成请求。这是一类通用“服务器出错了”的状态码。

    更精确地说,500 表示没有更具体的 5xx 错误码适用,属于兜底异常。

    2. 典型场景

  • 代码抛出未捕获异常(例如空指针、数据库连接失败)

  • 第三方服务超时或返回异常数据

  • 磁盘写满或内存溢出

  • 语法错误或类加载失败(Java NoClassDefFoundError

  • 权限不足(无法读取文件或写日志)

  • 配置错误(数据库连接池配置、环境变量缺失)

  • 数据不一致风险:异常可能导致事务部分提交

  • 安全风险:某些框架在 debug 模式下会暴露堆栈信息

  • 用户体感差:用户不知道是自己操作问题还是服务故障

  • 全局异常处理器(示例:Spring Boot)

  • 绝对不要在生产环境返回堆栈信息给客户端

  • 建议配合链路追踪(如 SkyWalking、Jaeger)快速定位

  • 不要返回裸状态码:API 应统一错误结构

  • 不要在 404 中暴露系统信息(如 “File /var/www/secret.conf not found”)

  • 为前端提供 fallback UI:比如 404 时显示最近内容推荐

  • 所有用户输入的路径做合法性校验

  • 配置全局异常处理器,统一返回标准错误 JSON

  • 生产环境关闭堆栈跟踪输出

  • 接入 APM 系统(如 Sentinel、Pinpoint)监控 500 发生频率

  • 为每个 500 错误自动创建报警(钉钉/邮件/PagerDuty)

  • 定期 review 异常日志,消灭高频 NullPointer 等低级错误

  • 查看该请求的访问日志,确认哪个 URL 返回了 500;

  • 查看应用错误日志,通常能直接看到异常堆栈;

  • 根据堆栈检查对应代码逻辑、数据库查询、外部调用;

  • 如果是偶发现象,检查是否有并发问题或资源瓶颈;

  • 修复后回归测试,并考虑增加相应异常捕获逻辑,避免同类问题再次出现。

    • 静态资源使用 CDN + 版本号,避免缓存导致的 404

    • 删除或迁移资源时,保留 301/302 跳转(至少一段时间)

    • 自定义 404 页面,包含返回首页/搜索/客服入口

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐