我正在从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);
}
答案 0 :(得分:1)
超时截止日期超过时,连续拉取之间的退避问题。您实际上是在寻找一个长轮询解决方案,您需要将退避时间减少到接近0,或使用自定义连接/客户端立即重试。
答案 1 :(得分:0)
为了最大限度地减少延迟,您需要同时处理多个拉取请求。根据您的吞吐量要求,可能需要同时处理许多未完成的请求。如果您的吞吐量很低,您仍然希望一次有多个拉取请求(至少两个或三个)。只要其中任何一个返回,无论是超出截止日期还是消息,都会启动另一个拉取请求。目标是始终有一个未完成的拉取请求,等待接收已发布的消息。