Go让消费速度更快

简介: Go让消费速度更快

Go让消费速度更快



可复用的生产消费逻辑


有时候我们从接口当中接受一批数据,想要它们在后台运行,或者说同步执行效率更快;有时候从缓存或者队列中消费数据,想要增加消费的速度;有时候跑一批数据,想要处理效率更高;那么遇到这些场景,这一套生产消费模式就足以应对了,来看下代码。


代码


func ConsumeTask(ctx context.Context) {
LOOP:
 var total int
 var success int
 start := time.Now()
 wg := sync.WaitGroup{}
 gLock := sync.Mutex{}
 taskChan := make(chan Task, 50)
 wg.Add(1)
 go func() {
  defer wg.Done()
  for {
   // 获取的长度是0或者错误 直接break
   // 生产 遇到错误continue
   // 反序列化
   total += 1
   taskChan <- task
  }
  // 结束生产
  close(taskChan)
 }()
  // 多个消费者
 for i := 0; i < 50; i++ {
  wg.Add(1)
  go func() {
   defer wg.Done()
   for {
    if task, ok := <-taskChan; ok { // 消费
       // 。。。。。。
       gLock.Lock()
       success += 1
       gLock.Unlock()
     }
    } else {// chan关闭了 就退出消费
     break
    }
   }
  }()
 }
 log.Warn(ctx, fmt.Sprintf("消费中"))
 wg.Wait()
 log.Warn(ctx, fmt.Sprintf("消费结束"))
 if success == 0 || total == 0 {
  log.Warn(ctx, fmt.Sprintf("当前无待消耗的任务, sleep 10s"))
  time.Sleep(10 * time.Second)
  goto LOOP
 }
 larkText := requestcommon.NewLarkCustomBotContentRichText("消费", time.Now().Format("2006-01-02 15:04:05"))
 totalText := fmt.Sprintf("总共待消费:%d", total)
 failText := fmt.Sprintf("失败:%d", total-success)
 successText := fmt.Sprintf("成功: %d", success)
 takeText := fmt.Sprintf("耗时: %v", time.Since(start))
 ipText := fmt.Sprintf("IP: %s", common.LocalIP())
 // 增加各种指标预警
 larkText.AddTextWithTag(totalText).AddTextWithTag(successText).AddTextWithTag(failText).AddTextWithTag(takeText).AddTextWithTag(ipText)
 // 通过飞书hook url 发送出去
 err := requestcommon.SendLarkCustomBotMsgRichText(ctx, "hook_url", *larkText)
 log.Warn(ctx, fmt.Sprintf("飞书发送消费通知 err: %v", err))
 goto LOOP
}


小结


这套模板大家可以拿来直接用,简单高效,欢迎有兴趣的同学一起交流哈。

相关文章
|
3月前
|
存储 Go 调度
Go 并发
Go 并发
21 3
|
4月前
|
NoSQL Go Redis
Go异步任务处理解决方案:Asynq
Go异步任务处理解决方案:Asynq
264 1
Go异步任务处理解决方案:Asynq
|
SQL 安全 关系型数据库
Go ORM 干啥的?|Go主题月
胖sir :接着,给你一个馅饼儿 兵长 : 来嘞!! 一篇来自ORM的整理笔记...
Go ORM 干啥的?|Go主题月
|
Go Cloud Native
为什么要写技术文章 | GO主题月
这个问题对于每一个人来说各有各的原因。有的为了写作变现,有的为了自己的兴趣,写小说,写文章,写书。
为什么要写技术文章 | GO主题月
|
监控 NoSQL 数据可视化
一文带您了解Go异步任务处理解决方案:Asynq
一文带您了解Go异步任务处理解决方案:Asynq
481 0
|
算法 Java Go
Go可以无限Go?回家等通知吧
Go可以无限Go?回家等通知吧
|
消息中间件 存储 监控
go操作Kafka
go操作Kafka
241 0
|
Go
go里的select特点|Go主题月
在go中有一个类似switch的关键字,那就是select。 select的每个case接收的是I/O通讯操作,不能有其他表达式。select要配合channel使用。
120 0
|
存储 Java Unix
【FAQ】go的十万个为什么?-指针分配|Go主题月
与 C 系列中的所有语言一样,Go 中的所有内容都按值传递。也就是说,一个函数总是获得所传递事物的副本,就像有一个赋值语句将值分配给参数一样。例如,将int值传递给函数将生成的副本int,而将指针传递将生成指针的副本,但不会复制其指向的数据。
131 0
|
Linux Go Windows
go第一站|Go主题月
Go目前支持三大平台的安装,Linux,Mac,Windows。
75 0