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