利用go特性实现高并发接口

   日期:2020-07-17     浏览:91    评论:0    
核心提示:一. 用go语言自带的锁。下面代码为抢购Api。//锁var mu sync.Mutex//抢购Apifunc (this *RushController) Purchase() { //商品ID goods_id := int64(1) //加锁 mu.Lock() //结束时解锁 defer mu.Unlock() //orm o := orm.NewOrm() //读取商品信息 m := models.Goods{Id: goods_id} err := o.Read(

一. 用go语言自带的锁。

下面代码为抢购Api

//锁
var mu sync.Mutex
//抢购Api
func (this *RushController) Purchase() {
	//商品ID
	goods_id := int64(1)
	//加锁
	mu.Lock()
	//结束时解锁
	defer mu.Unlock()
	//orm
	o := orm.NewOrm()
	//读取商品信息
	m := models.Goods{Id: goods_id}
	err := o.Read(&m)
	if err != nil{
		code,_ := beego.AppConfig.Int("paramError")
		this.ErrorJson(code, "数据错误")
	}
	//检查库存
	if m.Sku <= 0{
		code,_ := beego.AppConfig.Int("systemError")
		this.ErrorJson(code, "该商品已售罄")
	}
	//更新库存
	m.Sku--
	_,err = o.Update(&m)
	//订单入库
	order := models.Order{
		UserId: 1,
		GoodsId: goods_id,
		CreateTime: time.Now().Unix(),
	}
	o.Insert(&order)
	//返回
	arr := make(map[string]interface{})
	this.SuccessJson(arr)
}

二. 用go语言的channel。

下面代码为处理订单进程代码。

//订单channel
var chOrders chan models.Order = make(chan models.Order)
// 抢购code
const (
	buySuccess      = iota // 抢购成功
	buyFail           // 抢购失败
)
// 单线程死循环,专注处理数据更新
func RunRush() {
	for {
		//接收订单
		order := <-chOrders
		//orm
		o := orm.NewOrm()
		//读取商品信息
		m := models.Goods{Id: order.GoodsId}
		o.Read(&m)

		if m.Sku <= 0 {
			//无库存,通知回调失败
			order.Callback <- buyFail
		}else{//有库存
			//更新库存
			m.Sku -= 1
			o.Update(&m)
			//订单入库
			o.Insert(&order)
			//通知回调成功
			order.Callback <- buySuccess
		}
	}
}

下面代码为抢购Api

//抢购Api
func (this *RushController) Purchase() {
	//商品ID
	goods_id := int64(1)
	//orm
	o := orm.NewOrm()
	//读取商品信息
	m := models.Goods{Id: goods_id}
	err := o.Read(&m)
	if err != nil{
		code,_ := beego.AppConfig.Int("paramError")
		this.ErrorJson(code, "数据错误")
	}
	//检查库存
	if m.Sku <= 0{
		code,_ := beego.AppConfig.Int("systemError")
		this.ErrorJson(code, "该商品已售罄")
	}
	// 构造一个回调的channel
	callback := make(chan uint)
	//订单
	order := models.Order{
		UserId: 1,
		GoodsId: goods_id,
		CreateTime: time.Now().Unix(),
		Callback: callback,
	}
	// 把订单发送给channel
	chOrders <- order
	// 回调的channel等待处理结果
	code := <- callback
	if code == buySuccess{
		//抢购成功
		arr := make(map[string]interface{})
		this.SuccessJson(arr)
	}else{
		//抢购失败
		code,_ := beego.AppConfig.Int("systemError")
		this.ErrorJson(code, "抢购失败")
	}
}

总结

  优点:利用go语言自带的锁和channel,解决了并发抢购超卖的问题,实现快速,成本低。

  缺点:阻塞是一个办法,但不是非常好的解决方案,它简单粗暴,没有队列的削峰填谷那般巧妙,单纯靠 加锁 用于小并发没事,高并发 加锁就是灾难,用户都在等待。。。

  有什么高见欢迎大佬们在评论区指点。

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服