写点什么

【go 专题】Context 的理解

用户头像
南吕
关注
发布于: 2021 年 04 月 24 日

什么是 Context

Package context defines the Context type, which carries deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes.
复制代码


我以前对 Context 的理解,就是从字面上理解:上下文,一个请求链路中一直存在的某信息。打个比方,Client 请求 A-Service 到 B-Service,B-Service 再到 C-Service,在这个请求链路中,上游就会将内容传递给下游,A-->B,B--->C 是保持一个请求过程的。Context 是程序单元的一个运行状态、现场、快照。结合这句话,我对 Context 的理解是 Context 用于保证一个 Request 在同一个生命周期内。


在 Go 语言中,程序单元指的就是 Goroutine。


所以,一个 Request,可能会在多个 goroutine 中去处理,多个 goroutine 可能共享 Request 信息,都在同一个生命周期内,如果 Request 请求取消或超时,则所有的 goroutine 都应该结束。

为什么需要 Context

上述刚才说一个请求可能会在多个 goroutine 中去处理,所以如果其中一个 goroutine 超时了或者中断了,那这个 Request 就应该被立即停止结束,而不是一直等待。


所以,每个长请求都应该有个超时限制,一个长请求需要一个 Context 来保证整个请求都是在同一个生命周期内。有点“一荣俱荣,一损俱损”的味道。

使用场景

任何可能被阻塞,或者需要很长时间来完成的,都应该有个 context.Context


  • rpc 调用

  • 长请求,长链路/多函数调用

Go 中 Context 用法

type Context interface {    Deadline() (deadline time.Time, ok bool)    Done() <-chan struct{}    Err() error    Value(key interface{}) interface{}}
复制代码


Goroutine 的创建和调用关系是分层级的。 为了实现这种关系,Context 结构像一棵树,叶子节点须总是由根节点衍生出来的。

创建 Context

  • context.Background() 一般使用此方法

  • context.TODO() 在目前还不清楚要使用的上下文时,或上下文尚不可用时,使用此方法

创建子节点

func WithCancel(parent Context) (ctx Context, cancel CancelFunc)func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)func WithValue(parent Context, key interface{}, val interface{}) Contex
复制代码

使用 Context 原则

  1. 不要把 Context 存在一个结构体当中,要显式地传入函数。Context 变量需要作为第一个参数使用,一般命名为 ctx;

  2. 即使方法允许,也不要传入一个 nil 的 Context。如果你不确定要用什么 Context,那么传一个 context.TODO

  3. 使用 context 的 Value 方法时,只应该在程序和接口中传递“和请求相关的元数据”,不要用它来传递一些可选的参数;

  4. 要养成关闭 Context 的习惯,在建立之后,立即 defer cancel() 是一个好习惯


Q&A


1、如果不使用 Context 来保证请求处于一个生命周期,是否有其他的方式?


2、对于 Context 源码分析--->待办


参考资料:


  1. https://blog.csdn.net/chinawangfei/article/details/86559975

  2. https://golang.google.cn/pkg/context/

发布于: 2021 年 04 月 24 日阅读数: 16
用户头像

南吕

关注

你我皆凡人 2019.05.10 加入

hi,Jasen

评论

发布
暂无评论
【go专题】Context的理解