A simple seckill system based on redis implemented by laravel

Keywords: Redis Laravel PHP PhpStorm

Note: there are many articles about redis seckill system on the Internet. They are all confused. Then they can realize one by themselves, which is also convenient for later study

The implementation method is to use the list queue of redis, and the framework is laravel

The core part is the pop operation of list. As atomicity, even if many users arrive at the same time, it is executed in turn

 

Example:

<?php
/**
 * Created by PhpStorm.
 * User: chenyRain
 * Date: 2018/5/28
 * Time: 11:36
 */

namespace App\Http\Controllers;


use Illuminate\Support\Facades\Redis;

class RedisController extends Controller
{
    public $user_number = 50; // Number of people allowed to enter the queue

    /**
     * This method is equivalent to clicking into the product details page to start the seckill activity
     */
    public function index()
    {
        $goods_number = 10; // The quantity of goods in stock is 10

        if (! empty(Redis::llen('goods_name'))) {
            echo 'Inventory has been set up';
            exit;
        }

        // initialization
        Redis::command('del', ['user_number', 'success']);

        // Deposit goods redis In the list
        for ($i = 1; $i <= $goods_number; $i++) {

            // lpush Add elements from the head of the list
            Redis::lpush('goods_name', $i);
        }

        // Set expiration time
        $this->setTime();

        // Return to linked list goods_name Length of
        echo 'Goods are successfully put into the queue. Quantity:'.Redis::llen('goods_name');
    }

    public function setTime()
    {
        // Set up goods_name Expiration time, equivalent to activity time
        Redis::expire('goods_name', 120);
    }


    /**
     * This method is equivalent to the click to buy operation
     */
    public function start()
    {
        $uid = mt_rand(1, 99); // Hypothetical users ID

        // If the number of people exceeds 50, it will directly indicate that they have been robbed
        if (Redis::llen('user_number') > $this->user_number) {
            echo 'Sorry, it's been robbed';
            exit;
        }

        // Get results,Suppose it's in there uid
        $result = Redis::lrange('success', 0, 20);
        // If a user can only rob once, add the following judgment
        if (in_array($uid, $result)) {
            echo 'You've robbed it';
            exit;
        }

        // Queue users
        Redis::lpush('user_number', $uid);

        // Delete an element from the head of the list and return the deleted element,because pop Operations are atomic, and even if many users arrive at the same time, they are executed in turn
        $count = Redis::lpop('goods_name');
        if (! $count) {
            echo 'Robbed';
            exit;
        }

        $msg = 'Captured by:'.$uid.',commodity ID For:'.$count;
        Redis::lpush('success', $msg);
        echo 'The company plans to steal it';
    }

    /**
     * View the results
     */
    public function result()
    {
        $result = Redis::lrange('success', 0, 20);
        dd($result);
    }
}

Explain:

1. First run index method to set commodity inventory, and initialize result queue and user queue

2. Run the start method to rush to buy

Add ab test results below

Attach the list of people who have been caught

Posted by cuboidgraphix on Mon, 20 Apr 2020 10:27:27 -0700