今天在处理数据复制时,rpc请求进来后,做了个异步的流程,起了goroutine做数据复制后,rpc的接口直接ruturn了。 结果发现go routine中对其他服务的请求一直失败,debug后发现是因为go routine中发起对其他服务请求时一直提示context报错。
持续跟进发现是因为用的context是复用的GRPC接口中的context。 当GGRPC被return结束后, context会被设置成cancel的状态导致后续依赖次context的地方会失败。
1 | func (s *ExampleService) AsyncCall (ctx context.Context, req *examp.In) (*examp.Out, error) { |
像上面这种sample中的ExamplaGrpcCall
方法就无法访问成功,因为在请求前context已经被修改为cannel状态了。
解决办法也很简单: 重新建一个context而不要依赖GRPC原有的context。
如果服务之间有鉴权,新建的context需要从GRPC中的context中复制这部分信息。