20-无人售货柜项目完整版本迭代实战:从开发、测试、灰度、量产全流程
20-无人售货柜项目完整版本迭代实战从开发、测试、灰度、量产全流程前言大家好我是黒漂技术佬。前面 16 篇文章我们从 Git 分支模型讲到 CI/CD、代码规范、安全审计几乎把版本管理和 DevOps 的工具链都翻了一遍。这篇是整个系列的收官之作——我们把所有知识串起来用一个真实的无人售货柜项目迭代走一遍从需求到量产的完整流程。一、项目背景一次典型的版本迭代迭代目标在售货柜上新增AI 视觉识别取货功能——用户打开柜门后任意取走商品摄像头自动识别拿走了什么自动结算。涉及的三端端技术栈仓库版本号后端微服务Java SpringBoot K8svending-backendv2.4.0安卓固件Android NDK(C) 瑞芯微 SDKvending-firmwarev3.1.0小程序UniApp Vue3vending-miniappv2.4.0团队编制后端 2 人、安卓 2 人、算法 1 人、前端 1 人、测试 1 人、产品 1 人。总计 8 人。二、Phase 1需求评审 → 建立分支体系2.1 需求评审D-14 ~ D-10产品经理输出 PRD产品需求文档核心功能点拆解特性AI 视觉识别结算 子任务拆分 [后端] 新增识别结果处理接口对接视觉算法服务 [后端] 支付模块改造支持先拿后付模式 [固件] 摄像头实时采集与图片上传 [固件] 柜门状态检测开门时触发采集关门时触发结算 [算法] 模型升级轻量化 YOLOv8 部署到瑞芯微 NPU [前端] 新增取货结算中加载动画 [前端] 结算结果展示页拿走了什么、多少钱2.2 创建分支D-10评审通过后各端从develop拉出 feature 分支# 后端gitcheckout-bfeature/ai-vision-recognition develop# 固件gitcheckout-bfeature/ai-camera-collection develop# 前端gitcheckout-bfeature/ai-settlement-ui develop关键分支命名统一规范feature/功能模块-简短描述所有 team member 一眼能看出这条分支是干什么的。三、Phase 2并行开发D-10 ~ D-110 个工作日3.1 后端开发要点// 识别结果处理微服务核心代码结构RestControllerRequestMapping(/api/v2/vision)publicclassVisionRecognitionController{PostMapping(/recognize)publicResultRecognitionResponserecognize(RequestBodyRecognitionRequestreq){// 1. 接收图片 URL调用 YOLO 推理服务ListDetectedItemitemsvisionService.detect(req.getImageUrl());// 2. 匹配 SKU 数据库获取商品信息与价格ListSkuItemresultsskuService.matchItems(items,req.getDeviceId());// 3. 创建待结算订单先拿后付模式PendingOrderorderorderService.createUnpaidOrder(results,req.getDeviceId());returnResult.success(RecognitionResponse.from(order));}}3.2 固件开发要点安卓端用 JNI 调用 C 层的摄像头采集// native_camera.cpp —— 摄像头采集核心逻辑externCJNIEXPORT jstring JNICALLJava_com_vending_camera_CameraManager_captureAndUpload(JNIEnv*env,jobject thiz){// 1. 从 /dev/video0 采集一帧原始图像cv::Mat framecaptureFrame(0,640,480);// 2. 瑞芯威 NPU 上运行轻量分类模型判断柜内是否有手/有人boolhasInteractionrknnInference(frame);// 3. 如果有交互编码为JPEG上传到OSSif(hasInteraction){std::vectorucharjpegencodeToJpeg(frame,85);returnuploadToOss(jpeg);// 返回图片URL}returnenv-NewStringUTF();}3.3 每日提交规范每个 feature 分支每天至少提交一次甚至多次遵循 Conventional Commitsgitcommit-mfeat(vision): 实现YOLO识别结果与SKU数据库的匹配逻辑 - 新增 SkuMatcher 类基于置信度阈值(0.6)过滤误检 - 支持条码商品与散装称重商品两种匹配模式 - 匹配失败时返回默认兜底商品 Refs: #5201为什么强调每天提交小步提交的好处减少 merge 冲突的概率出了问题容易定位Code Review 时 Review 的是增量而非一大坨四、Phase 3联调与测试D0 ~ D34.1 提 Merge Request各端开发完成后提交 MR 合并到developMR 标题: feat: AI视觉识别结算功能 源分支: feature/ai-vision-recognition 目标分支: develop MR 描述模板: ## 变更概述 - 新增识别结果处理微服务接口 - 支付模块改造支持先拿后付 - 新增摄像头采集与上传模块 ## 测试计划 - [ ] 单元测试覆盖率 80% - [ ] 接口自动化测试通过 - [ ] 联调测试后端 固件 算法 ## 影响范围 - 支付模块有 Breaking Change: /api/v1/pay/confirm → /api/v2/pay/confirm4.2 Code Review CI 校验MR 触发 CI 流水线自动执行stages:-lint-test-security-buildlint:stage:lintscript:-mvn checkstyle:check# Java代码规范-npx eslint src/# 前端代码规范test:stage:testscript:-mvn test# 单元测试-mvn verify# 集成测试security:stage:securityscript:-trufflehog git file://.--since-commit HEAD~20--fail-mvn dependency-check:check# 依赖漏洞扫描build:stage:buildscript:-mvn package-DskipTests-docker build-t registry.example.com/vending-backend:2.4.0-rc1 .-docker push registry.example.com/vending-backend:2.4.0-rc14.3 联调踩坑联调阶段发现的典型问题问题 1算法模型在 PC 上跑 50ms部署到瑞芯微 NPU 上跑 300ms。排查后发现 NPU 推理前需要先做 INT8 量化直接用 FP32 跑会退回到 CPU 推理。解决增加一条 CI 任务自动将 PyTorch 模型转为 RKNN 格式并量化。问题 2后端接口返回字段名totalAmount前端写成了total_amountJSON 反序列化失败。解决统一接口契约用 Swagger 文档同步三端。五、Phase 4灰度发布D4 ~ D65.1 灰度策略设计灰度不是随便找几台机器试试而是有层次有策略的渐进式发布灰度阶段 1D410%2台线下测试柜 3台低流量门店柜 观察指标识别准确率 95%、结算时间 3秒、无异常扣款 灰度阶段 2D530%扩展至 20 台覆盖不同光照环境商场/写字楼/学校 观察指标不同场景识别率差异 3%、投诉率无明显上升 灰度阶段 3D660%扩展至 50 台 观察指标系统稳定性、丢单率、运维告警频率 全量D7100%全量推送剩余 80 台5.2 K8s 灰度部署后端服务用 K8s 的 Canary 发布策略# 稳定版本90% 流量apiVersion:apps/v1kind:Deploymentmetadata:name:vending-backend-stablespec:replicas:9template:spec:containers:-name:backendimage:vending-backend:2.3.2---# 灰度版本10% 流量apiVersion:apps/v1kind:Deploymentmetadata:name:vending-backend-canaryspec:replicas:1template:spec:containers:-name:backendimage:vending-backend:2.4.0-rc1通过 Service 的标签选择器加权路由Ingress Nginx Canary将 10% 流量导入灰度实例。5.3 固件灰度固件 OTA 平台按设备 ID 控制推送范围# OTA 管理后台调用curl-XPOST http://ota-server/api/campaign/create\-d{ version: 3.1.0, devices: [VM-001, VM-002, VM-010, VM-020, VM-030], release_note: AI视觉识别功能灰度测试, max_retry: 3 }六、Phase 5全量发布与版本管理收尾D76.1 合并到 master 并打 Tag灰度验证通过后将 develop 合并到 mastergitcheckout mastergitmerge --no-ff developgittag-av2.4.0-mfeat: AI视觉识别结算功能正式发布 新增 - YOLOv8 轻量化模型部署到瑞芯微 NPU - 先拿后付结算模式 - 低光照自动补光扫码 修复 - 电磁锁 SPI 通信超时问题 - 弱网环境支付重复扣款 发布范围全量 80 台售货柜gitpush origin master--tags6.2 三端版本对齐端版本号Tag部署方式后端v2.4.0v2.4.0K8s Deployment 滚动更新固件v3.1.0v3.1.0OTA 平台分批推送小程序v2.4.0v2.4.0微信审核后全量发布6.3 自动生成发布说明# CI 自动执行从上一个版本到当前版本的所有变化npx standard-version# 结果输出在 CHANGELOG.md 中# ## [2.4.0] - 2024-06-20# ### Features# * **vision**: AI视觉识别结算功能 (#5201)# * **scan**: 低光照自动补光 (#4892)# ...6.4 归档与文档更新版本发布后在项目 Wiki 中更新接口文档更新Swagger 自动同步运维手册更新新增识别服务的监控项和告警阈值用户文档更新小程序使用指南七、完整流程串联一张图看懂全流程需求评审 → 分支创建 → 开发提交 → MR CI校验 ↓ ↓ ↓ ↓ PRD feature/* 每天commit lint/test/security ↓ ↓ 10天开发 Code Review ↓ ↓ 联调测试 → 灰度发布 → 全量发布 → 版本归档 ↓ ↓ ↓ ↓ develop 10%→30%→ merge to CHANGELOG 集成测试 60%→100% master wiki 关键检查点 [D-14] 需求评审完成 [D-10] 分支创建 任务分包 [D-1] 功能开发完成MR 提交 [D3] 联调测试通过 [D6] 灰度验证通过 [D7] 全量发布 版本归档八、系列总结版本管理与 DevOps 的关键认知这个系列从第 1 篇到第 20 篇我们覆盖了Git 分支模型GitFlow、分支命名、合并策略commit 规范Conventional Commits、小步提交CI/CD 流水线代码检查、自动测试、自动构建容器化部署Docker 化、K8s 部署、灰度与回滚热修复流程紧急分支、双向合并、快速回退版本日志CHANGELOG 自动化、版本追溯安全规范密钥管理、代码扫描、配置隔离但工具只是手段真正重要的是团队建立起版本管理的纪律不在 master 上直接改代码哪怕只改一行提交信息写出做了什么、为什么不是fix bug合并前过 CI Code Review哪怕只改了一个配置文件线上变更可回滚哪怕这次肯定没问题每一次发布都有据可查CHANGELOG 不是装饰品这些纪律不是束缚而是在保护团队——保护你在出问题时能快速定位、在扩容时能平滑扩展、在交接时能无痛过渡。全文完。感谢阅读这个系列我们下个系列见。

