架构说明

# 相关知识点 ## 秒杀为什么独立一个微服务? > 假设秒杀不独立一个微服务, 而与其他微服务耦合, 会有一个非常严重的问题 > **即秒杀的并发量通常都是10K+的, 即秒杀的并发量很大, 如果耦合了其他微服务, 会造成连坐现象, 即该微服务不仅有秒杀的压力, 也有其他功能的压力, 导致该微服务会导致压力过大, 所在的功能全部失效** > **如果秒杀独立成一个微服务, 最坏的情况下, 只会影响到秒杀不可以, 其他功能仍然可用** > <font color='red'>**可以这样理解, 秒杀独立成一个微服务, 目的是让巨量并发为了不影响其他功能, 只影响自己, 具有贡献精神**</font> ## 秒杀商品为什么存储到Redis? > **因为秒杀是一个并发程度非常高的场景, 如果存储到数据库, 想象百万并发同时访问数据库, 数据库很容易崩溃, 更可能级联更亏, 因此, 秒杀商品不适合存储到数据库** > **由于Redis的特性可知, Redis读写效率都很高, 非常适合做秒杀商品的存储** ## 为什么每天凌晨上架商品? > **首先明确一点, 每天秒杀的东西都不同, 所以, 秒杀的商品需要定时上架, 为了让用户得到最好的体验, 我们需要在服务器资源占用最少的时候上架商品, 这就是为什么凌晨上架商品** ## 定时任务的相关知识 ### corn表达式 #### 基础语法 ```cron 秒 分 时 日(一个月里面的第几天) 月 周(一周里面的第几题那) 年 ``` ![image.png](https://cos.easydoc.net/13568421/files/lmn9jlqk.png) ##### 注意 > **在传统的`corn`表达式中, 是支持7位的, 但是, 在Springboot环境下, 是不支持年的** > **另外, corn表示星期几的数字在Springboot表示也有所不同, corn从星期日开始, 而在springboot中从星期一开始** #### 语法详解 1. `,`: 表示枚举, 或的关系 `"1,2,3 * * * * ?"` 第1或2或3秒都会执行这个任务 2. `-`: 表示范围, 表示这个时间段内每秒执行一次这个任务 `"1-10 * * * * ?"` 第1-10秒之间, 每秒执行一次这个任务 3. `*`: 表示任意, 即任意时刻都会执行这个任务 `* * * * * ?` 表示无时无刻都执行这个任务 4. `/`: 表示步长, 表示一个步长后执行这个任务 `*/5 * * * * ?` 表示任意时刻开始, 每隔5秒执行一次 5. `?`: 表示占位, 一个月的第几天, 一个星期的第几天, 这两个容易发生冲突, 如果用一个表示时, 另一个用`?`占位 `* * * 1 * ?` 或 `* * * ? * 2` 6. `L`: 表示最后一个 `* * * ? * 3L` 表示每个月的最后一个星期二执行一次 7. `W`: 表示工作日 `* * * W * ?` 表示每个月的工作日都会执行一次 8. `#`: 表示第几个 `* * * ? * 3#2` 表示每个月的第二个星期二执行一次 #### 示例 ![image.png](https://cos.easydoc.net/13568421/files/lmnenuf8.png) ## 定时任务为什么设置成异步? > **因为, 有可能有些定时任务非常的耗费资源, 执行起来非常的慢, 假设有一个corn表达式`* */3 * * * ?`, 每个3秒需要执行一次, 但是这个定时任务需要耗费6秒, 那么真正执行起来, 下一个任务实际需要等待9秒才能执行** > **这会出现一个很离谱的现象, 原本计划1个小时的任务可能变成3-4个消失才能完成, 资源利用不充分的同时, 很可能影响到用户体验, 因此需要异步执行, 不可用同步执行** ### 解决方案 #### 方案1 > 可以使用手动的异步编排, 即使用`CompletableFuture`对代码进行异步编排, 这种异步编排非常的稳健, 但是每次写代码都用手动的异步编排, 非常的麻烦, 不建议使用 #### 方案2 ![image.png](https://cos.easydoc.net/13568421/files/lmngvm3z.png) ![image.png](https://cos.easydoc.net/13568421/files/lmngvtgv.png) > `TaskSchedulingAutoConfiguration`是定时任务的自动配置类, 由上图可知, 该自动配置类的默认线程池的大小是1, 因此, 默认情况下, 执行的是同步执行, 但是, 我们把线程池的大小改变就可以异步执行了, 但是, 实测该操作并没有效果 #### 方案3 ```java @EnableAsync // 激活异步任务 @EnableScheduling public class ScheduleConfig { } ``` ```yaml task: execution: pool: core-size: 20 max-size: 100 ``` ![image.png](https://cos.easydoc.net/13568421/files/lmnh0px8.png) > 这是@EnableAsync的自动配置类, 我们可以通过改变里面的配置, 从而改变线程池的大小, 从而自定义异步执行 > **这个使用起来很方便, 而且支持自定义线程池, 推荐使用**