我是新手,Go并且每天都在学习它。我context cancelled在我们的项目中看到了很多错误,这让我很恼火。所以我想深入挖掘一下,弄清楚发生了什么。
如果我没记错的话,用“简单”的术语来说,上下文取消意味着给定的请求(通过 grpc 使用 gokit)已经超时。正确的?如果是这样,解决此问题的最佳方法是什么?
我应该调查为什么这些请求超时(可能底层数据库查询需要很长时间或其他什么)并修复这些请求吗?
它是Go内部的东西,可能暗示与某些相关的东西Go吗?
开始处理此错误的最佳方法是什么?现在,我只看到“上下文已取消”,但不知道为什么会这样。
上下文定义了上下文类型,它在 API 边界和进程之间携带截止日期、取消信号和其他请求范围的值。
对服务器的传入请求应该创建一个上下文,而对服务器的传出调用应该接受一个上下文。
上下文取消错误不一定意味着超时错误。
如果您正在使用 go 例程,如果父 go 例程完成但子例程仍在后台运行,并且子 go 例程具有与父 go 例程相同的上下文,则这可能会导致上下文取消,如果父 go 例程go 例程在退出之前关闭上下文。
因此,如果子例程不依赖于父例程上下文,那么为后台 go 例程创建新上下文始终是一个好习惯。可以使用创建一个新的上下文context.Background()
如果您的应用程序是基于微服务的(或有多个组件使用上下文相互调用),如果微服务 1 调用微服务 2,而微服务 2 明确关闭或取消上下文,即使在这种情况下,您也会收到此错误。
可以通过调用cancel()函数来关闭上下文,如下所示:
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
Run Code Online (Sandbox Code Playgroud)
取消此上下文会释放与其关联的资源。因此,如果被调用者已显式关闭上下文,如上所示,这可能会导致调用者的上下文取消错误。
可以通过检查 调用中的context.Canceled错误来处理这些上下文取消的错误grpc.Dial()(如果您使用的是 grpc)