如何在Google Pub/Sub';这是什么政策工作?

如何在Google Pub/Sub';这是什么政策工作?,go,publish-subscribe,google-cloud-pubsub,exponential-backoff,Go,Publish Subscribe,Google Cloud Pubsub,Exponential Backoff,最近发布的cloud.google.com/go/pubsub库(在v1.5.0中,参见)支持新的RetryPolicy服务器端功能。此文件的文档()当前为 我读过维基百科的文章,虽然它描述了离散时间内的指数退避,但我不知道这篇文章与MinimumBackoff和MaximumBackoff参数有什么特别的关系。关于这方面的指导,我参考了github.com/cenkalti/backoff的文档。该库将指数备份定义为 类型ExponentialBackOff结构{ 初始间隔时间。持续时间 随

最近发布的
cloud.google.com/go/pubsub
库(在v1.5.0中,参见)支持新的
RetryPolicy
服务器端功能。此文件的文档()当前为

我读过维基百科的文章,虽然它描述了离散时间内的指数退避,但我不知道这篇文章与
MinimumBackoff
MaximumBackoff
参数有什么特别的关系。关于这方面的指导,我参考了github.com/cenkalti/backoff的文档。该库将
指数备份定义为

类型ExponentialBackOff结构{
初始间隔时间。持续时间
随机化因子浮点64
乘法器浮点64
最大间隔时间。持续时间
//在MaxElapsedTime之后,ExponentialBackOff返回Stop。
//如果MaxElapsedTime==0,则它永远不会停止。
MaxElapsedTime时间。持续时间
停止时间,持续时间
时钟
//包含已过滤或未报告的字段
}
其中,每个随机间隔计算为

randomized interval =
    RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor])
其中,
RetryInterval
是当前重试间隔,据我所知,它从
InitialInterval
的值开始,并以
MaxInterval
为上限

我是否正确理解
最小回退
最大回退
对应于
github.com/cenkalti/backoff
中的
初始间隔
最大间隔
?也就是说,
MinimumBackoff
是初始等待时间,
MaximumBackoff
是重试之间允许的最大时间

为了验证我的理论,我编写了以下简化程序:

主程序包
进口(
“上下文”
“旗帜”
“fmt”
“日志”
“操作系统”
“时间”
“cloud.google.com/go/pubsub”
“google.golang.org/grpc/codes”
“google.golang.org/grpc/status”
)
变量(
射影串
最小回退,最大回退时间。持续时间
)
常数(
topicName=“测试主题”
subName=“测试订阅”
defaultMinimumBackoff=10*时间秒
defaultMaximumBackoff=10*时间.分钟
)
func main(){
flag.StringVar(&projectID,“projectID”,“我的项目”,“谷歌项目ID”)
flag.DurationVar(&minimumBackoff,“minimumBackoff”,5*time.Second,“minimumBackoff”)
flag.DurationVar(&maximumBackoff,“maximumBackoff”,60*time.Second,“最大退避”)
flag.Parse()
log.Printf(“以最小回退%v和最大回退%v运行…”,最小回退,最大回退)
retryPolicy:=&pubsub.retryPolicy{MinimumBackoff:MinimumBackoff,MaximumBackoff:MaximumBackoff}
客户端,错误:=pubsub.NewClient(context.Background(),projectID)
如果错误!=零{
log.Fatalf(“新客户端:%v”,错误)
}
主题,错误:=client.CreateTopic(context.Background(),topicName)
如果错误!=零{
log.Fatalf(“创建主题:%v”,错误)
}
log.Printf(“已创建主题%q”,主题名)
延迟函数(){
topic.Stop()
如果错误:=topic.Delete(context.Background());错误!=nil{
log.Fatalf(“删除主题:%v”,错误)
}
log.Printf(“已删除主题%s”,主题名称)
}()
sub,err:=client.CreateSubscription(context.Background(),subName,pubsub.SubscriptionConfig{
主题:主题,,
RetryPolicy:RetryPolicy,
})
如果错误!=零{
log.Fatalf(“创建订阅:%v”,错误)
}
log.Printf(“已创建订阅%q”,子名称)
延迟函数(){
如果错误:=sub.Delete(context.Background());错误!=nil{
log.Fatalf(“删除订阅:%v”,错误)
}
log.Printf(“已删除订阅%q”,子名称)
}()
go func(){
sub.Receive(context.Background(),func(ctx context.context,msg*pubsub.Message){
log.Printf(“Nacking消息:%s”,msg.Data)
msg.Nack()
})
}()
topic.Publish(context.Background(),&pubsub.Message{Data:[]字节(“Hello,world!”)})
log.Println(“已发布消息”)
时间。睡眠(60*时间。秒)
}
如果我分别使用5秒和60秒的默认标志
MinimumBackoff
MaximumBackoff
运行它,我会得到以下输出:

