通过 goroutine 异步发布到 google pub sub

Posted

技术标签:

【中文标题】通过 goroutine 异步发布到 google pub sub【英文标题】:Publishing to google pub sub asynchronously through goroutine 【发布时间】:2019-05-03 09:36:53 【问题描述】:

我正在尝试通过 goroutine 将消息异步推送到 google pub-sub,但我遇到了以下错误 panic: not an App Engine context 我正在使用 mux 并有一个 api 处理程序

n = 100 万

    func apihandler(w http.ResponseWriter, r *http.Request) 
       go createuniquecodes(n)
       return "request running in background"
    

    func createuniquecodes(n) 
       c := make(chan string)
       go createuniquecodes(c, n)  
       for val := range c         
           publishtopubsub(val)
        
   
   func createuniquecodes(n) 
        for i := 0; i < n; i++ 
           uniquecode := some random string
           // publish to channel and pubsub
           c <- uniquecode
        
        close(c)
    

func publishuq(msg string) error 
   ctx := context.Background()
   client, err := pubsub.NewClient(ctx, projectId)
   if err != nil 
     log.Fatalf("Could not create pubsub Client: %v", err)
   
   t := client.Topic(topicName)
   result := t.Publish(ctx, &pubsub.Message
   Data: []byte(msg),
 )
 id, err := result.Get(ctx)
 if err != nil 
    return err

fmt.Printf("Published a message; msg ID: %v\n", id)
return nil

请注意,我需要生成 500 万个唯一代码, 我将如何在 goroutine 中定义上下文,因为我正在异步执行所有操作

【问题讨论】:

【参考方案1】:

我假设您使用的是 App Engine 标准(非灵活)环境。请注意,“请求处理程序(在您的情况下为apihandler)有有限的时间来生成并返回对请求的响应,typically around 60 seconds。一旦达到截止日期,请求处理程序就会被中断”。

当调用go createuniquecodes(n)ctx := context.Background() 时,你试图“突破”请求,这就是not an App Engine context 的恐慌。从技术上讲,您可以使用 NewContext(req *http.Request) 从原始上下文中派生出一个有效的上下文,但同样,在您的请求超时之前只有 60 秒。

请查看TaskQueues,因为它们“让应用程序在用户请求之外异步执行工作,称为任务。”

【讨论】:

我通过 goroutine 异步执行此操作,所以不明白为什么会发生超时?是的,我可以使用任务队列并通过工作人员将任务委托给新上下文并发布到 pubsub App Engine 标准环境带有一些约束,其中一个约束是 goroutine 受请求的生命周期约束。我之前遇到过同样的问题,也许这个链接对你也有帮助:***.com/questions/27185405/…

以上是关于通过 goroutine 异步发布到 google pub sub的主要内容,如果未能解决你的问题,请参考以下文章

golang 使用goroutines和channel异步获取url

通过通道将值发送到多个 goroutine

高并发实时弹幕系统 并发数一定是可以进行控制的 每个需要异步处理开启的 Goroutine(Go 协程)都必须预先创建好固定的个数,如果不提前进行控制,那么 Goroutine 就随时存在爆发的可

Golang 多goroutine异步通知error的一种方法

go语言之行--golang核武器goroutine调度原理channel详解

Golang入门到项目实战 golang并发变成之通道channel