美文网首页
laravel 礼品码高并发多种实现方法

laravel 礼品码高并发多种实现方法

作者: 云逐梦 | 来源:发表于2019-05-29 15:47 被阅读0次

高并发实现礼品码抢购功能方法如下:

一、通过update更新语句会把并发串行化功能实现,通过了压力测试的高并发处理

        (假如这N个用户同时到达update这里,这个时候update更新语句会把并发串行化,也就是给同时到达这里的是N个用户排个序,一个一个执行,并生成排他锁)

 二、laravel+Redis简单实现队列通过了压力测试的高并发处理

            1.先用redis将1000个礼品码缓存

            2.然后用redis setnx判断用户key是否已经存在,存在则返回该用户已经参加了,否则继续

            3.判断礼品码个数,礼品码没有超出预设

            4.更新该礼品码数据用户uid和status状态

不多说,直接上代码:

namespace App\Http\Controllers;

use App\Giftcode;

use Illuminate\Http\Request;

use Illuminate\Routing\Route;

use Illuminate\Support\Facades\DB;

use Illuminate\Support\Facades\Log;

use Illuminate\Support\Facades\Redis;

use Illuminate\Support\Facades\Storage;

use PHPUnit\Framework\Exception;

class GiftcodeController extends Controller

{

/**

* yun1121.com:方法一:

* http://www.xxx.com/api/show1/2

*

* 通过update完成高并发更新

* (假如这N个用户同时到达update这里,这个时候update更新语句会把并发串行化,也就是给同时到达这里的是N个用户排个序,一个一个执行,并生成排他锁)

*

* id为主键  更改主键id为一个唯一的键值,更新时如果主键重复则用try catch 将错误catch 最后返回给用户礼品码

*

* ab高并发压力测试语句如下:

* ab -n 100  -c 100 -p 'post.txt' -T 'application/x-www-form-urlencoded' 'http://www.xxx.com/api/show1/27'

*

* @param $uid

* @return \Illuminate\Database\Eloquent\Model|null|object|string|static

*/

public function show1($uid)

{

try{

$row = DB::update("Update giftcodes set id=:id,status=1,uid=:uid where status=0 and uid is null limit 1 ",['id'=>$uid+10000,'uid'=>$uid]);

Log::info('uid:', ['msg'=>'抢购','uid'=>$uid]);

}catch (\Exception $e){

$row = 0;

Log::info('uid:', ['msg'=>'抢购失败','uid'=>$uid]);

}

if($row){

$gc_data =  DB::table('giftcodes')->where(['id'=> $uid+10000])->first();

$gc_data =  (array)$gc_data;

return $gc_data['gift_code'];

}else{

return 'fail';

}

}

/**

* yun1121.com:方法二:

* http://www.xxx.com/api/show2/2

*

* 1.先用redis将1000个礼品码缓存

* 2.然后用redis setnx判断用户key是否已经存在,存在则返回该用户已经参加了,否则继续

* 3.判断礼品码个数,礼品码没有超出预设

* 4.更新该礼品码数据用户uid和status状态

*

* ab高并发压力测试语句如下:

* ab -n 100  -c 100 -p 'post.txt' -T 'application/x-www-form-urlencoded' 'http://www.xxx.com/api/show2/27'

*

* @param $uid

* @return string

*/

public function show2($uid)

{

$isqueue = Redis::setnx('userqueue_'.$uid,$uid);

if(!$isqueue){

Log::info('uid:', ['msg'=>'您已抢购','uid'=>$uid]);

return '您已抢购';

}

Log::info('uid:', ['uid'=>$uid]);

$giftcode = Redis::rpop('giftcodeslist');

if(!$giftcode){

Log::info('uid:', ['msg'=>'已经购空','uid'=>$uid]);

return '已经购空';

}

try{

$row = DB::table('giftcodes')

->where('gift_code',"{$giftcode}")

->update(['uid'=>$uid,'status'=> 1]);

if($row){

Log::info('uid:', ['msg'=>'抢购成功','uid'=>$uid,'giftcode'=>$giftcode]);

return $giftcode;

}else{

Redis::del('userqueue_'.$uid);

Redis::lpush('giftcodeslist',$giftcode);

return 'update fail';

}

}catch (\Exception $e){

Redis::del('userqueue_'.$uid,1);

Log::info('uid:', ['msg'=>'抢购失败','uid'=>$uid]);

Redis::lpush('giftcodeslist',$giftcode);

return 'fail';

}

}

/**

* yun1121.com:将礼品码预设到缓存中

* @return string

*/

public function giftcodeQueue()

{

Redis::del('giftcodeslist');

$giftcode_list = DB::table('giftcodes')->where(['status'=> 0])->get()->toArray();

if($giftcode_list){

foreach ($giftcode_list as $key=>$val){

$val = (array)$val;

Redis::lpush('giftcodeslist',$val['gift_code']);

}

}

return '目前码数:'.Redis::llen('giftcodeslist');

}

}

        以上代码通过高并发测试成功!

ab -n 100  -c 100 -p 'post.txt' -T 'application/x-www-form-urlencoded' 'http://www.xxx.com/api/show1/27'

        欢迎大家讨论提供更多的实现方法!

尊重原创,转载请注明来源 http://www.yun1121.com/study/view/id/175 云逐梦

相关文章

网友评论

      本文标题:laravel 礼品码高并发多种实现方法

      本文链接:https://www.haomeiwen.com/subject/ixuytctx.html