相关新闻

GenericAgent游戏辅助:7大核心工具打造自动化任务与策略优化终极方案

GenericAgent游戏辅助:7大核心工具打造自动化任务与策略优化终极方案

GenericAgent游戏辅助:7大核心工具打造自动化任务与策略优化终极方案 【免费下载链接】GenericAgent Self-evolving agent: grows skill tree from 3.3K-line seed, achieving full system control with 6x less token consumption 项目地址: https://gitcode.com…

2026/9/27 2:22:47 阅读更多 →
MFC自定义位图按钮实现:Owner-Draw方案与状态管理详解

MFC自定义位图按钮实现:Owner-Draw方案与状态管理详解

1. 项目概述 在Windows桌面应用开发中,尤其是使用经典的MFC框架时,界面美观度一直是开发者需要面对的挑战。系统自带的按钮控件样式单一,往往与追求专业、现代化视觉效果的软件格格不入。这时,自定义按钮,特别是使用位…

2026/10/2 2:35:44 阅读更多 →
19-研发安全规范:代码防泄露、密钥过滤、敏感配置隔离

19-研发安全规范:代码防泄露、密钥过滤、敏感配置隔离

19-研发安全规范:代码防泄露、密钥过滤、敏感配置隔离 前言 大家好,我是黒漂技术佬。 先讲个真实的故事:某团队在 GitHub 上开源了一个 Demo 项目,顺手把生产环境的数据库密码也传上去了。第二天,数据库被清了&#xf…

