golang+win10+lua+docker+redis+AB测试,实现商品秒杀代码实现

发布一下 0 0

上一篇文章用php原生代码实现了秒杀功能,本文用golang来实现秒杀;

运行环境:win10,docker+redis+lua最后AB压力测试;

共同点:用户id都是10000-1000000之间的随机数,库存stock都是1000,AB参数 -n 10000 -c 200两者相同

不同点:本项目演示中,PHP没有采用框架,go采用gin实现http服务。

先看看下之前php的压力测试结果,为了严谨一点,我执行三次取平均值。三次测试QPS平均值314

golang+win10+lua+docker+redis+AB测试,实现商品秒杀代码实现

PHP实现

golang+win10+lua+docker+redis+AB测试,实现商品秒杀代码实现

PHP实现

golang+win10+lua+docker+redis+AB测试,实现商品秒杀代码实现

PHP实现

php的秒杀实现请参考我的历史文章 : PHP实现秒杀过程及代码

按照入门级的理解,go用了框架,应该更繁重点,但是最后的测试结果让人吃惊:

那就是go的QPS将近是PHP的3.4倍,所以go不愧是面向工资编程语言,来看结果:

QPS平均值1068.7

golang+win10+lua+docker+redis+AB测试,实现商品秒杀代码实现

go实现

golang+win10+lua+docker+redis+AB测试,实现商品秒杀代码实现

go实现

golang+win10+lua+docker+redis+AB测试,实现商品秒杀代码实现

go实现


代码奉上,环境搭建此处就不累赘了。

package mainimport (   "context"   "fmt"   "github.com/gin-gonic/gin"   "github.com/go-redis/redis"   "math/rand"   "net/http"   "strconv"   "time")var redisDb *redis.Clientvar luaScript = `         local userId   = KEYS[1];         local goodKey  = KEYS[2];         local stock    = KEYS[3];         local userExit = redis.call("sismember",goodKey,userId);            if tonumber(userExit) == 1 then                return 2;            end             local num = redis.call("get",stock);            if tonumber(num) <= 0 then                return 3;            else                redis.call("decr",stock);                redis.call("sadd",goodKey,userId);            end             return 1;`var evalSha stringfunc init() {   initRedisClient()}func initRedisClient() {   redisDb = redis.NewClient(&redis.Options{      Addr:     "localhost:6379",      Password: "",      DB:       0,   })   var err error   evalSha, err = redisDb.ScriptLoad(context.Background(), luaScript).Result()   if err != nil {      panic(err)   }}func main() {   // 1.创建路由   r := gin.Default()   // 2.绑定路由规则,执行的函数   // gin.Context,封装了request和response   r.GET("/kill", func(c *gin.Context) {      kill()      c.String(http.StatusOK, "秒杀成功")   })   // 3.监听端口,默认在8080   // Run("里面不指定端口号默认为8080")   r.Run(":8000")}func kill() {   err := redisDb.SetNX(context.Background(), "go_stock", 1000, 0).Err()   if err != nil {      panic(err)   }   //time.Now().Unix()秒 ab测试产生了很多一样的用户   rand.Seed(time.Now().UnixNano()) //毫秒   id := rand.Intn(990001) + 10000  //10000-1000000的随机数   userId := strconv.Itoa(id)       //整数转字符,如果直接int(id)会出现意想不到的结果   res, err2 := redisDb.EvalSha(context.Background(), evalSha, []string{userId, "go_user_ids", "go_stock"}).Result()   if err2 != nil {      panic(err2)   }   if res.(int64) == int64(1) {      fmt.Println("秒杀成功")   } else if res.(int64) == int64(2) {      fmt.Println("请勿重复操作")   } else {      fmt.Println("暂无库存了")   }}

不妥之处请指正。

版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除

本文地址:http://0561fc.cn/79580.html