Go 实现高并发下同步请求的思路

Go 实现同步请求的思路

1、背景

在实际生产中,我们或多或少的需要对接第三方的同步接口,那我们如何实现高并发下go的同步请求方法呢,下面我就讲一下我最近在生产中运用的一种方法。

我们最近遇到的需求是对接第三方的接口,需要实时的获取到对方的相应数据,超过三秒没有拿到则判断请求失败,返回对应的错误信息。

2、思路

我的做法是,首先定义一个全局的channel

var ReqChannel = make(chan *Packet, 20)

然后在请求的业务里,定义一个请求唯一的id并往这个channel里塞值,同时起一个协程循环的读取这个channel

for {
		req := <-model.ReqChannel
		packet := &Packet{
			Sign:      SignPubwin,
			CompanyId: CompanyId,
			Type:      req.Type,
			Id:        req.Id,
			Data:      req.Data,
		}
		Logger.Debugf("send packet to pubwin, id:%d, type:%#x, body:%s", req.Id, req.Type, string(req.Data))
		err := ptr.SendPacket2Pubwin(packet)
		if err != nil {
			Logger.Errorf("send packet to pubwin failed, id:%d, type:%#x, body:%s, err:%v", err, req.Id, req.Type, string(req.Data))
		}
	}

读取完以后,再定义一个全局的map,key是刚读取的请求的唯一ID,value定义成需要返回类型的channel

// 我的请求是返回一个byte数组
var ResMapChannel map[uint32]chan []byte

请求返回后,将请求的ID和返回的值塞到定义的map里,同是在请求的地方循环的读取key为请求ID的channel,
并设置对应的超时时间,记得处理结束移除对应map里的key,防止循环处理

// 初始化channel
var respChannel []byte
// 设置超时时间
ticker := time.NewTicker(3 * time.Second)
// 阻塞读取channel
for {
	select {
	case respChannel = <-model.ResMapChannel[id]:
		if respChannel != nil {
			// 处理返回的channel []byte
			err := json.Unmarshal(respChannel, &checkoutInfo)
			if err != nil {
				Logger.Errorf("response change failed! id %d, response channel %+v, err %s \n", id, respChannel, err.Error())
				return nil, err
			}
			// 处理结束移除map
			delete(model.ResMapChannel, id)
			return checkoutInfo, nil
		}
	case <-ticker.C:
		Logger.Errorf("response timeout, id %d", id)
		// 处理结束移除map
		delete(model.ResMapChannel, id)
		return nil, nil
	}
}

这样就可以保证高并发下的请求的返回的唯一正确性,以上仅仅是个人思路,仅供参考,对于有更好方法的小伙伴,或者是我的方法有不正确的地方,欢迎大家在评论区留言。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值