release-runbook.md 7.0 KB

双地图发布、体检和回滚

更新:2026-10-28。测试地图API已按下方记录升级;用户明确foodie-server暂不发布,未切业务字典、未执行SQL或真实商家同步。此前2026-10-26记录仅为当时本地验证状态。

后端配置

  • Google:继续配置既有 sys_googlemap_key,保证当前使用的Routes、矩阵和地址接口可用;新配置不写死密钥、不在日志输出。
  • 自部署:MAP_SELF_HOSTED_BASE_URL 经地图Nginx应含/api,直连Flask用实际服务根地址;读令牌MAP_SELF_HOSTED_READ_TOKEN对应地图MAP_READ_TOKEN,管理令牌MAP_SELF_HOSTED_ADMIN_TOKEN对应地图MAP_ADMIN_TOKEN。全部保留在服务端。
  • 外卖:默认自部署MAP_FOOD_DELIVERY_PROFILE=car,保留现有Google DRIVE距离口径;改motorcycle需另验实际价格及Google回滚后的差异。闪送按用户车型1/2选择,不受此默认项影响。
  • 默认连接2.5秒、读取18秒。地图矩阵整批约16秒预算,Nginx读取20秒;还须检查App网关总超时、实际门店数和并发,不以这些配置代替性能验收。
  • 本次后端只新增响应字段,不新增业务表/列,无新增后端DDL。地图仓库存量SQL按其updatesql/sql.md由开发者手工执行。

发布顺序与验收

  1. 地图保持一个API、两个车型OSRM引擎;核对数据集隔离、模型/路网文件,按地图发布检查清单发布,分别验证两车型真实算路。不能只检查健康接口200。
  2. 后端先保留GOOGLE发布。验证普通/v2/多店、自配送运费及闪送两点/多站点报价与建单;自取/堂食不新增地图依赖。支付方式、优惠/满额免运、骑手容量/接单范围、预约与履约状态继续原规则。
  3. 显式同步门店并按地图CLI重建搜索索引;详情见手动同步接口。更名、搬迁、停用分别核对稳定ID,不能把营业休息等同永久删除。
  4. 导出仅含稳定ID/WGS84坐标的存量门店/收货点样本,使用地图audit_routes.py分别体检两车型。网络/鉴权/5xx属于服务故障,不能计入坏地址。失败清单由业务确认修正和放量条件。
  5. 隔离/测试环境将sys_map_distance_source设置为唯一启用默认SELF_HOSTED,验证完整矩阵顺序、重复点、最大站点数、无路/吸附/越界/超时/令牌错误。外卖失败拒绝报价;闪送服务故障降级直线并估时,越界拒绝。不自动跨来源重试。
  6. 前端按接入文档改新选址及地图画面。旧App直连Google及旧地址接口兼容保留,只有算路来源切换不代表所有Google请求消失。
  7. 真实并发、P95/P99、车型法规、门牌/入口精度和App真机联调单独验收。前述本地单测不能代替真实OSRM/PostGIS或上线批准。

回滚

在平台字典管理将SELF_HOSTED默认改为N、GOOGLE改为唯一Y,保存后刷新缓存(后台保存通常已更新)。配置缺失、无默认、多默认或未知值均选GOOGLE。正式放量前保留Google有效配置并演练一次切回。

新报价、新下单和新选址请求恢复Google;已创建订单保留原距离、运费、促销和付款快照。报价与建单之间切换造成金额/批次指纹变化,按现有错误要求重新报价,不能静默改客户应付。店铺源表或地图DDL回滚按相应备份单独处理,改字典不恢复这些数据。

运维观察

日志关注提供方、接口、车型、耗时和结构化错误;不要采集完整地址、坐标、令牌、Key或原始上游响应。分别统计路线失败、闪送直线降级、外卖报价失败、新地址失败及金额变化。地图服务中断不影响数据库直线围栏、附近排序或已有订单状态操作。

2026-10-28 测试地图发布实录

  • 目标:tokyo-map,/opt/foodie-map-tw-20260909。原API缺失外卖矩阵(404),但双车型OSRM可用。只读确认地图库已有dataset字段、TW/taiwan元数据和10,311,783条搜索索引,现有机车Lua指纹与本地一致,不需要数据库迁移或路网重建。
  • 候选镜像 foodie-map-api:candidate-20261028 先在仅回环15050端口验证,复现并修复10km附近排序数据库超时。新查询使用现有geography GiST索引的KNN,附近展示米数与排序统一球面距离,不用于配送费或骑手接单围栏。
  • 验证后仅重建API容器,重载既有Nginx以刷新API地址。数据库、汽车、机车和前端容器ID未改变,前端源文件未修改。备用候选容器已清理。
  • 发布API镜像ID:sha256:8fa2fe9975a4f92777ec207e3b33a8d9909a22eec27862b5d9738fd5b38c5b8e。部署源来自地图master 7160933 加本轮未提交的API改动,精确文件哈希、打包件及验证结果保存在私有备份,不能仅以Git基线当作最终源版本。
  • 私有备份目录 /opt/foodie-map-backups/20261028-api:before.json记录原镜像ID/tag,source-before.tar.gz保留原源码,旧镜像另标记foodie-map-api:rollback-20261028;deployment.json记录实际源指纹,live-validation.json记录两车型及小样本性能。含环境凭据的candidate.env仅在服务器私有目录,未复制到Git或本地报告。

地图API回退时,在服务器用before.json中的镜像ID重新标记为其中原image_tag,然后在原项目目录执行 docker compose up -d --no-deps --no-build api,重载 docker compose exec -T frontend nginx -s reload,核验健康与两车型路线;需要后续重建旧镜像时先恢复source-before.tar.gz中的map_api源码。不要执行会重建数据库/路网的全栈命令。旧版不支持矩阵,回退后外卖不能继续选择自部署;业务来源仍需按前述字典规则切Google。此处未实际切换业务字典或触发Google计费请求。

实测范围和未通过项

公开台北样本:汽车6476米/546秒,机车6238米/694秒;三起点矩阵分别为[6476,3168,6476]与[6238,3168,6238],重复起点保持顺序。最终40请求、4并发均成功;10km附近最大约1090ms,不能宣称满足全境搜索P99<200ms。新2km接口上限仍保持,旧10km接口保留兼容。

只读业务库坐标体检覆盖24个台湾范围门店及35个地址,用最近配对生成52组,每车型50成功/2组NO_ROUTE。失败组的两个端点分别可自行吸附算路,不能直接认定地址错误;需业务确认跨不连通路网的配送范围,不自动改坐标、加渡轮或放宽机车禁行。详细含坐标CSV仅保存在上述私有目录与本地ruoyi-admin/target/map-release,不提交Git。

本轮不修改业务数据,不同步门店、不重建搜索索引:现有测试商家同步属于另一次明确操作,须先确认目标门店与是否对外开放。本轮用户要求后端暂不发布,因此foodie-server JAR仅构建,真实App/商家/平台联调、Google真实切流回滚、全境法规/动态条件限制及正式P99均保留后续验收。