当前位置: 首页 > article >正文

《苍穹外卖》实战:从零到一构建高并发外卖系统核心笔记

1. 公共字段自动填充的工程化实践第一次看到《苍穹外卖》项目里那些重复出现的创建人、创建时间、修改人、修改时间字段时我就意识到这绝对是个需要优化的地方。每个实体类都手动维护这些字段不仅容易出错后期维护更是噩梦。好在Spring AOP给我们提供了完美的解决方案。我采用的方案是自定义注解切面编程。首先定义了一个AutoFill注解标注在需要自动填充的Mapper方法上。然后创建了AutoFillAspect切面类通过Before通知在方法执行前自动注入这些字段值。这里有个小技巧我用了枚举来区分操作类型INSERT/UPDATE这样切面就能智能判断该填充哪些字段。Retention(RetentionPolicy.RUNTIME) Target(ElementType.METHOD) public interface AutoFill { OperationType value(); }实际使用时Service层完全不用关心这些字段只需要在Mapper方法加上注解就行。比如更新分类信息时AutoFill(OperationType.UPDATE) void update(Category category);但要注意两个坑第一SQL语句里这些字段还是得写第二字段赋值用的是反射性能会有轻微损耗。实测下来在常规业务场景中这点损耗完全可以接受。2. 微信生态集成实战心得做外卖系统免不了要对接微信生态这里我踩过的坑可能比写的代码还多。先说小程序登录流程前端获取code传给后端后端用codeappidsecret换openid。听起来简单但实际开发时微信接口的各种限制会让你怀疑人生。我专门封装了一个WeChatAuthService处理所有微信交互关键代码如下public String getOpenid(String code) { String url https://api.weixin.qq.com/sns/jscode2session; MapString, String params new HashMap(); params.put(appid, weChatProperties.getAppid()); params.put(secret, weChatProperties.getSecret()); params.put(js_code, code); params.put(grant_type, authorization_code); String response httpClient.doGet(url, params); return JSON.parseObject(response).getString(openid); }支付模块更是个深坑。没有商户资质的情况下我参考了网上的模拟支付方案。核心思路是在前端跳过真正的支付流程直接回调成功状态后端收到通知后自动更新订单状态。虽然不能真实交易但完整走通了支付流程对开发测试完全够用。3. Redis缓存策略的进阶玩法刚开始用Redis缓存菜品数据时我天真地以为简单set/get就完事了结果被缓存一致性问题狠狠教育。后来摸索出一套组合策略双写模式更新数据库后立即更新缓存失效模式数据变更时直接删除缓存延时双删先删缓存→更新DB→休眠→再删缓存在《苍穹外卖》中我最终采用了Spring Cache注解方案因为它足够简单高效Cacheable(value dishCache, key #categoryId) public ListDishVO list(Long categoryId) { // 查询数据库 } CacheEvict(value dishCache, allEntries true) public void save(DishDTO dishDTO) { // 保存逻辑 }特别提醒缓存key的设计非常重要。我习惯用业务前缀:参数的格式比如dishCache:1表示分类ID为1的菜品。这样既清晰又能避免key冲突。4. 高并发下的购物车设计购物车模块看似简单实则暗藏玄机。最大的挑战是要在用户体验和系统性能间找到平衡。我的方案是读写分离读操作走Redis缓存写操作同步到MySQL异步持久化用户添加商品时先写Redis通过消息队列异步落库冗余设计在购物车表中存储菜品名称、图片等冗余字段避免频繁联表查询核心数据结构设计如下# 用户购物车 user:cart:{userId} - { dish_1: 2, // 菜品1数量2 dish_2: 1 // 菜品2数量1 }实际编码时我抽象出了一个CartService统一处理购物车逻辑。其中有个精妙的设计是使用Redis的HASH结构存储购物车商品既能快速查询单个商品数量又能高效获取整个购物车。5. 订单系统的防重与幂等设计外卖系统的订单模块最怕两件事重复提交和支付掉单。我用了三个技术手段来防范前端防抖提交按钮点击后立即禁用防止连点Token机制页面加载时后端生成唯一token提交时校验数据库唯一索引对订单号字段建立唯一索引支付回调处理更要小心。我设计了状态机模式来管理订单状态流转public enum OrderStatus { PENDING_PAYMENT, // 待支付 PAID, // 已支付 COMPLETED, // 已完成 CANCELLED // 已取消 }每个状态变更都要记录操作日志这是后期排查问题的黄金数据。建议使用AOP统一记录代码大概长这样AfterReturning(execution(* com.sky.service.OrderService.*(..))) public void logOrderChange(JoinPoint jp) { // 获取方法参数中的订单ID // 记录变更前后的状态 // 存入日志表 }6. 性能优化的那些事儿项目上线前我用JMeter做了压力测试发现几个性能瓶颈N1查询问题获取订单详情时频繁查询关联表大对象序列化菜品列表JSON太大导致Redis阻塞锁竞争激烈秒杀活动时库存扣减超卖解决方案也很有意思。对于N1问题我用了MyBatis的collection标签做嵌套查询大对象序列化改用Protocol Buffers替代JSON库存扣减则采用RedisLua脚本实现原子操作local stock tonumber(redis.call(GET, KEYS[1])) if stock 0 then redis.call(DECR, KEYS[1]) return 1 else return 0 end还有个容易被忽视的优化点数据库连接池配置。经过多次调优最终确定的HikariCP参数如下spring.datasource.hikari.maximum-pool-size20 spring.datasource.hikari.minimum-idle10 spring.datasource.hikari.idle-timeout30000 spring.datasource.hikari.connection-timeout20007. 异常处理的艺术好的异常处理能让系统稳定性提升好几个Level。我的异常处理哲学是业务异常给用户友好提示如菜品已售罄系统异常记录详细日志自动报警第三方异常设计重试机制和降级方案在Spring中我用ControllerAdvice统一处理异常ExceptionHandler(BusinessException.class) public ResponseEntityErrorResult handleBusinessEx(BusinessException ex) { ErrorResult error new ErrorResult(ex.getCode(), ex.getMessage()); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error); } ExceptionHandler(Exception.class) public ResponseEntityErrorResult handleUnexpectedEx(Exception ex) { log.error(System error, ex); ErrorResult error new ErrorResult(500, 系统繁忙请稍后再试); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error); }对于微信支付等第三方调用一定要设置合理的超时时间和重试策略。我通常用Spring Retry来实现Retryable(value WeChatPayException.class, maxAttempts 3, backoff Backoff(delay 1000, multiplier 2)) public void callWeChatPay() { // 支付调用逻辑 }8. 监控与报警体系建设系统上线只是开始运维监控才是持久战。我搭建的监控体系包括业务指标订单量、支付成功率等系统指标CPU、内存、磁盘等中间件Redis命中率、MySQL慢查询使用PrometheusGrafana的方案关键配置如下# Prometheus配置示例 scrape_configs: - job_name: spring metrics_path: /actuator/prometheus static_configs: - targets: [localhost:8080]对于报警规则我建议遵循三个黄金指标错误率超过1%立即报警响应时间P99大于1秒需要关注吞吐量突然下降50%可能是故障前兆日志收集用的是ELK栈特别要注意日志格式统一。我定义的日志模板%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n9. 持续集成与交付项目后期我引入了完整的CI/CD流程。每次代码提交都会自动触发单元测试必须全部通过SonarQube代码质量检查Docker镜像构建测试环境部署GitLab CI的配置文件大概长这样stages: - test - build - deploy unit-test: stage: test script: - mvn test docker-build: stage: build script: - docker build -t sky-take-out . deploy-test: stage: deploy script: - kubectl apply -f k8s/deployment.yaml这套流程让我们的发布效率提升了70%以上。有个小技巧在Dockerfile中使用多阶段构建既能减小镜像体积又能保证安全性FROM maven:3.8-jdk-11 AS build COPY . . RUN mvn package FROM openjdk:11-jre-slim COPY --frombuild /target/sky-take-out.jar /app.jar ENTRYPOINT [java,-jar,/app.jar]10. 项目复盘与经验总结做完《苍穹外卖》这个项目最大的收获不是技术上的而是对工程思维的培养。有几个深刻体会文档的重要性初期偷懒没写文档后期联调时各种沟通成本爆炸接口设计原则坚持单一职责参数不超过3个代码评审文化好的CR能发现80%的潜在问题给后来者的建议数据库设计阶段多花点时间好的表结构能省去后期大量重构。我的检查清单包括是否有适当的索引字段类型是否合理是否考虑了分库分表可能性是否有完善的注释最后分享一个性能优化的小故事有次排查接口超时发现是MyBatis的日志级别设为DEBUG导致。所以记住生产环境一定要用INFO及以上级别。

相关文章:

《苍穹外卖》实战:从零到一构建高并发外卖系统核心笔记

1. 公共字段自动填充的工程化实践 第一次看到《苍穹外卖》项目里那些重复出现的创建人、创建时间、修改人、修改时间字段时,我就意识到这绝对是个需要优化的地方。每个实体类都手动维护这些字段,不仅容易出错,后期维护更是噩梦。好在Spring A…...

别再只做图像识别了!真正赚钱的多模态边缘场景正在爆发——3个已规模化商用的工业质检/远程医疗/智能座舱案例深度解密

第一章:多模态大模型边缘智能应用的产业拐点与技术范式跃迁 2026奇点智能技术大会(https://ml-summit.org) 全球AI基础设施正经历从“云中心密集推理”向“端—边—云协同认知”的历史性位移。多模态大模型(如Llama-3-Vision、Qwen2-VL、Phi-4-Multimo…...

如何管理Oracle服务器的内核共享内存_shmmax与shmall计算

shmmax需≥SGA最大值(如sga_max_size)并留10%余量,shmall需≥所有实例SGA总和4096;RAC环境还需额外考虑GRD开销且各节点独立计算;修改后须sysctl -p生效、验证ipcs -lm、重启listener与数据库。shmmax 设置多少才够用&…...

Hermes Agent 集成实践:从协议到生产

Hermes Agent 集成实践:从协议到生产分享 HagiCode 集成 Hermes Agent 的完整实践,包括 ACP 协议适配、会话池管理、前后端契约同步等核心经验。背景在构建 AI 辅助编码平台 HagiCode 的过程中,团队需要集成一个既能在本地运行又能扩展到云端…...

Java的java.lang.ModuleLayer依赖分析

Java模块化系统自Java 9引入以来,为开发者提供了更强大的依赖管理能力。其中,java.lang.ModuleLayer作为模块化架构的核心组件,允许动态创建层次化的模块依赖关系,为复杂应用的分层部署和隔离提供了可能。本文将深入分析ModuleLay…...

ENSP模拟器外网访问全攻略:从环境搭建到成功ping通8.8.8.8

ENSP模拟器外网访问实战指南:从零搭建到稳定连通 网络工程师和IT技术人员经常需要在隔离环境中测试网络设备的连通性,华为ENSP模拟器提供了完美的解决方案。但让模拟器中的设备访问真实外网却是一个充满技术细节的过程。本文将带你一步步突破虚拟与现实的…...

Mac NTFS读写终极指南:免费开源工具Nigate让你的硬盘自由飞翔

Mac NTFS读写终极指南:免费开源工具Nigate让你的硬盘自由飞翔 【免费下载链接】Free-NTFS-for-Mac Nigate: An open-source NTFS utility for Mac. It supports all Mac models (Intel and Apple Silicon), providing full read-write access, mounting, and manage…...

技术问题的解决思路与创新方法应用

技术问题的解决思路与创新方法应用 在快速发展的科技领域,技术问题的解决不仅依赖于传统经验,更需要创新思维和方法的应用。无论是软件开发、硬件设计,还是跨学科的技术整合,高效的解决思路往往能事半功倍。本文将围绕技术问题的…...

终极指南:使用ncmdump轻松解密网易云音乐NCM文件

终极指南:使用ncmdump轻松解密网易云音乐NCM文件 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否曾经下载了网易云音乐的NCM格式歌曲,却发现无法在其他播放器上播放?ncmdump就是你的救星&am…...

【多模态模型解释权威指南】:SITS2026核心演讲深度解码——3大不可忽视的认知盲区与5步可落地的XAI实践框架

第一章:SITS2026多模态模型解释演讲全景概览 2026奇点智能技术大会(https://ml-summit.org) SITS2026是面向下一代可信AI系统构建的旗舰级多模态模型解释框架,聚焦视觉-语言-时序信号三模态联合归因与可验证推理。该框架在2026奇点智能技术大会上首次完…...

AMD-GAIA开源框架-本地AI智能体

AMD GAIA开源框架:把AI智能体关在你自己的电脑里不联网的AI,才是真正属于你的AI 4月13日,AMD悄然发布了一个可能改变端侧AI格局的开源项目——GAIA。它做的事情听起来简单:让你在本地电脑上运行一个完整的AI智能体,不需…...

紧急预警:2024年已发现11起多模态生成偏见致商业合规风险事件!附欧盟AI Act第10条适配自查清单与72小时应急响应模板

第一章:多模态大模型偏见检测与消除 2026奇点智能技术大会(https://ml-summit.org) 多模态大模型在图像理解、语音生成与跨模态推理任务中展现出强大能力,但其训练数据固有的社会性偏差常被放大并编码为系统性偏见——例如在职业关联图像生成中强化性别…...

智能客服进入“感知智能”分水岭(SITS2026已验证):3个月内未升级多模态能力的团队,将面临首波客户流失预警

第一章:SITS2026案例:智能客服多模态应用 2026奇点智能技术大会(https://ml-summit.org) SITS2026(Smart Interactive Technical Support 2026)是面向金融与电信行业落地的智能客服标杆项目,其核心突破在于构建端到端…...

工业质检进入“感知觉醒”时代:激光雷达+高光谱+Transformer三模态融合方案首次披露,仅限大会VIP通道获取

第一章:工业质检进入“感知觉醒”时代:激光雷达高光谱Transformer三模态融合方案首次披露,仅限大会VIP通道获取 2026奇点智能技术大会(https://ml-summit.org) 传统工业质检长期受限于单一成像维度与静态特征建模能力,难以应对微…...

35岁后端程序员必看!转型AI大模型应用开发,收藏这份抄作业指南,少走弯路!

文章针对35岁后端程序员,分析转型AI大模型应用开发的必要性及优势,强调工程经验的重要性。文章提供转型四阶段计划及避坑指南,建议在职学习,聚焦RAG/Agent赛道,掌握LangChain等框架。强调后端技能与AI结合是未来稀缺优…...

SITS2026多模态评测集深度解析(业界首份全栈评估框架白皮书)

第一章:SITS2026发布:多模态大模型评测集 2026奇点智能技术大会(https://ml-summit.org) SITS2026(Singularity Intelligence Test Suite 2026)是面向下一代多模态大模型的综合性基准评测集,由全球32家研究机构联合构…...

告别Init.d!用Magisk实现安卓开机自启动的3个实战场景(含批量部署脚本)

告别Init.d!用Magisk实现安卓开机自启动的3个实战场景(含批量部署脚本) 在安卓设备管理中,开机自启动功能一直是开发者与企业用户的核心需求之一。无论是安全监控、自动化测试还是后台服务保活,能否在系统启动时可靠执…...

别再手动画圈了!用高德猎鹰服务API+Postman,5分钟搞定电子围栏(附完整请求参数)

高德猎鹰服务API实战:5分钟构建智能电子围栏系统 在物流追踪、共享设备管理和人员定位等场景中,电子围栏技术正成为空间智能化的核心组件。传统管理后台的手动绘制方式不仅效率低下,更难以应对批量操作需求。本文将展示如何通过高德猎鹰服务…...

基于LDAP与AES加密的企业级登录认证方案实践

1. 企业级登录认证的挑战与解决方案 在企业级应用开发中,登录认证系统往往面临多重挑战。特别是当系统需要同时支持内部员工和外协人员访问时,如何确保安全性、统一性和易用性就成为了关键问题。我最近参与的一个金融项目就遇到了这样的场景:…...

游戏开发者必看:如何用蒙特卡洛光线追踪提升你的3A级游戏画质(附Unity/Unreal实战代码)

游戏开发者必看:如何用蒙特卡洛光线追踪提升你的3A级游戏画质(附Unity/Unreal实战代码) 当玩家打开一款3A级游戏时,最先吸引他们的往往是逼真的光影效果——阳光透过树叶的斑驳投影、金属表面细腻的环境反射、雾气中自然的光线散射…...

从一次应急响应看致远OA wpsAssistServlet漏洞:攻击者如何利用,我们又该如何溯源与加固?

企业级致远OA安全事件深度剖析:从漏洞利用到防御体系构建 凌晨3点17分,安全运维工程师小李的手机突然响起刺耳的告警声——公司核心业务区的致远OA服务器触发了异常文件上传行为告警。当他远程连接到安全分析平台时,发现攻击者已经通过wpsAss…...

LEYBOLD SOGEVAC SV40BI真空泵

Leybold SOGEVAC SV40BI真空泵是一款油润滑旋片式真空泵,属于工业级粗真空获得设备,广泛用于实验室、半导体工艺、真空镀膜及工业生产设备中,用于建立稳定的低至中真空环境。中间特点:采用单级或双级油封旋片结构,实现…...

从B+到C+++:手把手教你根据传输距离选对GPON光模块(附实战配置案例)

从B到C:手把手教你根据传输距离选对GPON光模块(附实战配置案例) 光纤到户(FTTH)的普及让GPON技术成为宽带接入网的主流选择。作为一名经常需要部署OLT设备的工程师,我深刻体会到光模块选型对网络质量的影响…...

Cursor AI破解免费VIP终极完整指南:如何绕过试用限制享受Pro功能

Cursor AI破解免费VIP终极完整指南:如何绕过试用限制享受Pro功能 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reache…...

Leybold Inficon 850-400-G1真空计控制器

Leybold 与 INFICON 相关的 850-400-G1 真空计控制器,是用于真空系统监测与控制的重要仪表单元,主要用于配合多种真空规管,实现对低真空到高真空范围的精确测量与系统控制。中间特点:适用于多种真空传感器(如电离规、皮…...

告别传统采集卡!用Xilinx Zynq UltraScale+ RFSoC XCZU47DR搭建你的6GHz以下软件无线电实验平台

6GHz以下软件无线电革命:基于Xilinx RFSoC的下一代射频实验平台设计指南 在无线通信和信号处理领域,实验室里的射频工程师们常常面临一个两难选择——要么使用价格高昂的商业软件无线电设备(如USRP),要么自行搭建复杂的…...

AMD FirePro™ S7150 X2 虚拟显卡在虚拟化环境中的性能优化与配置技巧

1. AMD FirePro™ S7150 X2 虚拟显卡深度解析 第一次接触这块双芯显卡时,我正为某企业的虚拟化桌面项目选型。当时测试机房里堆满了各种显卡,但S7150 X2独特的被动散热设计立刻吸引了我的注意——这个265W功耗的大家伙居然完全依赖服务器风道散热&#x…...

嘉立创MSPM0G3507移植MPU6050避坑实录:初始化卡死、OLED无显示的三种排查与解决

嘉立创MSPM0G3507移植MPU6050实战避坑指南:从初始化卡死到数据采集的深度解决方案 第一次将MPU6050运动传感器移植到嘉立创MSPM0G3507开发板时,我遇到了三个令人抓狂的问题:初始化卡死、OLED屏幕一片漆黑、数据读取不稳定。经过72小时的反复调…...

鲁班猫系统镜像备份与迁移实战:用1张SD卡搞定多设备系统克隆(附镜像瘦身技巧)

鲁班猫系统镜像备份与迁移实战:用1张SD卡搞定多设备系统克隆(附镜像瘦身技巧) 当你在实验室同时维护五台鲁班猫开发板时,最崩溃的瞬间莫过于每次系统升级都要重复下载镜像、烧录SD卡的全过程。去年我在部署智能家居中控集群时&…...

告别野火SDK工具链:用系统自带gcc-aarch64搞定RK3588 LVGL移植,实测更稳定

告别野火SDK工具链:用系统自带gcc-aarch64搞定RK3588 LVGL移植,实测更稳定 在嵌入式开发领域,交叉编译工具链的选择往往决定了项目的成败。对于RK3588这样的高性能ARM平台,开发者常面临一个关键抉择:是使用厂商提供的S…...