将Google PubSub与Golang配合使用。轮询服务的最有效(成本)方式

时间:2016-04-11 15:17:26

标签: go google-compute-engine google-cloud-pubsub

我们正在从AMQP迁移到Google的Pubsub。

The docs suggest这可能是我们的最佳选择,因为我们使用的是计算引擎,无法通过推送服务打开我们的工作人员。

它还表示,根据使用情况,拉动可能会产生额外费用:

  

如果使用轮询,则可能会导致网络使用率过高   经常打开连接并立即关闭它们。

我们在go中创建了一个测试用户,它在循环中运行:

func main() {
    jsonKey, err := ioutil.ReadFile("pubsub-key.json")
    if err != nil {
        log.Fatal(err)
    }
    conf, err := google.JWTConfigFromJSON(
        jsonKey,
        pubsub.ScopeCloudPlatform,
        pubsub.ScopePubSub,
    )
    if err != nil {
        log.Fatal(err)
    }
    ctx := cloud.NewContext("xxx", conf.Client(oauth2.NoContext))

    msgIDs, err := pubsub.Publish(ctx, "topic1", &pubsub.Message{
        Data: []byte("hello world"),
    })

    if err != nil {
        log.Println(err)
    }

    log.Printf("Published a message with a message id: %s\n", msgIDs[0])

    for {
        msgs, err := pubsub.Pull(ctx, "subscription1", 1)
        if err != nil {
            log.Println(err)
        }

        if len(msgs) > 0 {
            log.Printf("New message arrived: %v, len: %d\n", msgs[0].ID, len(msgs))
            if err := pubsub.Ack(ctx, "subscription1", msgs[0].AckID); err != nil {
                log.Fatal(err)
            }
            log.Println("Acknowledged message")
            log.Printf("Message: %s", msgs[0].Data)
        }
    }
}

我的问题是,这是否是正确/推荐的拉取信息的方式。

我们全天收到大约100毫秒/秒。我不确定在无休止的循环中运行它是否会破坏我们,并且找不到任何其他不错的例子。

1 个答案:

答案 0 :(得分:3)

通常,在Cloud Pub / Sub中提取订阅者的关键是确保始终至少有一些未完成的Pull请求,并将max_messages设置为适合以下情况的值:

  • 发布消息的速率,
  • 这些消息的大小,以及
  • 订阅者可以处理邮件的邮件速率。

一旦拉回请求返回,您应该发出另一个请求。这意味着异步处理和调整在pull响应中返回给你的消息(或者异步启动新的pull请求)。如果您发现吞吐量或延迟不是您所期望的,首先要做的是添加更多并发拉取请求。

声明“如果使用轮询,如果您经常打开连接并立即关闭它们,可能会导致高网络使用”,如果您的发布率非常低,则适用。想象一下,你一天只发布两三条消息,但你不断用pull请求进行轮询。这些拉取请求中的每一个都会产生请求的成本,但除了实际有消息的次数之外,您不会收到任何消息,因此“每条消息的成本”相当高。如果您以相当稳定的速率发布并且您的拉取请求返回非零数量的消息,则网络使用和成本将与消息速率一致。