网站怎么提升实用性/短视频培训机构

网站怎么提升实用性,短视频培训机构,建设彩票网站制作,品牌建设网秒杀系统流程图 秒杀系统关键点 高并发处理: 使用网关(如 Nginx)进行流量限流,避免过载。分布式锁或 Redis 原子操作控制并发。 活动状态检查: Redis 存储活动状态(如 seckill:activity:1:status),快速…

秒杀系统流程图

在这里插入图片描述

秒杀系统关键点

  1. 高并发处理:
  • 使用网关(如 Nginx)进行流量限流,避免过载。
  • 分布式锁或 Redis 原子操作控制并发。
  1. 活动状态检查:
  • Redis 存储活动状态(如 seckill:activity:1:status),快速判断活动是否进行中。
  1. 用户资格校验:
  • Redis Set 记录参与用户(如 seckill:activity:1:users),检查是否重复参与。
  • 示例: SADD seckill:activity:1:users user123 和 SISMEMBER。
  1. 库存扣减(Redis Lua 脚本):
  • 为什么用 Lua 脚本?
    • 保证原子性,避免并发超卖。
    • 减少网络往返,提高性能。
  • Redis Key: seckill:activity:1:stock(库存)。
  • Lua 脚本示例:
local stock_key = KEYS[1]
local current_stock = tonumber(redis.call('GET', stock_key) or 0)
if current_stock <= 0 thenreturn -1  -- 库存不足
end
redis.call('DECR', stock_key)
return current_stock - 1  -- 返回剩余库存
  • Java 调用 Lua 脚本(Spring Boot + Redis):
@Autowired
private StringRedisTemplate redisTemplate;public boolean deductStock(String activityId) {String stockKey = "seckill:activity:" + activityId + ":stock";String script = "local stock_key = KEYS[1] " +"local current_stock = tonumber(redis.call('GET', stock_key) or 0) " +"if current_stock <= 0 then return -1 end " +"redis.call('DECR', stock_key) " +"return current_stock - 1";Long result = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class),Collections.singletonList(stockKey));return result != null && result >= 0;
}
  1. 订单生成:
  • 异步队列(如 RabbitMQ、Kafka)处理订单生成,减轻数据库压力。
  • 示例: 将 {userId, activityId, timestamp} 发送到队列。
  1. 数据库写入:
  • 异步任务消费队列,批量插入订单到 MySQL。
  • 避免实时写库导致瓶颈。
  1. 防超卖:
  • Redis Lua 脚本确保库存不减为负。
  • 数据库加乐观锁(如 UPDATE stock SET count = count - 1 WHERE id = ? AND count > 0)。
  1. 返回响应:
  • 扣减成功后立即返回“秒杀成功”,后续操作异步完成。

完整流程伪代码

@RestController
public class SeckillController {@Autowiredprivate StringRedisTemplate redisTemplate;@Autowiredprivate RabbitTemplate rabbitTemplate;@PostMapping("/seckill/{activityId}")public String seckill(@PathVariable String activityId, @RequestParam String userId) {// 1. 检查活动状态String status = redisTemplate.opsForValue().get("seckill:activity:" + activityId + ":status");if (!"ongoing".equals(status)) {return "活动未开始或已结束";}// 2. 检查用户资格if (redisTemplate.opsForSet().isMember("seckill:activity:" + activityId + ":users", userId)) {return "已参与秒杀";}// 3. 扣减库存 (Lua 脚本)if (!deductStock(activityId)) {return "库存不足";}// 4. 标记用户参与redisTemplate.opsForSet().add("seckill:activity:" + activityId + ":users", userId);// 5. 异步生成订单rabbitTemplate.convertAndSend("seckill-queue", new OrderMessage(userId, activityId, System.currentTimeMillis()));return "秒杀成功";}
}

补充:

redis减扣后 减扣 MySQL 库存方案

1. 异步减扣 MySQL 库存(推荐)

