高并发解决方案
1、Redis分布式锁,缺点同一时刻只能有一个人进入;优化方案库存分段来增强并发数。
// 释放锁
public static void unlock(String key, String value) {
StringRedisTemplate stringRedisTemplate = SpringContextHolder.getApplicationContext()
.getBean(StringRedisTemplate.class);
String currentValue = stringRedisTemplate.opsForValue().get(key);
if (value.equals(currentValue)) {
stringRedisTemplate.delete(key);
}
}
将当前数据锁定,使其他用户无法访问
public static boolean lock(String key, String value, long second) {
StringRedisTemplate stringRedisTemplate = SpringContextHolder.getApplicationContext()
.getBean(StringRedisTemplate.class);
if (stringRedisTemplate.opsForValue().setIfAbsent(key, value)) {
stringRedisTemplate.expire(key, second, TimeUnit.SECONDS);// 设置过期时间
return true;
}
return false;
}
2、Redis预存库存数据, 主要通过自增来判断库存数量是否充足,通过Redis的单线程的特性来控制,再有MQ队列来进行同步数据。
3、MySQL 数据库查询存入的数据的小于等于当前ID的下单数量总和 来控制库存(ID 为自增)。
利用mysql 的方式 是先把数据存入 数据库,在通过查询小于等于当前id 的数量总和,来看是否订单是否有效,如果超出库存就设为无效订单,返回库存不足。
注意:注意事务的干扰
count = select sum(1) from tab where user_id = $ and ID <= $
4、并发时用队列来进行排队(先进先出)特性来处理,主要是通过MQ来异步处理数据,这种一般适合那种在添加数据时候产生的并发,不适合及时返回的情况。
5、利用数据库本身的行锁特性, 修改的时候并发可以用sql 语句 update set a = a+ 1 wher id =$ 的方式。
6、并发如果是要求及时返回结果可以用 redis + lua 来处理高并发,而且还可以融入mq
这种方式将数据存入Redis中,由lua语言来操作Redis,lua脚本语言操作redis具有原子性,不会被其他线程打断,所有关于redis的操作在一个lua脚本有事务特性。
7、令牌,漏桶
高并发的解决思路
一般的思考方向:缓存、分流、隔离、限流