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

苍穹外卖项目笔记day08

在苍穹外卖中,我们对于一些没有及时处理的异常订单,应定时自动去处理,因此我们这里便引入了Spring Task

同时,也可以用它与websocke结合来完成客户下单与催单的提醒功能

Spring Task

Spring Task 是Spring框架提供的任务调度工具,可以按照约定的时间自动执行某个代码逻辑。

只要在需要定时处理的场景都可以使用@Autowired
private WebSocketServer webSocketServer;
/**
* 支付成功,修改订单状态
*
* @param outTradeNo
*/
public void paySuccess(String outTradeNo) {
// 当前登录用户id
Long userId = BaseContext.getCurrentId();

    // 根据订单号查询当前用户的订单Orders ordersDB = orderMapper.getByNumberAndUserId(outTradeNo, userId);// 根据订单id更新订单的状态、支付方式、支付状态、结账时间Orders orders = Orders.builder().id(ordersDB.getId()).status(Orders.TO_BE_CONFIRMED).payStatus(Orders.PAID).checkoutTime(LocalDateTime.now()).build();orderMapper.update(orders);//////////////////////////////////////////////Map map = new HashMap();map.put("type", 1);//消息类型,1表示来单提醒map.put("orderId", orders.getId());map.put("content", "订单号:" + outTradeNo);//通过WebSocket实现来单提醒,向客户端浏览器推送消息webSocketServer.sendToAllClient(JSON.toJSONString(map));///////////////////////////////////////////////////
}

定位:定时任务框架

作用:定时自动执行某段Java代码

场景:信用卡还款信息,贷款还款消息,待支付消息等

cron表达式

cron表达式其实就是一个字符串,通过cron表达式可以定义任务触发的时间

构成规则:分为6或7个域,由空格分隔开,每个域代表一个含义

每个域的含义分别为:秒、分钟、小时、日、月、周、年(可选)

而且一般的值不同时设置,其中一个设置,另一个用?表示。

cron并不需要我们专门去研究怎么写,直接使用这个生成器

在线Cron表达式生成器

使用步骤
  1. 导入依赖

但是这个依赖特别小,小到连自己的实体都没有,它属于是spring context中的一个附属依赖,而在spring boot依赖中就已经包含了spring context这个依赖,因此并不需要额外添加


<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>版本号</version>
</dependency>
  1. 启动类添加注解 @EnableScheduling 开启任务调度
  2. 自定义定时任务类

代码实现也非常简单,只需要添加 @Scheduled(cron = “”)这个注释

	/*** 处理支付超时订单*/@Scheduled(cron = "0 * * * * ?")public void processTimeoutOrder(){log.info("处理支付超时订单:{}", new Date());LocalDateTime time = LocalDateTime.now().plusMinutes(-15);// select * from orders where status = 1 and order_time < 当前时间-15分钟List<Orders> ordersList = orderMapper.getByStatusAndOrdertimeLT(Orders.PENDING_PAYMENT, time);if(ordersList != null && ordersList.size() > 0){ordersList.forEach(order -> {order.setStatus(Orders.CANCELLED);order.setCancelReason("支付超时,自动取消");order.setCancelTime(LocalDateTime.now());orderMapper.update(order);});}}

设置定时任务确实可以解决异常订单,但是如果我们设置一秒一次,虽然可以,但是大量查询数据库会造成性能问题,因此定时任务的核心在于:如何高效率的设置任务

WebSocket

WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接, 并进行双向数据传输。HTTP协议和WebSocket协议对比:

  • HTTP是短连接
  • WebSocket是长连接
  • HTTP通信是单向的,基于请求响应模式
  • WebSocket支持双向通信
  • HTTP和WebSocket底层都是TCP连接

WebSocket缺点:

服务器长期维护长连接需要一定的成本各个浏览器支持程度不一WebSocket 是长连接,受网络限制比较大,需要处理好重连

结论:WebSocket并不能完全取代HTTP,它只适合在特定的场景下使用

WebSocket应用场景:

1). 视频弹幕

2). 在线聊天、实时数据监控、多人游戏、协同编辑等

实现步骤:

1). 直接使用websocket.html页面作为WebSocket客户端

2). 导入WebSocket的maven坐标

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

3). 导入WebSocket服务端组件WebSocketServer,用于和客户端通信

4). 导入配置类WebSocketConfiguration,注册WebSocket的服务端组件

5). 导入定时任务类WebSocketTask,定时向客户端推送数据

代码实现:

