介绍
PARCEL 是一家虚构礼品店。访客浏览 Arc lamp 或 Clay vase,并比较配送与取货费用。取货已经可以返回估价,但配送失败。你的任务是把新的失败请求从入口追踪到实际响应的服务,再恢复准确的配送价格,同时不破坏取货功能。
具备基本终端操作能力即可。你将编辑两个简短的 Nginx 配置文件、阅读真实日志并测试实际响应。无需应用编程、SDK、外部账号、购买或个人信息。所有服务都运行在同一预置训练实例中;这里教授请求关联,并不是完整的分布式追踪平台。
使用 Website 浏览并请求估价。所有命令都在 Workstation 运行,其初始目录是 /home/labex/project/parcel。每个单元都有独立环境。端口 8081 上的入口将每次估价请求转发给一个后端。配送服务监听 8091,取货服务监听 8092。端口用于标识网络服务;在 Workstation 使用 127.0.0.1 时,它表示本实验实例。
为新请求建立统一标识
在这一步,你将了解正常客户流程、观察失败现象,并将一个新请求关联到两份真实日志。从 Website 开始。
认识礼品店
在 Two good things 下打开 Arc lamp。详情页显示 $48 和本地插画。选择 Estimate collection,保留 Arc lamp 和 Near,然后点击 Get estimate。应显示 $2.00 和 HTTP 200。这是必须保留的正常功能。点击 PARCEL↗ 返回首页,打开 Delivery,再点击 Get estimate。页面显示 Estimate unavailable 和 HTTP 404。
HTTP 是浏览器使用的请求/响应协议。200 表示响应成功;404 表示接收请求的服务未找到所请求的路径。连接错误不同:它表示没有收到可用的服务端响应。当前标识显示 not available,因此还不能方便地把客户响应对应到服务日志。