2026/10/4 8:10:31 阅读更多 →

最新新闻

PHPStan 从 1.x 升级到 2.0 完整指南:配置迁移、规则变化与扩展开发适配(object-enumerator 项目实践)

PHPStan 从 1.x 升级到 2.0 完整指南:配置迁移、规则变化与扩展开发适配(object-enumerator 项目实践)

开发工具 【免费下载链接】object-enumerator Traverses array structures and object graphs to enumerate all referenced objects 项目地址: https://gitcode.com/gh_mirrors/ob/object-enumerator 点击查看 免费下载 本篇指南以 PHPStan 官方升级文档&#xff…

2026/10/15 2:04:13 阅读更多 →
HoloCubic 的 LVGL 模拟器 Bar 进度条控件实战:从 lv_ex_bar_1 示例读懂 lv_bar 核心机制

HoloCubic 的 LVGL 模拟器 Bar 进度条控件实战:从 lv_ex_bar_1 示例读懂 lv_bar 核心机制

嵌入式物联网智能硬件嵌入式GUI硬件开发 【免费下载链接】HoloCubic 带网络功能的伪全息透明显示桌面站 项目地址: https://gitcode.com/gh_mirrors/ho/HoloCubic 点击查看 免费下载 本篇技术指南以 HoloCubic 开源仓库中 LVGL 模拟器(VS2019 SDL2 工程…

