使用node基于redis的setnx实现秒杀

express基于nodejs的web快速开发框架;视图模板引擎使用twitter的hogan.js

使用express构建整个项目

npm install hogan.js --save
express --view=hogan expressdemo1

创建的目录结构:

接着进入项目目录:npm install

然后运行:SET DEBUG=expressdemo1:* & npm start

实战项目

使用express的generator生成秒杀项目,这里主要利用redis的setnx锁来实现不能秒超,能抗高并发(当然这个方案有些缺点,但是能够满足我们当前的业务需求)

这里贴出seckill.js的代码

var express = require('express');
var router = express.Router();
var client = require('redis').createClient(6379, 'Host');
var client3 = require('redis').createClient(6378, 'Host');

router.get('/sku/:sku', function(req, res, next) {
 var resource = 'locks:sku:' + req.params.sku;
 var sku = req.params.sku;
 var ttl = 7; //s
 //预先判断一次库存,有库存才进行加锁
 client.get(sku, function(err, reply) {
 if (!err) {
 if (Number(reply) <= 0) {
 res.json({'result':'failed'});
 } else {
 client3.set(resource,Date.now(),'NX','PX',ttl*1000,function(err,reply){
 //获取到锁
 if(reply){
 //操作库存
 client.get(sku,function(err,reply){
 if(!err){
 if(Number(reply)<=0){
 res.json({'result':'failed'});
 }else{
 deductInventory(sku,Number(reply));
 client3.del(resource);
 res.json({'result':'succeeded'});
 }
 }else{
 res.json({'errcode':-1,'errmsg':'获取sku('+sku+')库存失败'});
 }
 });
 }else{//获取锁失败
 res.json({'result':'failed'});
 }
 });
 }
 }else{
 res.json({'errcode':-1,'errmsg':'获取sku('+sku+')库存失败'});
 }
 });
});

//减库存
function deductInventory(sku, reply) {
 reply--;
 client.set(sku, reply);
}

module.exports = router;

执行下压力测试(Apache Bench)(环境:本机(4核,8G内存,一台测试redis)

设置参数:1w请求,1000并发(ab.exe -n 10000 -c 1000 localhost:3000/seckill/sku/15769983)

可以看出,在这个级别性能不错。

 

目前这个秒杀方案,还没有在具体的项目中使用,这里提前调研,如果没什么问题,后期会用到实际项目里面。

 

本文参考官网:

http://expressjs.com/

http://twitter.github.io/hogan.js/

作者:张雪飞
出处:https://zhangxuefei.site/p/1743
版权说明:欢迎转载,但必须注明出处,并在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

发表评论

电子邮件地址不会被公开。 必填项已用*标注