context里的超时时间是怎么在微服务之间传递的

题目:有A、B三个服务,调用链路为:A->B,为了控制调用的超时时间。A服务生成一个context,超时时间设置为3s,在A服务调用B服务的时候会把context传给B服务。这样子就能控制调用超时时间为3s,请问context里的超时是怎么在两个服务之间传递的,通过什么传递的?

在Go语言中,当微服务A需要将context的信息传递给微服务B时,实际上并不是直接将context对象通过网络发送。相反,context中的某些信息(如截止时间、取消信号等)会被提取出来,并作为请求的一部分发送给微服务B。

以下是context信息如何在网络上从微服务A传递到微服务B的步骤:

1.提取信息:在微服务A中,当准备发起对微服务B的请求时,会从当前的context中提取出需要传递的信息。这通常包括截止时间(如果有的话)和取消信号。

2.设置请求元数据:这些信息会被设置到请求的元数据(Metadata)中。对于HTTP请求,这可能意味着将截止时间转换为超时头(如果协议支持),或者将取消信号转换为某种形式的请求标识,以便在必要时能够中断处理。对于gRPC,可以使用元数据或特定的RPC上下文来传递这些信息。

3.发送请求:微服务A发起一个gRPC请求时,它会将元数据附加到请求头(Headers)中,这些元数据包含了关于请求的各种信息,如认证 信息、用户代理等。元数据在请求头中时键值对的形式传递。

4.解析元数据:微服务B接收到请求后,会从请求头中解析请求的元数据,从中提取出截止时间和取消信号(如果有的话)。然后,微服务B会创建一个新的context对象,并将这些信息设置到新的context中。

5.处理请求:微服务B使用新创建的context来处理请求。这意味着如果微服务A的context被取消,微服务B可以通过检查其自己的context来得知这一点,并相应地中断处理。

需要注意的是,这种传递方式并不是自动的;开发者需要显式地从context中提取信息,并将其设置到请求中。此外,不同的通信协议和框架可能有不同的方式来处理context信息的传递。例如,gRPC提供了专门的上下文传播机制,而HTTP则可能需要开发者自行实现一些逻辑来传递这些信息。

最后,还要考虑到安全性和隐私性问题。不应该将敏感信息或不应暴露给微服务B的信息通过context传递。因此,在设计和实现这种传递机制时,需要仔细考虑哪些信息应该被传递,以及如何安全地传递这些信息。

grpc超时传递是通过metadata进行传递的,最终会被转化为grpc-timeout的值,代码如下:

if v := r.Header.Get("grpc-timeout"); v != "" {
  to, err := decodeTimeout(v)
  if err != nil {
   return nil, status.Errorf(codes.Internal, "malformed time-out: %v", err)
  }
  st.timeoutSet = true
  st.timeout = to
}

 从请求头里取出超时时间的元数据,然后再通过得到的值构建一个context。 

posted @ 2024-03-17 13:06  cs_wu  阅读(29)  评论(0编辑  收藏  举报