1.3 一次请求的完整旅程导览


文档摘要

1.3 一次请求的完整旅程导览 本节摘要:本节用一个具体例子——浏览器请求一篇博客文章——把请求在 httpd 内部的完整旅程走一遍,每一站标注"这一步做什么、可能出什么问题、对应哪类配置指令"。本节是全书总索引:第 2 到第 6 章分别放大旅程的一段。 学习目标 阅读完本节,你应当能够: 按顺序说出请求经过的十个左右站点; 把常见的故障现象(403、404、502、首字节慢)定位到具体站点; 把常见配置指令归到旅程中的对应站点; 解释"阶段"与"模块"如何在这一旅程中协作。 旅程的起点:从浏览器出发 设定一个具体场景:用户在浏览器地址栏敲下站点域名加一篇博客文章的路径,按下回车。

1.3 一次请求的完整旅程导览

本节摘要:本节用一个具体例子——浏览器请求一篇博客文章——把请求在 httpd 内部的完整旅程走一遍,每一站标注"这一步做什么、可能出什么问题、对应哪类配置指令"。本节是全书总索引:第 2 到第 6 章分别放大旅程的一段。

学习目标

阅读完本节,你应当能够:

  1. 按顺序说出请求经过的十个左右站点;
  2. 把常见的故障现象(403、404、502、首字节慢)定位到具体站点;
  3. 把常见配置指令归到旅程中的对应站点;
  4. 解释"阶段"与"模块"如何在这一旅程中协作。

旅程的起点:从浏览器出发

设定一个具体场景:用户在浏览器地址栏敲下站点域名加一篇博客文章的路径,按下回车。浏览器先做三件与服务器无关的事:解析 DNS 得到 IP、(若走 HTTPS)完成证书验证所需的准备工作、把请求行和请求头打包。这个背景下,真正发往服务器的报文核心就三行:

GET /blog/apache-journey.html HTTP/1.1 Host: www.example.com Accept-Encoding: gzip, br

第一行是方法与路径,第二行是虚拟主机判定的依据,第三行埋下了第 5 章压缩章节的伏笔。记住这三个信息,我们进站。

第一站:监听端口与 MPM 接客

报文到达服务器的 80 或 443 端口。核心根据配置里的 Listen 指令决定监听哪些地址与端口;接住连接的则是 MPM——prefork、worker 或 event 三选一。它们的差别用一句话预览:prefork 每个连接一个进程,worker 用进程池加线程,event 用少量线程看管大量连接。选型与调参是第 2 章的主菜,这里只需建立印象:MPM 决定了服务器同时能陪多少客人

这一站可能出的故障:连接被拒(端口没监听、防火墙拦截)、握手后长时间无响应(工作进程耗尽、Accept 队列堆积)。对应的观察手段是连接状态统计与错误日志里的"dropped"类记录。

第二站:虚拟主机匹配——用哪份配置伺候你

工作线程拿到请求头后,第一件事是读 Host 头,与配置中所有虚拟主机逐一匹配。命中的那份虚拟主机配置,就是后续所有处理的环境。如果没有任何一个匹配,请求落到第一个定义的虚拟主机(默认站点)——这就是为什么"敲 IP 访问会打开一个不相干网站"的经典现象会发生。基于端口、基于 IP、基于域名的三种虚拟主机形态,以及匹配的优先级规则,在第 3 章。

这一站典型故障:配置了新域名却不生效(DNS 未指向、ServerName 拼写错误)、HTTPS 站点证书与域名不符(虚拟主机与证书没对应好)。

第三站:配置合并与 .htaccess 搜身

虚拟主机确定后,httpd 把主配置、虚拟主机、<Directory> 容器乃至路径上每个目录里的 .htaccess 逐层合并成一份"最终工单"。合并有严格的顺序与覆盖规则——这就是为什么同一条指令写在三个地方会有三种效果。.htaccess 的查找有真实的磁盘开销,高流量站点应该用 AllowOverride None 关掉它,把规则搬进主配置。细节同样在第 3 章。

典型故障: .htaccess 改了不生效(AllowOverride 限制了类别)、规则互相覆盖(合并顺序与预期不符)。

