如果接收方可以正常工作,为什么我有“未送达的邮件”?

时间:2019-05-29 11:01:36

标签: go google-cloud-pubsub

stackdriver undelivered messages

我重新启动了Windows VM,但这没有帮助。第二天,我重新启动了main.go,之后我看到了旧的卡住消息开始出现。

我的Subscription Type是拉动,我的Acknowledgement Deadline最多是600秒。

背景:我想在托管的Windows实例组中将Pubsub用作负载平衡器(该任务需要Windows API)。消息处理需要占用大量CPU(需要执行几个HTTP调用),并且可能需要花费几秒钟到几分钟的时间。

Stackdriver的其他一些指标: stackdriver pubsub stackdriver oldest unacknowledged message stackdriver backlog size

我不知道可以检查什么。一天前,我进行了高负载测试,看起来一切都很好(如上图所示,Undelivered Messages为零)。现在我的CPU消耗为零,受管组减少到一个实例(这不在生产环境中)。我尝试第一次使用Pubsub。我的main()的代码,用于从文本块中合成音频,编码为两种格式并上传到S3:

func main() {
    fmt.Printf("Current time: %v\n",
        time.Now().Format(timeFormat),
    )

    // https://godoc.org/cloud.google.com/go/pubsub#Subscription.Receive
    err := subscription.Receive(ctx, func(ctx context.Context, m *pubsub.Message) {
        timeStart := time.Now()
        if timeStartFirstMessage == nil {
            timeStartFirstMessage = &timeStart
        }

        var data pubsubMessage
        json.Unmarshal(m.Data, &data)
        fmt.Printf("Got message: %#v\n", data)

        var wg sync.WaitGroup
        wg.Add(len(data.TextChunks))

        wavs := make([][]byte, len(data.TextChunks))
        for i, chunk := range data.TextChunks {
            /** TODO without 'go' (sequential) will process in correct order:
             * user can listen first and seconds chunks faster,
             * but m4a will be later,
             * but on "high load" of the VM with ~2x more messages in parallel
             * (each message on it is own goroutine)
             * performance may be even better (I think) because
             * hundreds of CPU intensive goroutine is worse.
             *
             * Also in sequential code I can append() to wav[]
             * instead of doind it later in another func,
             * maybe this will also improve perfomance (profile).
            **/
            go func(i int, chunk string) {
                fmt.Printf("Index of text chunk: %d\n", i)
                wav := tts(data.Voice, chunk)
                streamOfOggEncoder := encodeOggVorbis(wav)
                uploadToS3(
                    "intelligentspeaker",
                    data.Sub+"/"+data.HashArticle+"/"+fmt.Sprint(i),
                    "audio/ogg",
                    streamOfOggEncoder,
                )
                wavs[i] = wav

                wg.Done()
            }(i, chunk)
        }
        wg.Wait()
        wavConcated := concat(wavs)

        filename := buildPodcastEpisodeFilename(data.Title)
        err := encodePodcastEpisode(wavConcated, filename)
        if err != nil {
            m.Nack()
            return
        }

        if err != nil {
            logger.Log(logging.Entry{Payload: fmt.Sprintf("ERROR on m4a deleting: %v", err)})
        }

        key := data.Sub + "/" + data.HashArticle + "/" + random() + "/" + filename
        readCloser, size := getReadCloserAndSize(filename)
        if readCloser == nil {
            m.Nack()
            return
        }
        uploadToS3("intelligentspeaker--podcasts", key, "audio/x-m4a", readCloser)
        // Next message may be with the same title (filename)
        err = os.Remove(filename)

        fmt.Printf("Duration: %v\n", duration(wavConcated))
        updatePodcastXML(
            key,
            data.Title,
            data.URLArticle,
            data.FavIconURL,
            duration(wavConcated),
            data.Utc,
            size,
        )

        fmt.Printf("DONE pubsub message, current time: %v\n", time.Now().Format(timeFormat))
        fmt.Printf("Time of message processing: %v\n", time.Since(timeStart).Round(time.Second))
        fmt.Printf(
            "Time of all messages processing (counted from the first message, not from the start of this app): %v\n",
            time.Since(*timeStartFirstMessage).Round(time.Second),
        )

        m.Ack()

    })
    if err != nil {
        logger.Log(logging.Entry{Payload: fmt.Sprintf("ERROR on registering receiver: %v", err)})
    }

}

更新:找到了similar question

1 个答案:

答案 0 :(得分:0)

我假设所涉及的度量标准为pubsub.googleapis.com/subscription/num_undelivered_messages,该度量标准度量的是“订阅中未确认的消息(也称为积压消息)的数量”。在“确认请求”图表中,我们看到您的订阅者在28日晚上9点左右停止了对消息的确认。这是“最早的未确认消息”时代开始(线性地)增长的同时。同时,“待办事项大小”图非常平坦。这意味着在订阅的积压订单中有少量“问题”消息,订阅者未确认。订户很可能由于某种原因而无法处理这小部分消息。这些消息可能以某种方式畸形,或者不符合订户代码的某些期望。

您可以尝试调试的一件事是使用gcloud命令行工具“窥视”订阅的积压订单中的消息:https://cloud.google.com/sdk/gcloud/reference/pubsub/subscriptions/pull。请注意,如果您未设置gcloud标志,则--auto-ack工具将不会确认任何消息。