使用.Net客户端的Google Pub子消息拉延迟问题

时间:2017-02-27 06:52:10

标签: google-cloud-pubsub

我正在从Google PubSub不断提取消息。一切顺利,除了获取消息所需的时间大约是12到15秒,在我们的情况下是不可接受的。以下是我的CallTiming设置:

 public CallSettings GetPullSetting()
    {
        CallTiming timing = CallTiming.FromRetry(new RetrySettings(
                retryBackoff: new BackoffSettings(new TimeSpan(0, 0, 0, 0, 50), new TimeSpan(0, 0, 5), 1),
                timeoutBackoff: new BackoffSettings(new TimeSpan(0, 0, 0, 18, 0), new TimeSpan(0, 0, 20), 1),
                totalExpiration: Google.Api.Gax.Expiration.FromTimeout(TimeSpan.FromMilliseconds(600000))));

        return CallSettings.FromCallTiming(timing);
    }

我尝试所有类型的组合将此延迟减少到最多3秒。

一个观察结果是,无论何时成功提取消息,并且在pull的下一次迭代中,如果pubsub上有消息,它会立即获取该消息。这意味着如果在连续pull中发现消息,则延迟非常低。

但问题是,在一次迭代中我得到Deadline exceeded异常,因为pubsub没有消息。然后我在pubsub中推送一条消息进行下一次迭代。此时需要很多时间(13到16秒)。因此,重现此问题的条件是我将尝试一次失败的尝试。

此处粘贴的代码:

public void PullTest()
        {
            var cont = true;
            SubscriberSettings settings = new SubscriberSettings()
            {
                PullSettings = GetPullSetting()
            };
            SubscriberClient subscriberClient = SubscriberClient.Create(settings: settings);
            var subscriberName = new SubscriptionName("project-name", "subscription-name");
            while (cont)
            {
                try
                {
                    PullResponse response = subscriberClient.Pull(subscriberName, returnImmediately: false, maxMessages: 1);
                    System.Diagnostics.Trace.WriteLine(">>>>>> " + DateTime.Now.ToString());
                    System.Diagnostics.Trace.WriteLine(">>>>>> " + "Job Recieved" + response.ReceivedMessages.ToList().FirstOrDefault());
                    subscriberClient.Acknowledge(subscriberName, new List<string>() { response.ReceivedMessages.ToList().FirstOrDefault().AckId });
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Trace.WriteLine(">>>>>> " + DateTime.Now.ToString());
                    System.Diagnostics.Trace.WriteLine(">>>>>> " + ex.Message);
                }
            }
        }

 public CallSettings GetPullSetting()
        {
            CallTiming timing = CallTiming.FromRetry(new RetrySettings(
                    retryBackoff: new BackoffSettings(new TimeSpan(0, 0, 0, 0, 50), new TimeSpan(0, 0, 5), 1),
                    timeoutBackoff: new BackoffSettings(new TimeSpan(0, 0, 0, 18, 0), new TimeSpan(0, 0, 20), 1),
                    totalExpiration: Google.Api.Gax.Expiration.FromTimeout(TimeSpan.FromMilliseconds(600000))));

            return CallSettings.FromCallTiming(timing);
        }

2 个答案:

答案 0 :(得分:1)

超时截止日期超过时,连续拉取之间的退避问题。您实际上是在寻找一个长轮询解决方案,您需要将退避时间减少到接近0,或使用自定义连接/客户端立即重试。

答案 1 :(得分:0)

为了最大限度地减少延迟,您需要同时处理多个拉取请求。根据您的吞吐量要求,可能需要同时处理许多未完成的请求。如果您的吞吐量很低,您仍然希望一次有多个拉取请求(至少两个或三个)。只要其中任何一个返回,无论是超出截止日期还是消息,都会启动另一个拉取请求。目标是始终有一个未完成的拉取请求,等待接收已发布的消息。