Python后端中间件专题23:两个 API 实例只能有一个入口——Nginx 反代与可信请求头
Python后端中间件专题23两个 API 实例只能有一个入口——Nginx 反代与可信请求头假设api-a和api-b都在工作客户端究竟该记住哪个地址若把两个容器端口都公开客户端就要承担故障发现、切换和安全头处理。TicketFlow 只把 Nginx 的127.0.0.1:8080暴露给部署主机两个 API 名称留在 Compose 网络中。统一入口首先是一条边界其次才是分流器。本课目标与前置读完应能解释upstream与proxy_pass、验证两个不同上游均被使用、在停掉一台 API 后经同一个入口继续读取已创建的租户工单并指出转发头从哪里开始可信。前置是 02 的/live与/health区别、07 的写请求幂等键、22 的搜索故障边界只读静态配置不需要 Docker真实切换必须在获准的远端隔离 Compose 项目运行。上一课练习答案答案 EX-22-01 [code]在已安装开发依赖的project/中保存为ex22_search_failure.py。这里的 ES 是MockTransport不是可用性演练importasyncioimporthttpxfromticketflow.search.http_adapterimportElasticsearchHTTP,SearchUnavailablefromticketflow.search.queryimportSearchFiltersasyncdefmain():asyncwithhttpx.AsyncClient(base_urlhttp://es.test:9200,transporthttpx.MockTransport(lambdarequest:httpx.Response(503)),)asclient:searchElasticsearchHTTP(client,aliasticketflow-tickets)try:awaitsearch.search(tenant_idtenant-a,queryvpn,filtersSearchFilters(),size10)exceptSearchUnavailableaserror:assertstr(error)search service unavailableprint(explicit unavailable)else:raiseAssertionError(503 must not become an empty successful result)asyncio.run(main())运行命令PYTHONPATHsrc python ex22_search_failure.pyPowerShell$env:PYTHONPATHsrc; python ex22_search_failure.py。预期输出explicit unavailable这只证明适配器把 ES 503 转为有类型的不可用错误并没有向真实 ES 发请求。答案 EX-22-02 [prose]PostgreSQL 仍正常时按 ID 读取详情以数据库事实为准既有工单读取可继续创建/修改依照 SQL 事务与 Outbox 提交不应等待 ES 索引可用。搜索端点则显式返回服务不可用项目 API 将SearchUnavailable映射到 HTTP 503而不是200 {hits:[]}后者会让用户误以为“确实没有单”掩盖尚未索引或服务故障。写入成功不意味着搜索立即可见。Nginx 的双上游只处理 API 实例故障两个实例依赖同一个坏掉的 ES切换 API 并不能修复搜索。从图读入口的故障域图中两条上游线不是两份业务数据两台 API 仍共享 PostgreSQL 事实源。upstream ticketflow_api使用least_conn偏向当前活动连接较少的实例不是严格一下一下轮询。max_fails1 fail_timeout5s是 Nginx 被动失败判断不是主动探活proxy_next_upstream_tries 2给单次请求最多两个上游尝试。健康检查必须结合/health的依赖状态而不是只看 Nginx 的静态/live。请求到达代理时客户端可能伪造X-Forwarded-For: 10.0.0.1或X-Request-ID: administrator。配置使用$remote_addr覆盖前者用 Nginx 生成的$request_id覆盖后者还以$scheme/$host/$server_port重建协议、主机与端口。API 只能在直达 API 端口不可被不可信客户端访问、且代理是明确可信跳的前提下使用这些头如果上游还有负载均衡器$remote_addr指向那一跳必须额外配置可信代理来源和 real-IP 规则不能无条件拼接用户传来的 XFF。Host由$host得到也不能被当作用户权限证明。实际怎么验而不是看见 200 就算切换正式本地检查点从课程根运行独立安装 lesson-23 并执行 baseline 与 09–23 的全部历史合同python tools/verify_executable_revisions.py--lesson 23--python python真实故障切换另需在获授权的隔离远端项目运行python scripts/run_remote_selector.py --checkpoint 23 --selector tests/e2e/test_nginx_failover.py::test_public_entry_reads_existing_ticket_after_one_api_replica_stops。该测试才会观察双 upstream、停api-a后读取既有事实并恢复实例本地静态合同不能替代这一证据。单次 200 不证明双实例分流静态/live200 不证明 API 可用。本地未设TICKETFLOW_REMOTE_TESTS1时此 selector 为SKIPremote-service-required不是故障切换 PASS。静态nginx.conf还不能证明线上 TLS、真实请求头覆盖或复原动作成功。对非幂等写请求代理重试可能在确认不确定窗口重复送达07 的Idempotency-Key和 SQL 唯一事实约束仍不可少。分诊卡同一个入口不同的坏法观察下一步不应下的结论/live200/health503分别看 api-a/b 日志和 PostgreSQL 健康、迁移Nginx 活着不等于应用就绪新日志只有一个upstream地址确认第二实例是否启动、连接数与日志时间窗least_conn不保证短样本交替不应据少量请求断言配置失效停 api-a 后仍 502/504查 api-b 进程、网络/DNS、重试次数及超时恢复故障注入双实例本身不保证共同依赖可用应用日志出现客户端伪造的 ID/IP确认只能通过入口访问、检查代理覆写头及实际加载配置不要把任意X-Forwarded-*视为认证本课练习练习 EX-23-01 [code]在project/写一个只读配置审计脚本读取docker/nginx/nginx.conf断言api-a:8000、api-b:8000、proxy_next_upstream_tries 2存在且X-Forwarded-For、X-Request-ID分别被$remote_addr、$request_id覆盖。打印四项检查结果。说明这为什么仍不等于实测双实例故障切换。练习 EX-23-02 [prose]某次写请求在 api-a 执行 SQL commit 后代理没收到响应并重试 api-b。分析何时可能产生重复、由哪一层收敛区分 Nginx/live与 API/health各能证明什么说明停掉唯一一台坏实例时的排障顺序。收束与下一站入口统一了地址和受信头的来源但没有替业务证明成功也没有为请求大小和等待时间定界。24 将用 413、504、TLS 配置把边缘保护与 API 业务规则拆开。完整核心模块Nginx 双实例入口worker_processes auto; pid /tmp/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; server_tokens off; access_log /dev/stdout; error_log /dev/stderr warn; upstream ticketflow_api { least_conn; server api-a:8000 max_fails1 fail_timeout5s; server api-b:8000 max_fails1 fail_timeout5s; keepalive 32; } server { listen 80; server_name _; location /live { access_log off; add_header Content-Type text/plain; return 200 nginx alive\n; } location / { proxy_http_version 1.1; proxy_set_header Connection ; proxy_set_header Host $host; # Do not relay client-supplied forwarding or request identity headers. proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Request-ID $request_id; proxy_set_header X-Forwarded-Port $server_port; proxy_next_upstream error timeout http_502 http_503 http_504; proxy_next_upstream_tries 2; proxy_pass http://ticketflow_api; } } }

相关新闻

AI聊天机器人三大安全攻击事件拆解:信任滥用、指令注入与供应链投毒

AI聊天机器人三大安全攻击事件拆解:信任滥用、指令注入与供应链投毒

1. 当聊天窗口变成攻击入口你可能已经习惯了每天跟AI聊天机器人打交道——写邮件、查资料、生成代码、做表格,甚至让它帮你分析合同条款。但你想过没有,这个你越来越依赖的对话窗口,本身就可能是一个精心设计的攻击入口?我做了十多…

2026/10/13 6:50:52 阅读更多 →
Python后端中间件专题19:“相关”究竟怎么算——boost、search_after 与聚合

Python后端中间件专题19:“相关”究竟怎么算——boost、search_after 与聚合

Python后端中间件专题19:“相关”究竟怎么算——boost、search_after 与聚合 客服搜索“VPN 登录”,第一条却是正文长篇提到 VPN 的普通工单,标题直接写“VPN 登录故障”的工单排在后面。产品经理说“相关性不对”,但后端不能只回…

2026/10/13 6:50:52 阅读更多 →
自由学习记录(228)

自由学习记录(228)

xxxxxxxxxxxxxxxxxxx 源码里确认了一个关键顺序:**先稳定地形、水域范围和 PCG 规则,再完成地表与雪的整理,最后录水面。**PCG 会改写 Terrain 材质权重和清雪遮罩;雪的运行材质还会读取这些地表层。水面画面里能看到的河床&…

2026/10/13 6:49:51 阅读更多 →

最新新闻

SpringBoot+Vue打造装饰工程管理系统:完整实战解析

SpringBoot+Vue打造装饰工程管理系统:完整实战解析

做装饰工程项目管理的系统,很多老牌软件公司都停留在单体架构时代,界面老旧、流程僵硬,项目经理宁可自己拉Excel表格也不愿意用。而新团队上来就搞微服务分布式,对一家中小型装饰公司来说,根本就是杀鸡用牛刀&#xff…

2026/10/13 7:36:08 阅读更多 →
Dalsa Nano相机C++采集例程:从接口配置到稳定抓帧

Dalsa Nano相机C++采集例程:从接口配置到稳定抓帧

简介:面向机器视觉、自动化检测与工业现场应用的 Dalsa Nano 相机 C 使用例程,以 GigE Vision 千兆网通信协议为基础,完整演示了相机从连接初始化、参数配置到实时图像采集、显示与保存的整个流程。压缩包内含 77 个文件,主体为 C…

2026/10/13 7:36:08 阅读更多 →
Hive多DISTINCT性能优化:用COLLECT_SET替代COUNT(DISTINCT)

Hive多DISTINCT性能优化:用COLLECT_SET替代COUNT(DISTINCT)

1. 项目概述:为什么“多个DISTINCT”会成为Hive SQL里的隐形性能杀手你有没有写过这样的Hive SQL?SELECT dt,COUNT(DISTINCT user_id) AS dau,COUNT(DISTINCT CASE WHEN is_paying 1 THEN user_id END) AS paying_users,COUNT(DISTINCT CASE WHEN chann…

2026/10/13 7:36:08 阅读更多 →
Flutter鸿蒙化适配:floor_generator桥接SQLite的完整实践与踩坑记录

Flutter鸿蒙化适配:floor_generator桥接SQLite的完整实践与踩坑记录

上个月在适配一个跨平台进销存项目到鸿蒙平台时,数据库层成了第一个硬骨头。这个项目的十几个业务模块全部建立在 floor 这个 ORM 框架之上,实体类、DAO 接口、查询条件都是现成的,本来以为 Flutter 能在鸿蒙环境跑起来,floor 也能…

2026/10/13 7:36:08 阅读更多 →
虚拟机 ens33 没有 IP?ifconfig 不显示网卡地址的排查与修复

虚拟机 ens33 没有 IP?ifconfig 不显示网卡地址的排查与修复

刚装好的虚拟机,开机之后敲下 ifconfig ,屏幕上来回翻的输出里只有 lo 和那个让人无语的 ens33 ,连个 IPv4 地址都不给。这个画面我见过太多次,第一次踩坑时还以为是虚拟网卡坏了,把虚拟机删了重建两回&#xff…

2026/10/13 7:36:08 阅读更多 →
E2B沙箱实战:AI智能体代码执行失控防护与排障指南

E2B沙箱实战:AI智能体代码执行失控防护与排障指南

1. 先搞清楚:AI 智能体为什么总能把沙箱跑崩上周有个朋友找我,说他的 AI 智能体项目出事了:Agent 在沙箱里跑了一段“看似无害”的 Python 脚本,结果沙箱彻底失联,连宿主机都差点被拖挂,最后只能重启整台机…

2026/10/13 7:35:07 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →