Distributed flash sale solution--java

Prerequisite: first cache the product details and flash sale products in redis to reduce access to the database (scheduled tasks can be used).
Flash sale products are nothing more than those few steps (there may be some judgments in front, such as whether the user is logged in, one order per person, flash sale Time verification, etc.)
1 One person, one order
2. Determine inventory
3. Reduce inventory
4. Create order

What problem needs to be solved for flash sale?

1. Solve the oversold problem

1.1 This flash sale will definitely be oversold, so it must be locked. There are only two types of locks, optimistic locks and pessimistic locks.
Pessimistic lock: Just lock before 1. The reentrant lock in redisson is used here.

        // 获取分布式锁对象
        RLock lock = redissonClient.getLock("seckillLock");
        try {
    
    
            //等待5秒获取锁,执行60秒还是没有释放锁就强制释放
            boolean b = lock.tryLock(5L, 60L, TimeUnit.SECONDS);
            if (b){
    
    
               SeckillProductVo  seckillProductVo = seckillProductService.find(time, seckillId);
                //1.保证库存足够
                if (seckillProductVo.getStockCount()<=0){
    
    
                    return Result.error(SeckillCodeMsg.SECKILL_STOCK_OVER);
                }
              //下面两个方法必须写在一起避免事务未提交,未扣减库存就释放锁
            //2.扣减库存
            //3.生成订单
                orderInfo=orderInfoService.doSeckill(phone,seckillProductVo);
            }
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            lock.unlock();
        }

1.2 Optimistic locking: There is no need to use code to demonstrate this
1. One person, one order
2. Determine inventory
3. Reduce inventory
4. Create order

When reducing inventory in 3. mysql statement and inventory > 0, MySQL will have its own row lock. So only one modification operation will be performed at a time. Neither of the above two methods will cause oversold
, but they fail to solve the flash sale problem. The reason is that high concurrent requests enter the database to check the database, which will cause the database to crash or block the execution of other mysql.

2. How to solve the problem of repeated orders?

2.1 After creating the order in 4., store the user's unique identification, id or phone in the redis set key->{phone1,phone2}
redisTemplate.opsForSet().isMember(orderKey,phone) returns true or false and
the process becomes 1. One person, one order 2. Determine inventory 3. Reduce inventory 4. Create order 5. redisTemplate.opsForSet().add(orderKey,phone);

2.2 However, this does not completely solve the problem of repeated orders, for example, the user clicks on two requests at the same time. Under extreme conditions, the judgment of thread a to enter step 1 requires a lot of operations from 1 to 4. When thread a does not reach step 5, thread b comes in, which will also cause repeated orders. Therefore, the unique index of the database must be used to solve the problem. The unique index of the user's unique identifier and the unique identifier of the flash sale product can be solved. That is, an
Insert image description here
error will appear when creating an order in 4. After the inventory is reduced in 3, the data can be rolled back.
However, the inventory in redis is different from the database, and redis cannot be rolled back. Cannal will be used later to synchronize the database and redis inventory. . .
Some people may say that 2.1 does not solve the duplication problem, why not just use 2.2 to solve it? 2.1 can be solved in most cases and avoids the pressure on the data caused by someone clicking the flash kill multiple times, so using 2.1 and 2.2 together is the best choice.

3. Flow control
3.1 The request must be intercepted outside the database. If there are only 10 stocks, only 10 threads can finally reach the database, which is an ideal solution. Therefore, the
flash sale product inventory of the database is stored in redis for pre-sale. , only the -1 operation can be performed in redis to enter the service, which greatly reduces the number of requests to the service layer.

3.2 If there are multiple products in the same flash sale time period, such as 100 flash sale products, and the inventory of each flash sale product is 10, then 10*100 requests will arrive in the database. If it is Taobao's Double 11, obviously the flash sale products will More. Then we need to perform peak clipping control of traffic.
Insert image description here
Intercept messages from the controller. When the service gets the messages, it takes it slowly. MQ can take some time to store some of the requests in it and queue them for processing. The service takes them according to its own processing capabilities. Some people may say that queue processing is not very slow? After sending the message in the controller, the request is considered to be over, and the user will not see the purchase result immediately. passing behind
Insert image description here

Insert image description here
The final proposal
Insert image description here

おすすめ

転載: blog.csdn.net/qq_56533553/article/details/132693585