TT Lab
开始
学习 学习路径 课程

FDE综合实战:仓库收到了三次相同订单

开启代理之后,内部 API 挂了

在 TT Lab 中继续学习

目标

用会记录的模拟代理,亲自测量在客户内部代理配置下 curl、Python urllib、requests 各自走哪条路径,并制作让三个工具都走同一条路径的配置、集成连接器和判定工具。

为什么重要

代理环境变量不是标准而是惯例,所以每个工具的解释不同。因此在填入客户配置之后,会出现 curl 健康检查是绿灯、而只有 Python 采集器在内部 API 上收到 403 的情况。凭推测去修改配置,很容易救活一个工具却弄坏另一个。本实验培养的是用记录来确认“那个请求有没有到达代理”的习惯。

材料:/opt/lab/p1a-proxy/ —— corpnet.py(模拟代理、内部 API)、customer.env(客户配置)、cases.tsv(18 个用例)、connector.py(有问题的集成连接器)。没有互联网。127.0.0.2、127.0.0.3 也是这个 Pod 自己(回环),corp.example、saascorp.example 这样的名称无法解析——想直连的请求会在名称解析上失败,但没有出现在代理记录里,这件事本身就是“走了直连”的证据。

预计 60 分钟。会话结束后 /root/proxy 会消失,所以需要的文件要另外保存。

步骤

  1. 用 python3 /opt/lab/p1a-proxy/corpnet.py up 启动模拟的内部网络,在应用 customer.env 的状态下,分别用 curl、urllib、requests 请求一次 http://127.0.0.2:8080/health。查看响应正文中的 served_by 和 id,在 /root/proxy/repro.tsv 中写下 도구<TAB>PROXY|DIRECT<TAB>id(占位符为工具名称)三行。
  2. 用三个工具运行 cases.tsv 中第 2 步的用例(c01..c05,大小写和按协议区分的变量),按 case<TAB>curl<TAB>urllib<TAB>requests 的格式写入 /root/proxy/matrix.tsv。
  3. 测量第 3 步的用例(c06..c10,后缀、前导点、带星号的域名),追加到 matrix.tsv。
  4. 测量第 4 步的用例(c11..c14,IP、CIDR、端口),追加到 matrix.tsv。
  5. 测量第 5 步的用例(c15..c18,单个星号以及小写、大写的优先级),追加到 matrix.tsv。
  6. 制作 /root/proxy/fixed.env,让三个工具访问内部四处(127.0.0.2:8080、127.0.0.3:8080、localhost:8081、api.corp.example:8080)时直连,访问外部三处(http、https 的 saascorp.example,updates.vendor.example)时走代理 http://127.0.0.1:3128。
  7. 把 connector.py 复制为 /root/proxy/connector.py 并修复。要继续使用 CONNECTOR_PROXY,但命中 NO_PROXY 的 URL 要直连,并且不能使用环境中的 HTTP_PROXY、HTTPS_PROXY。
  8. 制作 /root/proxy/route_probe.py。python3 route_probe.py <env파일> URL...(占位符为 env 文件)要把配置文件中的代理地址换成本地哨兵,实际运行三个工具,为每个 URL 输出 url<TAB>curl<TAB>urllib<TAB>requests,判定不一致时以退出码 3 结束,全部一致则为 0。

参考

用客户配置重现故障并留下证据

启动 corpnet,用 customer.env 分别用三个工具发送一次请求,然后把工具、路径、id 写入 /root/proxy/repro.tsv。

响应正文中的 served_by 是 corp-proxy,就说明走了代理。id 必须与 logs 中的记录行对得上,并且通过记录中的 User-Agent 交叉确认是哪个工具发的。customer.env 要用 set -a 只在子 shell 中 export。

测量大写 HTTP_PROXY 和 ALL_PROXY

用三个工具运行 cases.tsv 的 c01..c05,以 PROXY/DIRECT 写入 /root/proxy/matrix.tsv。

每个用例都用 env -i 构造干净的环境,并查看请求前后 proxy.jsonl 的行数是否增加。请在 curl 手册的 ENVIRONMENT 一节中,找出只针对 http_proxy 的那个例外。

后缀、前导点、带星号的域名

测量 c06..c10,追加到 /root/proxy/matrix.tsv(不要删掉前面用例的行)。

想直连的请求会在名称解析上失败。要看的不是是否失败,而是是否到达了代理记录。saascorp.example 是以 corp.example 结尾的另一家公司的名称。

写了 CIDR 和端口的 NO_PROXY

测量 c11..c14,追加到 /root/proxy/matrix.tsv。

CIDR 支持在 curl 手册的 --noproxy 说明中,连同版本一起给出。urllib 文档写道 no_proxy 条目可以带端口。文档没有说明的工具,要测了才知道。

单个星号与小写优先

测量 c15..c18,追加到 /root/proxy/matrix.tsv。

请比较星号是列表中的一个条目时,与是整个列表时的区别。值为空字符串的小写变量,是被读作“未设置”还是“空列表”,各个工具也不一样。

以三个工具的公共子集重写配置

制作 /root/proxy/fixed.env,让内部四处直连,外部三处走 http://127.0.0.1:3128 指定的代理。

请只挑选在前面填好的表中、三个工具给出相同答案的写法。需要决定四件事:大小写、域名前面的点、用什么代替 CIDR、是否带端口。

修复使用 proxies 参数的集成连接器

把 /opt/lab/p1a-proxy/connector.py 复制为 /root/proxy/connector.py,并修改为遵守 NO_PROXY。

requests.utils 中有一个函数,可以根据 URL 和 no_proxy 字符串告知是否绕过代理。会话的 trust_env 决定是否使用环境变量中的代理。如果把内部 IP 写死在代码里,用其他 NO_PROXY 评分时就会不合格。

无论什么配置都能测量各工具路径的探针

制作 /root/proxy/route_probe.py。接收 env 文件和若干 URL,通过实际运行判定三个工具的路径并以 TSV 输出,不一致时以 3 结束,一致时以 0 结束。

客户的代理地址在这个 Pod 里是连不通的。判断规则(no_proxy)保持不变,只把代理值换成本地哨兵地址,就能根据哨兵是否收到连接来判定。评分器会用随机的域名和代理地址来测试。