Golang 中 Context 的理解

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

什么是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/
目录
相关文章
|
6天前
|
存储 SQL 安全
Golang底层原理剖析之上下文Context
Golang底层原理剖析之上下文Context
68 0
|
6天前
|
Linux Go
浅谈Golang上下文Context
浅谈Golang上下文Context
28 0
|
6天前
|
数据管理 Go 开发者
Golang深入浅出之-Go语言上下文(context)包:处理取消与超时
【4月更文挑战第25天】Go语言中的`context`包在并发、网络请求和长任务中至关重要,提供取消、截止时间和元数据管理。本文探讨`context`基础,如`Background()`、`TODO()`、`WithCancel()`、`WithDeadline()`和`WithTimeout()`。常见问题包括不当传递、过度使用`Background()`和`TODO()`以及忽略错误处理。通过取消和超时示例,强调正确传递上下文、处理取消错误和设置超时以提高应用健壮性和响应性。正确使用`context`是构建稳定高效Go应用的关键。
22 1
|
6天前
|
Go 开发者
Golang深入浅出之-Go语言上下文(context)包:处理取消与超时
【4月更文挑战第23天】Go语言的`context`包提供`Context`接口用于处理任务取消、超时和截止日期。通过传递`Context`对象,开发者能轻松实现复杂控制流。本文解析`context`包特性,讨论常见问题和解决方案,并给出代码示例。关键点包括:1) 确保将`Context`传递给所有相关任务;2) 根据需求选择适当的`Context`创建函数;3) 定期检查`Done()`通道以响应取消请求。正确使用`context`包能提升Go程序的控制流管理效率。
21 1
|
7月前
|
监控 安全 Go
Golang 语言中 Context 的使用方式
Golang 语言中 Context 的使用方式
24 0
|
6天前
|
监控 安全 Go
golang面试:golang中的context(四)
golang面试:golang中的context(四)
45 0
|
7月前
|
存储 SQL 安全
Golang 语言标准库 context 包控制 goroutine
Golang 语言标准库 context 包控制 goroutine
30 0
|
7月前
|
Go API 调度
No.14 Golang中Context你了解吗?(下)
No.14 Golang中Context你了解吗?
|
7月前
|
Go
No.14 Golang中Context你了解吗?(上)
No.14 Golang中Context你了解吗?
|
9月前
|
存储 安全 测试技术
Golang Context 详细原理和使用技巧
Golang Context 详细原理和使用技巧