基本概念
一、高并发的相关概念:
- PV:综合浏览量,即页面浏览量和点击量,如果一个系统的日PV在千万级以上,那么我们称这个系统为高并发系统。
- QPS:每秒响应的请求数。
- 响应时间:从请求发出到收到响应的时间。
- 吞吐量:单位时间里处理的请求数量。
如何实现一个系统的高并发或者说提高一个系统的并发量呢?
- 扩容
扩容分为水平扩容和垂直扩容。水平扩容就是增加机器数量,怼机器。垂直扩容就是增加单机处理能力,怼硬件。 - 提高接口并发能力
- 缓存
- 动静分离
动静分离是说,动态页面和静态页面分开不同的软件架构设计方法。 - 服务降级(业务高峰期,为了保证核心业务,需要停掉一些不太重要的业务)
- 限流(限制系统 的流量)
高并发三把利器:缓存,限流,降级。
二、库存售罄问题优化
如果库存已经售罄,那么后续的大流量会对数据库产生不必要的压力。这里就可以使用redis在库存售罄之后打一个标记,我们可以通过这个标记再去判断是否可以进行秒杀下单。
三、流量削峰技术
- 验证码技术
- 限流算法
- 令牌桶算法
- 漏桶算法
- 队列泄洪
- 原理:
本质:排队策略
排队有时候比并发更加高效(Redis单线程模型)
依靠排队去限制并发流量
依靠排队和限制下游拥塞窗口的程度调整队列释放流量的大小 - 目的:保护下游系统涌入流量,提高下游系统的可用性。
- 代码实现
线程池
四、令牌桶实例
- 导包
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.2-jre</version>
</dependency>
- 代码
//引用类
@Autowired
private RateLimiter rateLimiter;
@PostConstruct
public void init(){
//初始化工具类表示每秒生成100个令牌
rateLimiter = RateLimiter.create(100);
}
//然后只需要在请求里执行下面的方法即可
rateLimiter.acquire();
五、队列泄洪线程池实现
//声明一个线程池
private ExecutorService executorService;
@PostConstruct
public void init(){
//初始化工具类表示每秒生成100个令牌
rateLimiter = RateLimiter.create(100);
//创建一个固定大小的线程池
executorService = Executors.newFixedThreadPool(100);
//创建一个 只有一个线程的线程池
//executorService = Executors.newSingleThreadExecutor();
//创建一个缓存线程池
//executorService = Executors.newCachedThreadPool();
//创建一个执行定期任务的线程池
//executorService = Executors.newScheduledThreadPool();
}
Future<CreatePromoOrderResponse> future = executorService.submit(new Callable<CreatePromoOrderResponse>() {
@Override
public CreatePromoOrderResponse call() throws Exception {
CreatePromoOrderResponse createPromoOrderResponse = promoService.createPromoOrderInTransaction(createPromoOrderRequest);
return createPromoOrderResponse;
}
});
//获取执行的结果
CreatePromoOrderResponse createPromoOrderResponse = future.get();