理解证据
预置入口日志已经记录 Nginx 为每次请求生成的标识。后端可以记录转发来的标识。连接两者后,同一个失败请求会生成如下形式的记录;点号表示你自己请求的标识:
entry: {"id":"...","path":"/api/delivery","status":404,"upstream":"127.0.0.1:8091","upstream_status":"404"}
delivery: {"service":"delivery","id":"...","path":"/v1/shipping","status":404}
入口路径是浏览器请求的路径。后端路径是入口实际转发的路径。upstream 表示联系到的后端地址,upstream_status 是其真实响应状态。相同标识把两次观察连接起来;请求很多时,只比较时间戳不够可靠。日志不记录请求体或秘密。
连接请求标识
切换到 Workstation。pwd 输出当前目录,cat 输出文件内容:
pwd
应显示 /home/labex/project/parcel。如果你离开了该目录,运行 cd /home/labex/project/parcel;cd 用于切换当前目录。没有以 / 开头的路径,例如 correlation.conf,相对于当前目录解析。
cat correlation.conf
文件目前只有一条注释。Nginx 是预置入口服务器,其配置由以分号结尾的指令组成。主服务器配置包含这个小文件,因此你无需编辑主配置框架。
请求头或响应头是随 HTTP 请求或响应传递的具名值。proxy_set_header 设置发给后端的头;add_header 为客户响应添加头。$request_id 是 Nginx 为当前请求生成的值。always 让失败响应也包含这个头,而不仅是成功响应。X-Request-ID 是这里双方约定的名字。入口自行生成标识,不信任访客提供的标识。
cat > correlation.conf 用 here-document 替换该文件。请粘贴整个代码块,包括单独占一行的最后一个 CONF。给 'CONF' 加引号会在文件中保留字面值 $request_id,交给 Nginx 而非 shell 解释:
cat > correlation.conf <<'CONF'
proxy_set_header X-Request-ID $request_id;
add_header X-Request-ID $request_id always;
CONF
读取保存的文件,再用提供的辅助脚本应用配置。bash 执行这个 shell 脚本。它先检查语法,只在配置有效时重新加载 Nginx;不会修复路线或判断价格。
cat correlation.conf
bash reload.sh
应看到配置测试成功,以及 **Configuration accepted. Send a new request to test it.**。若测试报告某行错误,对照代码块检查拼写、分号和字面美元符号,重新写入文件后重试。语法检查失败时,之前运行的配置继续提供服务。重新加载不会改变旧响应,必须发送新请求。
追踪你自己的新失败请求
在 Website 的 Delivery 页面再次点击 Get estimate。它仍应失败,但 Request reference 现在包含32个十六进制字符。复制这个确切的新值,不要使用上文的点号或截图中的标识。
返回 Workstation。shell 变量为后续命令保存一个值。把下面的 PASTE_YOUR_NEW_REQUEST_REFERENCE_HERE 替换为从 Website 复制的确切新标识。保留单引号,= 两边不要加空格。引号保留字面值,不要原样运行占位文本:
REQUEST_ID='PASTE_YOUR_NEW_REQUEST_REFERENCE_HERE'
grep 输出匹配的行。-F 将值当作普通文本,双引号让变量值保持完整。以下绝对路径可在任意目录使用:
grep -F "$REQUEST_ID" /var/log/parcel/entry.jsonl
grep -F "$REQUEST_ID" /var/log/parcel/delivery.jsonl
两条记录应包含完全相同的标识、后端路径 /v1/shipping 和状态 404。这证明配送请求确实到达了一个正在响应的后端;它不是服务停止或网络连接缺失。输出为空通常意味着使用了旧标识或输入错误:在 Website 重新请求,复制新值并重新设置 REQUEST_ID。如果只启用响应头,后端标识仍是 -;两条指令都需要。
本步检查发送新的只读请求来测试关联,不要求某个特定的 shell 变量、命令历史或复制出来的日志文件。
恢复路线并保留两种估价
在这一步,你将利用两份日志记录和服务契约修复配送。从 Workstation 开始。
区分地址和路径
用 cat 读取路线配置:
cat routes.conf
location = 块匹配一个精确的公开路径,花括号将指令分组。proxy_pass 告诉 Nginx 把请求发到哪里。在 http://127.0.0.1:8091/v1/shipping 中,地址和端口选择服务,/v1/shipping 选择服务内的操作。任一部分都可能有误。对于这些精确 location,配置的后端路径替换匹配的公开路径;查询选项仍随请求传递。
预置服务的契约如下:
| 公开操作 | 负责服务 | 服务地址 | 后端路径 |
|---|---|---|---|
| 配送 | delivery | http://127.0.0.1:8091 |
/v1/delivery |
| 取货 | collection | http://127.0.0.1:8092 |
/v1/collection |
两个服务都响应 /health,但服务健康不代表路线正确。日志显示配送请求到达了 8091 的 /v1/shipping。该服务负责配送,却不提供这个路径。契约要求 /v1/delivery。取货的地址和路径本来就都正确。
应用小范围修复
只替换可编辑的路线文件,同时保留取货路线:
cat > routes.conf <<'CONF'
location = /api/delivery {
proxy_pass http://127.0.0.1:8091/v1/delivery;
}
location = /api/collection {
proxy_pass http://127.0.0.1:8092/v1/collection;
}
CONF
bash reload.sh
若语法检查失败,对照花括号和分号,重写文件后重试。不要编辑预置后端、网站、日志或主服务器配置。只返回 200 而没有真实正确的估价,是掩盖缺陷而不是修复。
测试真实价格和关联
切换到 Website,打开 Delivery,再请求 Arc lamp / Near。应显示 $6.00、HTTP 200 和新标识。选择 Clay vase / Far 再请求,应为 $13.00。打开 Collection 测试 Arc lamp / Near,仍必须是 $2.00;Clay vase / Far 必须是 $4.00。每次点击发送新请求,所以标识应不同。通过 PARCEL↗ 返回商品页时,图片和价格也应正常。

返回 Workstation。curl 发送 HTTP 请求。-sS 隐藏进度但显示连接错误;-i 包含响应头。单引号让 & 保留在 URL 内,不被 shell 解释。? 后的查询选项选择商品和距离:
curl -sS -i 'http://127.0.0.1:8081/api/delivery?item=vase&zone=far'
应得到 HTTP/1.1 200 OK、一个 X-Request-ID 响应头,以及包含 "service": "delivery"、"amount": 13、"currency": "USD" 的 JSON 字段。JSON 是由具名值组成的文本格式。正文的 request_id 应等于响应头的值。头名称的大小写可能不同,但含义不变。
取这个响应的标识,重新设置 REQUEST_ID,再重复第1步的两条 grep -F 命令。两份日志现在都显示 200,delivery 日志记录 /v1/delivery。旧 404 记录仍是有用历史,不要清除或重写。
独立检查保留的功能:
curl -sS -i 'http://127.0.0.1:8081/api/collection?item=lamp&zone=near'
应看到 200、"service": "collection" 和 "amount": 2。收到 404 是普通 HTTP 响应,因此没有失败状态选项的 curl 仍可能正常退出。连接错误则表示进程不可用或地址错误,应检查最近的有效配置,不要把它当作上文的路径证据。
最终检查请求两种操作的所有商品/距离组合,将新标识与真实服务日志匹配,并测试完整客户网站。只有正常访问日志会追加;评分不会重新加载配置、改写文件或创建订单。
总结
你用同一个生成的标识关联了新请求的入口和后端日志,区分了响应服务的缺失路径与连接失败,并修复了实际路线。你测试了不同业务结果,同时保留取货功能。独立挑战会改变接收请求的服务,继续使用相同的地址/路径与关联方法。



