Go并发编程-context安全传递数据

Context包-安全传递数据

context包我们就用来做两件事:
控制链路 安全传递数据

安全传递数据,是指在请求执行上下文中线程安全地传递数据,依赖于 WithValue 方法。

因为Go本身没有thread-local机制,所以大部分类似的功能都是借助于 context 来实现的。

例子:
链路追踪的 trace id
AB测试的标记位
压力测试标记位分库
分表中间件中传递 sharding hint
ORM 中间件传递 SQL hint
Web 框架传递上下文

微服务链路传递

  • 进程内同进程链路传递:context;
  • 微服务跨进程传递:微服务协议特定字段,
    如:Dubbo attachment
    Dubbo的隐式参数attachment了。什么是attachment?可以把它认定为Dubbo协议中的一个扩展点。就有点类似于Http协议,我们可以自定义请求头信息。而在Dubbo中,我们也可以自定义RPC请求中的参数
    如:grpc 在http协议的 header里去传递的。

Context包 父子关系

控制是从上至下的,查找是从下至上的。

context 的实例之间存在父子关系:

  • 当父亲取消或者超时,所有派生的子context 都被取消或者超时当

  • 找 key 的时候,子 context 先看自己有没有,没有则去祖先里面找控制是从上至下的,查找是从下至上的。

ctx := context.Background()
parent := context.WithValue(ctx,mykey{},"my value")

child := context.WitchValue(parent,mykey{},"my new value")

Log("parent mykey:",parent.Value(mykey{}))
Log("child mykey",child.Value(mykey{}))


// child test输出
parent mykey: my value
child mykey: my new value


child2,cancel := context.WitchTimeout(parent,time.Second)
defer cancel()
Log("child2 mykey:",child2.Value(mykey{}))

// child2 test输出
// child2 并没有设置mykey,但会继承自parent的mykey
parent mykey: my value
child mykey: my new value
child2 mykey: my value


 child3 := context.WithValue(parent,newkey{},"child3 value")
 Log("parent newkey", parent.Value(newkey{}))
 Log("child3 newkey", child3.Value(newkey{}))
// child3 test输出
parent newkey:<nil>
child3 newkey: child3 value

总之:儿子新值覆盖了旧值,父亲也拿不到新的值。
儿子新增了key,父亲也拿不到新的key

context包 父无法访问子内容

因为父 context 始终无法拿到子 context 设置的值,所以在逼不得已的时候我们可以在父 context 里面放一个 map,后续都是修改这个 map。


// 逼不得已使用
 parent1 := context.WithValue(ctx,mapData{},map[string]string{})

 child4,cancel := context.WithTimeout(parent1,time.Second)
 defer cancel()
 
 md := child4.Value(mapData{}).(map[string]string{})
 md["key1"] = "value1"
 pmd := parent1.Value(mapData{}).(map[string]string{})
 
 Log("parent1 mapData:", pmd["key1"])

// child4 test输出
parent newkey:<nil>
child3 newkey: child3 value

WithValue 注意会检测 Key type Comparable 可比较的
在这里插入图片描述

context包 – valueCtx 实现

valueCtx 用于存储 key-value 数据,特点:

  • 典型的装饰器模式:在已有 Context 的基础上附加一个存储 key-value 的功能
  • 只能存储一个 key, val
    valueCtx实现了Conext接口
    Value先找自己再找父亲

Value向上追溯

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值