架构说明
# 相关知识点
## 秒杀为什么独立一个微服务?
> 假设秒杀不独立一个微服务, 而与其他微服务耦合, 会有一个非常严重的问题
> **即秒杀的并发量通常都是10K+的, 即秒杀的并发量很大, 如果耦合了其他微服务, 会造成连坐现象, 即该微服务不仅有秒杀的压力, 也有其他功能的压力, 导致该微服务会导致压力过大, 所在的功能全部失效**
> **如果秒杀独立成一个微服务, 最坏的情况下, 只会影响到秒杀不可以, 其他功能仍然可用**
> <font color='red'>**可以这样理解, 秒杀独立成一个微服务, 目的是让巨量并发为了不影响其他功能, 只影响自己, 具有贡献精神**</font>
## 秒杀商品为什么存储到Redis?
> **因为秒杀是一个并发程度非常高的场景, 如果存储到数据库, 想象百万并发同时访问数据库, 数据库很容易崩溃, 更可能级联更亏, 因此, 秒杀商品不适合存储到数据库**
> **由于Redis的特性可知, Redis读写效率都很高, 非常适合做秒杀商品的存储**
## 为什么每天凌晨上架商品?
> **首先明确一点, 每天秒杀的东西都不同, 所以, 秒杀的商品需要定时上架, 为了让用户得到最好的体验, 我们需要在服务器资源占用最少的时候上架商品, 这就是为什么凌晨上架商品**
## 定时任务的相关知识
### corn表达式
#### 基础语法
```cron
秒 分 时 日(一个月里面的第几天) 月 周(一周里面的第几题那) 年
```

##### 注意
> **在传统的`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` 表示每个月的第二个星期二执行一次
#### 示例

## 定时任务为什么设置成异步?
> **因为, 有可能有些定时任务非常的耗费资源, 执行起来非常的慢, 假设有一个corn表达式`* */3 * * * ?`, 每个3秒需要执行一次, 但是这个定时任务需要耗费6秒, 那么真正执行起来, 下一个任务实际需要等待9秒才能执行**
> **这会出现一个很离谱的现象, 原本计划1个小时的任务可能变成3-4个消失才能完成, 资源利用不充分的同时, 很可能影响到用户体验, 因此需要异步执行, 不可用同步执行**
### 解决方案
#### 方案1
> 可以使用手动的异步编排, 即使用`CompletableFuture`对代码进行异步编排, 这种异步编排非常的稳健, 但是每次写代码都用手动的异步编排, 非常的麻烦, 不建议使用
#### 方案2


> `TaskSchedulingAutoConfiguration`是定时任务的自动配置类, 由上图可知, 该自动配置类的默认线程池的大小是1, 因此, 默认情况下, 执行的是同步执行, 但是, 我们把线程池的大小改变就可以异步执行了, 但是, 实测该操作并没有效果
#### 方案3
```java
@EnableAsync // 激活异步任务
@EnableScheduling
public class ScheduleConfig {
}
```
```yaml
task:
execution:
pool:
core-size: 20
max-size: 100
```

> 这是@EnableAsync的自动配置类, 我们可以通过改变里面的配置, 从而改变线程池的大小, 从而自定义异步执行
> **这个使用起来很方便, 而且支持自定义线程池, 推荐使用**