  • 时机
    • Redis 减库存成功后,将任务发送到异步队列(如 RabbitMQ、Kafka),由后台消费者异步更新 MySQL 库存。
  • 流程
    1. 用户发起秒杀请求。
    2. Redis Lua 脚本扣减库存(原子操作)。
    3. 扣减成功后:
      • 发送消息到队列(如 {activityId, userId, timestamp})。
      • 返回“秒杀成功”给前端。
    4. 队列消费者异步处理:
      • 更新 MySQL 库存表。
      • 生成订单记录。
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private RabbitTemplate rabbitTemplate;@PostMapping("/seckill/{activityId}")
public String seckill(@PathVariable String activityId, @RequestParam String userId) {// Redis 减库存if (!deductStock(activityId)) {return "库存不足";}// 异步更新 MySQLrabbitTemplate.convertAndSend("seckill-queue", new OrderMessage(activityId, userId, System.currentTimeMillis()));return "秒杀成功";
}// Lua 脚本扣库存
private boolean deductStock(String activityId) {String stockKey = "seckill:stock:" + activityId;String script = "local stock = tonumber(redis.call('GET', KEYS[1]) or 0) " +"if stock <= 0 then return 0 end " +"redis.call('DECR', KEYS[1]) " +"return 1";Long result = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class),Collections.singletonList(stockKey));return result != null && result == 1;
}// 队列消费者
@Component
@RabbitListener(queues = "seckill-queue")
public class SeckillConsumer {@Autowiredprivate JdbcTemplate jdbcTemplate;@RabbitHandlerpublic void process(OrderMessage msg) {// 更新 MySQL 库存String sql = "UPDATE seckill_stock SET stock = stock - 1 WHERE activity_id = ? AND stock > 0";int updated = jdbcTemplate.update(sql, msg.getActivityId());if (updated > 0) {// 插入订单jdbcTemplate.update("INSERT INTO seckill_order (activity_id, user_id, create_time) VALUES (?, ?, ?)",msg.getActivityId(), msg.getUserId(), msg.getTimestamp());}}
}
优点
  • 高性能: Redis 减库存后立即返回,MySQL 异步处理,避免实时写库瓶颈。
  • 高并发: 适合秒杀场景,减少数据库压力。
缺点
  • 数据一致性: Redis 和 MySQL 可能短暂不一致(最终一致性)。
  • 失败处理: 队列消费失败需重试或补偿。
  • 适用场景
  • 高并发秒杀,优先保证响应速度。

2. 同步减扣 MySQL 库存

  • 时机
    • Redis 减库存成功后,在同一事务中同步更新 MySQL 库存。
  • 流程
    1. 用户发起秒杀请求。
    2. Redis Lua 脚本扣减库存。
    3. 扣减成功后:
    4. 立即更新 MySQL 库存。
    5. 生成订单。
    6. 返回“秒杀成功”。
@PostMapping("/seckill/{activityId}")
@Transactional
public String seckill(@PathVariable String activityId, @RequestParam String userId) {// Redis 减库存if (!deductStock(activityId)) {return "库存不足";}// 同步更新 MySQLint updated = jdbcTemplate.update("UPDATE seckill_stock SET stock = stock - 1 WHERE activity_id = ? AND stock > 0",activityId);if (updated == 0) {// 回滚 Redis(可选)redisTemplate.opsForValue().increment("seckill:stock:" + activityId);return "库存不足";}// 插入订单jdbcTemplate.update("INSERT INTO seckill_order (activity_id, user_id, create_time) VALUES (?, ?, ?)",activityId, userId, System.currentTimeMillis());return "秒杀成功";
}
优点
  • 强一致性: Redis 和 MySQL 库存保持同步。
  • 简单: 无需异步队列。
缺点
  • 性能瓶颈: MySQL 写操作耗时,影响并发能力。
  • 回滚复杂: 如果 MySQL 更新失败,需回滚 Redis。
  • 适用场景
  • 低并发场景,或对数据一致性要求极高。

3. 延迟减扣 MySQL 库存(定时同步)

  • 时机
    • Redis 减库存后,通过定时任务(如每分钟)批量同步 MySQL 库存。
  • 流程
    1. Redis 减库存。
    2. 记录每次扣减的日志(如 Redis List seckill:stock:log)。
    3. 定时任务读取日志,批量更新 MySQL。
  • 实现示例
// 秒杀接口
@PostMapping("/seckill/{activityId}")
public String seckill(@PathVariable String activityId, @RequestParam String userId) {if (!deductStock(activityId)) {return "库存不足";}// 记录日志redisTemplate.opsForList().leftPush("seckill:stock:log", activityId + "," + userId + "," + System.currentTimeMillis());return "秒杀成功";
}// 定时任务
@Component
@EnableScheduling
public class StockSyncTask {@Autowiredprivate StringRedisTemplate redisTemplate;@Autowiredprivate JdbcTemplate jdbcTemplate;@Scheduled(fixedRate = 60000) // 每分钟public void syncStock() {List<String> logs = redisTemplate.opsForList().range("seckill:stock:log", 0, -1);if (logs != null && !logs.isEmpty()) {Map<String, Integer> stockUpdates = new HashMap<>();for (String log : logs) {String[] parts = log.split(",");String activityId = parts[0];stockUpdates.merge(activityId, 1, Integer::sum);}// 批量更新 MySQLfor (Map.Entry<String, Integer> entry : stockUpdates.entrySet()) {jdbcTemplate.update("UPDATE seckill_stock SET stock = stock - ? WHERE activity_id = ?",entry.getValue(), entry.getKey());}redisTemplate.opsForList().trim("seckill:stock:log", logs.size(), -1); // 清空已处理日志}}
}
优点
  • 性能优化: 批量处理,减少 MySQL 频繁写。
  • 容错: 日志记录便于排查。
缺点
  • 一致性延迟: MySQL 库存更新有延迟。
  • 复杂性: 需维护日志和定时任务。
  • 适用场景
  • 中等并发,允许短暂不一致。

选择依据

方案MySQL减库存时机一致性性能复杂度适用场景
异步减扣Redis 后异步队列最终一致高并发秒杀
同步减扣Redis 后立即同步强一致低并发强一致性
延迟减扣Redis 后定时批量延迟一致中等并发可接受延迟

推荐方案