package com.sky.websocket;import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;/*** WebSocket服务*/
@Component
@ServerEndpoint("/ws/{sid}")
public class WebSocketServer {//存放会话对象private static Map<String, Session> sessionMap = new HashMap();/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session, @PathParam("sid") String sid) {System.out.println("客户端:" + sid + "建立连接");sessionMap.put(sid, session);}/*** 收到客户端消息后调用的方法** @param message 客户端发送过来的消息*/@OnMessagepublic void onMessage(String message, @PathParam("sid") String sid) {System.out.println("收到来自客户端:" + sid + "的信息:" + message);}/*** 连接关闭调用的方法** @param sid*/@OnClosepublic void onClose(@PathParam("sid") String sid) {System.out.println("连接断开:" + sid);sessionMap.remove(sid);}/*** 群发** @param message*/public void sendToAllClient(String message) {Collection<Session> sessions = sessionMap.values();for (Session session : sessions) {try {//服务器向客户端发送消息session.getBasicRemote().sendText(message);} catch (Exception e) {e.printStackTrace();}}}}
package com.sky.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** WebSocket配置类,用于注册WebSocket的Bean*/
@Configuration
public class WebSocketConfiguration {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}
	@Autowiredprivate WebSocketServer webSocketServer;/*** 支付成功,修改订单状态** @param outTradeNo*/public void paySuccess(String outTradeNo) {// 当前登录用户idLong userId = BaseContext.getCurrentId();// 根据订单号查询当前用户的订单Orders ordersDB = orderMapper.getByNumberAndUserId(outTradeNo, userId);// 根据订单id更新订单的状态、支付方式、支付状态、结账时间Orders orders = Orders.builder().id(ordersDB.getId()).status(Orders.TO_BE_CONFIRMED).payStatus(Orders.PAID).checkoutTime(LocalDateTime.now()).build();orderMapper.update(orders);Map map = new HashMap();map.put("type", 1);//消息类型,1表示来单提醒map.put("orderId", orders.getId());map.put("content", "订单号:" + outTradeNo);//通过WebSocket实现来单提醒,向客户端浏览器推送消息webSocketServer.sendToAllClient(JSON.toJSONString(map));}


文章转载自:

http://EnPstvY5.wjLhp.cn
http://N2lpUyTP.wjLhp.cn
http://JYjxJlxE.wjLhp.cn
http://J4Q3fIGQ.wjLhp.cn
http://jgY1dfEm.wjLhp.cn
http://Yn8sEQUA.wjLhp.cn
http://sq8tIdAo.wjLhp.cn
http://AflARkyS.wjLhp.cn
http://F2ljwPr4.wjLhp.cn
http://T6JuLa8I.wjLhp.cn
http://Rh3GLavu.wjLhp.cn
http://WF0EvlGp.wjLhp.cn
http://r5I4b4S2.wjLhp.cn
http://ypYxAiKp.wjLhp.cn
http://rlPxO5Zb.wjLhp.cn
http://ENRDiMvJ.wjLhp.cn
http://WDwbwlP3.wjLhp.cn
http://lUofW8Te.wjLhp.cn
http://zWAmzKFd.wjLhp.cn
http://domX4nKY.wjLhp.cn
http://MvMSxW9a.wjLhp.cn
http://lFSxiWTL.wjLhp.cn
http://7sZbhLKG.wjLhp.cn
http://AfEcLnf0.wjLhp.cn
http://QDAcS0ja.wjLhp.cn
http://Y0hEUdSU.wjLhp.cn
http://TScBMvtJ.wjLhp.cn
http://4Hwn4xfx.wjLhp.cn
http://j5D4IEwn.wjLhp.cn
http://6Jl7N9Sg.wjLhp.cn
http://www.dtcms.com/a/379887.html

相关文章:

  • 智能逗猫球方案MCU控制方案浅析-智能宠物玩具,宠物解闷神器
  • Unity键盘控制角色运动
  • 大数据毕业设计-基于Spark的全国高速公路实时路况融合与拥堵预测系统(高分计算机毕业设计选题·定制开发·真正大数据)
  • zmq源码分析之session
  • Xcode 上传 ipa 全流程详解 App Store 上架流程、uni-app 生成 ipa 文件上传与审核指南
  • Java 泛型详解:从基础到高级应用
  • 第6.2节 Android Agent开发<二>
  • ubuntu挂载新硬盘的方法
  • Kubernetes Ingress:使用 Apache APISIX 进行外部流量路由
  • 初学者如何选择适合的云平台进行AIGC训练?
  • Docker存储卷(Volume)完全指南:从入门到精通
  • STM32-FreeRTOS操作系统-二值信号量与计数信号量
  • 蒸面器/蒸脸仪方案开发,蒸面器/蒸脸仪MCU控制方案分析
  • 容器技术崛起:从PaaS到Docker的变革探问
  • 如何定位Mysql慢查询和短而频的查询
  • 机器学习的基本流程:从数据到模型
  • springboot rabbitmq 消息队列入门与实战
  • 使用vllm部署neo4j的text2cypher-gemma-2-9b-it-finetuned-2024v1模型
  • 栈-844.比较含退格的字符串-力扣(LeetCode)
  • [Dify] HTTP 请求节点详解:如何在 Dify 中配置与调用第三方 API
  • SQL优化简单思路
  • 构建AI智能体:三十一、AI医疗场景实践:医学知识精准问答+临床智能辅助决策CDSS
  • HTTP的Web服务测试在Python中的实现
  • 华为HCIE-云计算培训课程有哪些?
  • 绕过 FlashAttention-2 限制:在 Turing 架构上使用 PyTorch 实现 FlashAttention
  • 美食分享|基于Springboot和vue的地方美食分享网站系统设计与实现(源码+数据库+文档)
  • 华为HICE云计算的含金量高吗?
  • 【算法--链表】146.LRU缓存--通俗讲解
  • 5 绑定表
  • 记录一次利用arthas和skywalking做接口性能优化的全过程