> go run main.go
2020/07/29 18:49:32 Running with minumum backoff 5s and maximum backoff 1m0s...
2020/07/29 18:49:33 Created topic "test-topic"
2020/07/29 18:49:34 Created subscription "test-subscription"
2020/07/29 18:49:34 Published message
2020/07/29 18:49:36 Nacking message: Hello, world!
2020/07/29 18:49:45 Nacking message: Hello, world!
2020/07/29 18:49:56 Nacking message: Hello, world!
2020/07/29 18:50:06 Nacking message: Hello, world!
2020/07/29 18:50:17 Nacking message: Hello, world!
2020/07/29 18:50:30 Nacking message: Hello, world!
2020/07/29 18:50:35 Deleted subscription "test-subscription"
2020/07/29 18:50:35 Deleted topic test-topic
然而,如果我分别以1s和2s的
MinimumBackoff
maxiumbackoff
运行它,我得到

> go run main.go --minimumBackoff=1s --maximumBackoff=2s
2020/07/29 18:50:42 Running with minumum backoff 1s and maximum backoff 2s...
2020/07/29 18:51:11 Created topic "test-topic"
2020/07/29 18:51:12 Created subscription "test-subscription"
2020/07/29 18:51:12 Published message
2020/07/29 18:51:15 Nacking message: Hello, world!
2020/07/29 18:51:18 Nacking message: Hello, world!
2020/07/29 18:51:21 Nacking message: Hello, world!
2020/07/29 18:51:25 Nacking message: Hello, world!
2020/07/29 18:51:28 Nacking message: Hello, world!
2020/07/29 18:51:31 Nacking message: Hello, world!
2020/07/29 18:51:35 Nacking message: Hello, world!
2020/07/29 18:51:38 Nacking message: Hello, world!
2020/07/29 18:51:40 Nacking message: Hello, world!
2020/07/29 18:51:44 Nacking message: Hello, world!
2020/07/29 18:51:47 Nacking message: Hello, world!
2020/07/29 18:51:50 Nacking message: Hello, world!
2020/07/29 18:51:52 Nacking message: Hello, world!
2020/07/29 18:51:54 Nacking message: Hello, world!
2020/07/29 18:51:57 Nacking message: Hello, world!
2020/07/29 18:52:00 Nacking message: Hello, world!
2020/07/29 18:52:03 Nacking message: Hello, world!
2020/07/29 18:52:06 Nacking message: Hello, world!
2020/07/29 18:52:09 Nacking message: Hello, world!
2020/07/29 18:52:12 Nacking message: Hello, world!
2020/07/29 18:52:13 Deleted subscription "test-subscription"
2020/07/29 18:52:13 Deleted topic test-topic

在后一个例子中,两次NACK之间的时间似乎相当一致~3s,这可能表示在2s的
MaximumBackoff
范围内“尽最大努力”完成这项工作?我仍然不清楚的是,是否存在随机性,是否存在乘数(从第一个例子来看,每次重试之间的时间似乎不是两倍长),以及是否存在一个等价的
MaxElapsedTime
,超过该时间将不再重试?

最小退避和最大退避的重试策略字段类似于上面示例中的InitialInterval和MaxInterval。云发布/订阅使用与您提到的类似的公式来计算指数延迟。这也包括随机化


在MaxInterval之外,每次后续重试都会增加MaxInterval的延迟。如果您想在一定次数的尝试后停止重试,我们建议使用。

酷,我想我的下一个问题是:
RetryPolicy
实现中的
乘数和
随机化因子值是多少?在第一个示例中,NACK之间的时间似乎增长非常缓慢,这表明
乘数
接近1。这些是系统内部细节,随着时间的推移会发生变化。我们不推荐依赖它们的用户。