2026/10/15 2:04:13 阅读更多 →
Display Driver Uninstaller(DDU)深度解析:显卡驱动彻底清理工具的使用原理与实战指南

Display Driver Uninstaller(DDU)深度解析:显卡驱动彻底清理工具的使用原理与实战指南

系统编程 【免费下载链接】display-drivers-uninstaller Display Driver Uninstaller (DDU) a driver removal utility / cleaner utility 项目地址: https://gitcode.com/gh_mirrors/di/display-drivers-uninstaller 点击查看 免费下载 本文基于 Readme_ES.md&…

2026/10/15 2:04:13 阅读更多 →
GluonCV 语义分割模型的推理与 INT8 量化实战指南

GluonCV 语义分割模型的推理与 INT8 量化实战指南

计算机视觉深度学习预训练 【免费下载链接】gluon-cv Gluon CV Toolkit 项目地址: https://gitcode.com/gh_mirrors/gl/gluon-cv 点击查看 免费下载 本篇技术指南以 GluonCV 仓库 scripts/segmentation/README.md 为核心,系统讲解语义分割(S…

2026/10/15 2:04:13 阅读更多 →
从裸机指令到意识涌现:一个底层系统程序员眼中大模型计算的“祛魅”时刻

从裸机指令到意识涌现:一个底层系统程序员眼中大模型计算的“祛魅”时刻

这几年,人工智能(AI)与大语言模型(LLM)的狂潮席卷了全球的每一个角落。从各大媒体惊呼“通用人工智能(AGI)即将降临”,到风险投资机构为各种“智能体自主意识”概念疯狂挥舞支票&…

2026/10/15 2:04:13 阅读更多 →
STM32+华为云IoT+Qt:智能家居远程控制系统的三层架构与MQTT实践

STM32+华为云IoT+Qt:智能家居远程控制系统的三层架构与MQTT实践

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

2026/10/15 2:03:12 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/15 0:14:36 阅读更多 →
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/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练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/14 7:53:34 阅读更多 →