  • 高并发秒杀: 采用异步减扣。
    • Redis 负责实时库存控制,MySQL 异步更新。
    • 通过队列解耦,确保高吞吐量。
  • 关键点:
    • Redis Lua 脚本保证原子性。
    • 异步任务失败时,需重试或补偿(如记录失败日志)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/73481.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【js逆向入门】图灵爬虫练习平台 第九题

地址&#xff1a;aHR0cHM6Ly9zdHUudHVsaW5ncHl0b24uY24vcHJvYmxlbS1kZXRhaWwvOS8 f12进入了debugger&#xff0c;右击选择一律不在此处暂停&#xff0c; 点击继续执行 查看请求信息 查看载荷&#xff0c;2个加密参数&#xff0c;m和tt 查看启动器&#xff0c;打上断点 进来 往…

Vue中的状态管理器Vuex被Pinia所替代-上手使用指南

Pinia.js 是新一代的状态管理器&#xff0c;由 Vue.js团队中成员所开发的&#xff0c;因此也被认为是下一代的 Vuex&#xff0c;即 Vuex5.x&#xff0c;在 Vue3.0 的项目中使用也是备受推崇 Pinia.js 有如下特点&#xff1a; 完整的 typescript 的支持&#xff1b;足够轻量&…

向量数据库学习笔记(1) —— 基础概念

一、 嵌入模型 Embedding Models 嵌入模型是将复杂数据&#xff08;如文本、图像、音频等&#xff09;转换为向量表示的机器学习模型 1. 核心概念 嵌入(Embedding)&#xff1a;将高维、非结构化的数据映射到低维、稠密的向量空间 向量表示&#xff1a;输出固定长度的数值向量…

[NO-WX179]基于springboot+微信小程序的在线选课系统

[NO-WX179]基于springboot微信小程序的在线选课系统 1、管理员角色&#xff08;web端&#xff09;&#xff1a;2、教师角色&#xff08;web端&#xff09;&#xff1a;3、用户角色&#xff08;小程序或web端&#xff09;&#xff1a;4、部分运行截图管理端--教师管理管理端--学…

2025年渗透测试面试题总结-某 长亭(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 长亭 一、Spring SpEL表达式注入漏洞 1. 技术原理 2. 利用条件 3. 攻击方法 4. 防御策略 二、Jav…

conda环境下解决gitk乱码模糊

关键词 conda、git、gitk、git gui、模糊、linux、乱码 现象 操作系统&#xff1a;ubuntu24.04 conda版本&#xff1a;25.1.1 正常的终端里gitk显示不会模糊 但是在conda创建的python虚拟环境中使用gitk&#xff0c;字体开始变得模糊不清 分析 根据deepseek的原因原因分析…

【C++项目实战】:基于正倒排索引的Boost搜索引擎(1)

1. 项目的相关背景与目标 针对boost网站没有搜索导航功能&#xff0c;为boost网站文档的查找提供搜索功能 站内搜索&#xff1a;搜索的数据更垂直&#xff0c;数据量小 类似于cplusplus.com的搜索 2.搜索引擎的相关宏观原理 3.技术栈和项目环境 技术栈&#xff1a;C/C&am…

深入理解指针(1)(C语言版)

文章目录 前言一、内存和地址1.1 内存1.2 究竟该如何理解编址 二、指针变量和地址2.1 取地址操作符&2.2 指针变量和解引用操作符*2.2.1 指针变量2.2.2 如何拆解指针类型2.2.3 解引用操作符 2.3 指针变量的大小 三、指针变量类型的意义3.1 指针的解引用3.2 指针-整数3.3 voi…

第一天学爬虫

阅读提示&#xff1a;我今天才开始尝试爬虫&#xff0c;写的不好请见谅。 一、准备工具 requests库&#xff1a;发送HTTP请求并获取网页内容。BeautifulSoup库&#xff1a;解析HTML页面并提取数据。pandas库&#xff1a;保存抓取到的数据到CSV文件中。 二、爬取步骤 发送请求…

重学Java基础篇—线程池参数优化指南

一、核心参数解析 线程池&#xff08;ThreadPoolExecutor&#xff09;的性能取决于以下关键参数&#xff1a; 参数说明corePoolSize核心线程数&#xff0c;即使空闲也不会被回收maximumPoolSize最大线程数&#xff0c;当队列满且核心线程忙时创建新线程workQueue任务队列&…

记一次线上环境JAR冲突导致程序报错org.springframework.web.util.NestedServletException

一、问题描述 有个文件导入功能&#xff0c;用到了Hutool 的加密解密功能&#xff0c;本地运行完全可以&#xff0c;但是线上报错&#xff1a;“org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFou…

2.基于多线程的TCP服务器实现

目录 1. 简单分析之前的代码 2. 多线程服务器设计 2.1 C11线程的基本使用 2.2 服务器主体逻辑 3. 错误处理的封装 4. 完整的代码实现 客户端代码&#xff08;client.cpp&#xff09; 服务器代码&#xff08;server.cpp&#xff09; 5. 运行方式 在我们预想中&#xff…

从零构建大语言模型全栈开发指南:第二部分:模型架构设计与实现-2.2.3实战案例:在笔记本电脑上运行轻量级LLM

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 实战案例:在笔记本电脑上运行轻量级LLM2.2.3 模型架构设计与实现1. 环境与工具准备1.1 硬件要求1.2 软件栈选择2. 轻量级模型架构设计2.1 模型参数配置2.2 关键技术优化3. 实战流程3.1 数据准备流程3.2…

工业软件的破局与重构:从技术依赖到自主创新的未来路径

工业软件作为现代工业的“神经与大脑”&#xff0c;不仅是制造业数字化转型的核心工具&#xff0c;更是国家工业竞争力的战略制高点。近年来&#xff0c;中国工业软件市场在政策驱动与技术迭代中迅猛发展&#xff0c;但核心技术受制于人的困境仍待突破。如何实现从“跟跑”到“…

歌曲缓存相关功能

1. 核心组件 MusicCacheManager (音乐缓存管理器) 单例模式&#xff1a;确保全局只有一个实例&#xff0c;方便管理。 private static var instance: MusicCacheManager?static func shared() -> MusicCacheManager {if instance nil {instance MusicCacheManager()}ret…

阿里开源的免费数据集成工具——DataX

企业里真实的数据流转是什么样子的呢&#xff1f; 左侧描述了一个企业真实的样子&#xff0c;我们总是需要把数据从一个地方搬到另一个地方&#xff0c;最后就是搬来搬去搬成了一张张解不开的网。 右侧则表达了使用DataX为中心实现数据的同步。 什么是DataX DataX是一个异构…

26考研——图_图的遍历(6)

408答疑 文章目录 三、图的遍历图的遍历概述图的遍历算法的重要性图的遍历与树的遍历的区别图的遍历过程中的注意事项避免重复访问遍历算法的分类遍历结果的不唯一性 广度优先搜索广度优先搜索&#xff08;BFS&#xff09;概述BFS 的特点广度优先遍历的过程示例图遍历过程 BFS …

前端解决方案:实现网页截图并导出PDF功能

前端解决方案&#xff1a;实现网页截图并导出PDF功能 在前端开发中&#xff0c;我们经常会遇到需要将网页内容导出为PDF的需求。本文将以一个准考证预览和导出的例子&#xff0c;带你一步步实现这个功能。我们会处理包括跨域图片、Canvas绘图、PDF生成等多个技术要点。 一、基…

【MySQL】表操作

表操作 一、创建表 1、语句2、语句介绍3、注意事项4、介绍5、示例 二、查看表结构 1、语句2、介绍3、返回的信息4、示例 三、添加字段 1、语句2、语句介绍3、示例 四、修改 1、语句2、语句介绍3、示例 五、删除 1、语句2、示例 六、修改表名 1、语句2、语句介绍3、示例 七、删…

响应“一机两用”政策 ,实现政务外网安全

在数字化办公的浪潮下&#xff0c;企业与政务机构面临着既要保障数据安全&#xff0c;又要高效访问互联网的双重需求。“一机两用”成为解决这一难题的关键。 政策驱动&#xff0c;需求迫切 随着《网络安全法》《数据安全法》等法律法规的相继出台&#xff0c;网络安全防护的要…