苍穹外卖笔记Day09Day101. SpringTask 定时任务苍穹外卖实战1.1 基本概念SpringTask 是Spring 框架原生自带的定时任务工具无需整合 Quartz 等第三方中间件轻量、简单、开箱即用专门用于处理苍穹外卖中「周期性、定时执行」的业务场景无需手动触发自动按配置时间执行。1.2 核心作用苍穹外卖实战场景定时清理定时清理过期未支付订单如 30 分钟未支付自动取消、清理过期优惠券、清理日志数据定时统计每日凌晨统计前一天的订单量、营业额、用户新增数量生成运营报表定时同步定时同步商品库存、同步用户积分、同步配送状态定时提醒定时提醒商家处理待接单订单、提醒配送员取餐。1.3 核心注解必背面试高频1EnableScheduling作用开启 SpringTask 定时任务功能必须加在SpringBoot 启动类或配置类上否则定时任务不生效。苍穹外卖实战示例启动类SpringBootApplicationEnableScheduling// 开启定时任务publicclassSkyApplication{publicstaticvoidmain(String[]args){SpringApplication.run(SkyApplication.class,args);}}2Scheduled作用标记在「要定时执行的方法」上指定任务的执行时间、频率。方法要求无参数、无返回值void否则定时任务会报错。苍穹外卖实战示例定时取消过期订单ServicepublicclassOrderServiceImplimplementsOrderService{// 定时执行每1分钟检查一次取消30分钟未支付的订单Scheduled(cron0 */1 * * * ?)publicvoidcancelExpiredOrder(){// 业务逻辑查询30分钟未支付、未取消的订单执行取消操作ListOrderexpiredOrdersorderMapper.selectExpiredUnpaidOrders();for(Orderorder:expiredOrders){order.setStatus(OrderStatus.CANCELLED);order.setCancelReason(订单超时未支付自动取消);orderMapper.update(order);}}}1.4 Scheduled 三大执行方式面试重点区分清楚1fixedRate固定频率执行不推荐用于苍穹外卖核心场景核心逻辑从上一次任务开始执行的时间计算每隔指定时间执行一次无论上一次任务是否执行完毕。示例Scheduled(fixedRate 5000)→ 每 5 秒执行一次即使上一次任务执行了 3 秒下一次也会在第 5 秒准时启动。缺点如果任务执行时间超过设定频率会导致任务堆积占用线程资源苍穹外卖中很少使用除非是轻量、快速执行的任务。2fixedDelay固定间隔执行苍穹外卖常用核心逻辑从上一次任务执行结束的时间计算等待指定时间后再执行下一次任务避免任务堆积。示例Scheduled(fixedDelay 5000)→ 上一次任务执行完后等待 5 秒再执行下一次。适用场景苍穹外卖中耗时较短的定时任务如每 10 分钟同步一次库存。3cron 表达式精准定时最常用、面试必问核心逻辑通过表达式精准控制任务的执行时间支持秒、分、时、日、月、周、年功能最强大适配苍穹外卖中所有复杂定时场景。语法7个字段空格分隔秒 分 时 日 月 周 年可选通配符说明面试常考*匹配所有值如秒位写 *表示每秒执行?仅用于「日」和「周」表示不指定值避免日和周冲突/表示递增如 0/5 * * * * ? → 每 5 秒执行一次-表示范围如 0 0 9-18 * * ? → 每天 9 点到 18 点整点执行,表示多个值如 0 0 12,18 * * ? → 每天 12 点、18 点各执行一次。苍穹外卖常用 Cron 示例面试必背0 0 2 * * ?→ 每天凌晨 2 点执行日志清理、报表统计0 */1 * * * ?→ 每 1 分钟检查过期订单0 0 0 * * ?→ 每天凌晨 0 点重置当日数据统计0 0 12 * * ?→ 每天中午 12 点推送当日订单统计给商家。1.5 SpringTask 执行机制面试高频坑点1默认机制SpringTask 默认是单线程执行所有定时任务共用一个线程如果一个任务执行时间过长如清理大量日志耗时 5 分钟会导致其他定时任务延迟执行甚至卡死。2多线程配置生产环境必须配置苍穹外卖实战解决单线程阻塞问题配置线程池让不同任务在不同线程中执行互不影响。配置类代码面试可直接写ConfigurationEnableSchedulingpublicclassScheduledConfigimplementsSchedulingConfigurer{// 配置线程池核心线程数根据任务数量调整苍穹外卖建议5-10个OverridepublicvoidconfigureTasks(ScheduledTaskRegistrartaskRegistrar){taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));}}面试考点为什么要配置多线程答避免单线程任务阻塞保证所有定时任务按时执行提升系统稳定性。1.6 面试高频问题结合苍穹外卖苍穹外卖中SpringTask 用在哪些场景答清理过期订单、统计报表、同步库存、定时提醒EnableScheduling 和 Scheduled 的作用分别是什么答前者开启定时任务功能后者标记定时方法fixedRate 和 fixedDelay 的区别答前者从任务开始计时后者从任务结束计时后者避免堆积SpringTask 默认是单线程还是多线程如何优化答默认单线程配置线程池优化写出一个“每天凌晨 2 点执行”的 Cron 表达式答0 0 2 * * ?。2. WebSocket 详细讲解苍穹外卖实战2.1 基本概念WebSocket 是一种全双工、双向通信的网络协议基于 TCP 连接允许客户端浏览器/APP和服务器之间建立持久连接实现「实时通信」—— 服务器可以主动向客户端推送消息客户端也可以主动向服务器发送消息无需客户端频繁发起请求区别于 HTTP 单向通信。2.2 核心作用区别于 HTTP面试重点HTTP 协议是「请求-响应」模式客户端发起请求服务器才会返回响应服务器无法主动向客户端推送消息WebSocket 协议是「持久连接」模式连接建立后双方可随时互发消息实时性极高无需频繁请求减少网络开销。2.3 苍穹外卖实战场景除了实时提醒新订单1核心场景1新订单实时提醒基础商家端用户下单后服务器通过 WebSocket 实时向商家推送新订单消息无需商家刷新页面配送端商家接单后实时向配送员推送待取餐订单同步订单地址、取餐时间。2核心场景2订单状态实时同步高频用户端用户下单后实时同步订单状态待接单 → 待配送 → 配送中 → 已完成无需刷新页面商家端实时同步订单支付状态未支付 → 已支付、取消状态及时处理订单。3核心场景3实时聊天苍穹外卖增值功能用户与商家聊天用户咨询菜品、修改订单商家实时回复用户与配送员聊天用户询问配送进度配送员实时反馈。4核心场景4库存实时更新秒杀/热销场景商家端热销菜品库存不足时实时推送库存预警如“番茄炒蛋库存仅剩5份”用户端用户下单时实时推送库存变化如“库存不足无法下单”。5核心场景5实时通知运营/系统通知商家端平台推送活动通知如“周末满减活动开启”、违规提醒、系统维护通知配送端推送配送范围调整、配送费调整通知用户端推送优惠券到账、会员权益更新、订单评价提醒。6核心场景6实时数据统计商家后台商家端实时查看当日订单量、营业额、接单率数据随订单变化实时更新无需手动刷新报表。2.4 WebSocket 核心原理面试必背握手阶段客户端发起 HTTP 请求请求头中携带Upgrade: websocket表示要升级为 WebSocket 协议连接建立服务器响应同意升级双方建立持久 TCP 连接后续通信不再使用 HTTP 协议数据传输连接建立后客户端和服务器可通过帧Frame互发消息支持文本、二进制数据连接关闭客户端或服务器主动发送关闭帧释放连接。2.5 苍穹外卖 WebSocket 核心实现简化版面试可写1引入依赖SpringBoot 整合 WebSocketdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-websocket/artifactId/dependency2配置类开启 WebSocket 支持ConfigurationpublicclassWebSocketConfig{BeanpublicServerEndpointExporterserverEndpointExporter(){// 注册 WebSocket 端点开启 WebSocket 支持returnnewServerEndpointExporter();}}3WebSocket 核心服务类处理连接、消息推送// 端点路径ws://localhost:8080/ws/order/{merchantId}商家端按商家ID区分连接ServerEndpoint(/ws/order/{merchantId})ComponentpublicclassOrderWebSocketServer{// 存储商家ID与对应的WebSocket连接key商家IDvalue连接对象privatestaticMapLong,SessionsessionMapnewConcurrentHashMap();// 连接建立时执行商家打开后台页面建立连接OnOpenpublicvoidonOpen(Sessionsession,PathParam(merchantId)LongmerchantId){sessionMap.put(merchantId,session);}// 连接关闭时执行商家关闭页面释放连接OnClosepublicvoidonClose(PathParam(merchantId)LongmerchantId){sessionMap.remove(merchantId);}// 接收客户端消息商家发送消息给服务器OnMessagepublicvoidonMessage(Stringmessage,PathParam(merchantId)LongmerchantId){// 处理商家消息如确认接单、拒绝订单System.out.println(收到商家merchantId的消息message);}// 核心方法服务器向指定商家推送消息如新订单提醒publicvoidsendMessage(LongmerchantId,Stringmessage){SessionsessionsessionMap.get(merchantId);if(session!nullsession.isOpen()){try{session.getBasicRemote().sendText(message);}catch(IOExceptione){e.printStackTrace();}}}}4业务层调用推送新订单消息ServicepublicclassOrderServiceImplimplementsOrderService{AutowiredprivateOrderWebSocketServerwebSocketServer;// 下单成功后向商家推送新订单消息OverridepublicvoidcreateOrder(OrderDTOorderDTO){// 1. 生成订单、入库等业务逻辑...// 2. 向对应商家推送新订单消息LongmerchantIdorderDTO.getMerchantId();Stringmessage您有新订单请及时处理订单号orderDTO.getOrderNumber();webSocketServer.sendMessage(merchantId,message);}}2.6 面试高频问题结合苍穹外卖WebSocket 和 HTTP 的区别答HTTP 单向请求-响应无法主动推送WebSocket 双向全双工持久连接实时性高减少请求开销苍穹外卖中WebSocket 除了新订单提醒还有哪些用途答订单状态同步、实时聊天、库存预警、实时通知、数据统计WebSocket 连接建立的过程答客户端发起 HTTP 升级请求 → 服务器响应升级 → 建立 TCP 持久连接如何保证 WebSocket 连接的稳定性答心跳检测、重连机制、异常关闭时释放连接苍穹外卖中如何区分不同商家的 WebSocket 连接答通过商家ID作为key存储连接对象推送消息时根据商家ID定位连接。3. 总结面试重点SpringTaskSpring 原生定时工具核心注解 EnableScheduling Scheduled三大执行方式fixedRate、fixedDelay、cron必须配置多线程避免阻塞苍穹外卖主要用于定时清理、统计、同步任务WebSocket双向实时通信协议核心是持久连接苍穹外卖除新订单提醒还用于订单状态同步、实时聊天、库存预警等场景核心实现是端点配置 连接管理 消息推送两者关联SpringTask 可定时触发 WebSocket 消息推送如每天中午推送订单统计共同支撑苍穹外卖的定时、实时业务需求。