第四站:控制区——你被允许进来吗

进入内容处理前有三道闸:访问控制(这个 IP/网段/国家被允许吗)、认证(你是谁,Basic/Digest/表单凭证校验)、授权(验证过身份后,允许看这个资源吗)。2.4 版本起全部统一到 Require 指令族。三道闸任何一道拒绝,请求就地终止并返回 401 或 403。第 6 章安全章节会给出生产环境的组合套路。

典型故障:403 Forbidden 九成出在这一站——目录无索引文件且禁止列表、IP 被拒、文件权限让运行用户读不了。

第五站:改写与映射——去哪里找内容

放行之后,URL 要变成"内容来源"。三条岔路:重写引擎可以按规则改写甚至重定向 URL(内部改写或 302 跳出);别名与文档根把 URL 映射到文件系统路径;代理指令把请求转交给后端服务器。这一站是 httpd 最灵活也最容易出事的环节,正则写错一个字符,整站路由崩盘。第 3 章讲重写,第 4 章讲代理。

典型故障:404(映射错路径)、重定向循环(两台服务器互相把对方设为目标)、代理 502(后端挂了)。

第六站:内容生成——响应体从哪来

映射完成后要产出响应体。静态文件直接读盘;动态内容则由处理器接管——CGI 起子进程执行、FastCGI 把请求递给常驻的 PHP-FPM 进程池、代理模块把活转给后端应用服务器。生成的响应(连同状态码与响应头)交给下一站。第 4 章展开。

典型故障:502/503(后端进程池耗尽)、PHP 页面显示源码(处理器没配置)、首字节极慢(动态生成无缓存)。

第七站:输出过滤与压缩——装箱车间

响应体踏上归途前经过输出过滤链:压缩模块按请求头的 Accept-Encoding 决定 gzip 压缩与否,头处理模块补充安全响应头、剥离服务器版本号、设置缓存控制。这里是响应的"最后一道加工",第 5 章。

典型故障:压缩了本不该压的内容(已压缩图片再压一遍白费 CPU)、安全头缺失(没在此处统一加)。

第八站:缓存与发送

如果有缓存层命中,前几站可能整段被跳过——这正是缓存的价值。发送阶段,event MPM 的异步优势体现在这里:慢慢发的静态大文件不再占用一个完整线程。HTTP/2 的多路复用也改变了发送的形态,多个请求共享一条连接。

第九站:日志与审计——行程记录归档

响应发出的同时,访问日志异步记录这条请求的时间、状态、耗时、字节数;错误日志记录旅途中任何异常。日志是排错的起点,第 6 章教你怎么配置出"能回答问题"的日志格式。

图 1-3 请求旅程十站全景与故障对照

图 1-3 请求旅程十站全景与故障对照

状态码即路标

把常见状态码当路标背下来,排错速度会有质变:

  • 403:控制区把你拦了(权限、IP 拒绝、无索引);
  • 404:映射阶段没找到内容(路径错、重写错、文档根错);
  • 301/302:改写阶段主动改变了旅程方向;
  • 500:内容生成阶段服务器内部出错(模块崩溃、配置语法在运行期爆雷);
  • 502/504:代理阶段,后端坏了或太慢。

⚠️ 常见坑:排错时只盯访问日志的状态码,不看错误日志。状态码告诉你哪一站出事,错误日志常常直接告诉你哪一行配置出的血。

本节要点回顾

  • 十站模型:监听接客 → 虚拟主机 → 配置合并 → 三道闸 → 重写映射 → 内容生成 → 输出过滤 → 缓存发送 → 日志 → 连接复用;
  • 三个请求头信息:路径决定映射、Host 决定虚拟主机、Accept-Encoding 决定压缩;
  • 状态码路标:403/404/301/500/502 各对应旅程中的固定站点;
  • 模块与阶段协作:每站都是若干模块通过钩子在当值;
  • 本书结构映射:第 2 至第 6 章分别放大旅程的一段,遇到问题先定位站点再翻对应章节。

旅程地图已经摊开。下一站,第 2 章:请求抵达端口,MPM 如何接客。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U