异步情况下的span传递问题
Describe the bug (描述bug) 关于异步情况下 clientSpan的cr时间问题,对应span中的字段为:_received_real_us 观察到这个字段是在收包阶段设置。若brpc作为proxy,接收上游请求,之后发起异步调用,这时Server Controller会被销毁,由此调用Span的submit方法,此种情况下,异步调用的clientSpan会跟随ServerSpan一同销毁,由此会出现cr=0的情况。 Span销毁后,只是调用ReturnToObject丢回对象池,异步回调结束后,仍然可以拿到ParentSpan的指针,同时Client Controller事实上仍然是持有 client Span的指针的,这里设计是否存在问题?
To Reproduce (复现方法) 异步调用,一段时间后返回,cr时间为0.
Expected behavior (期望行为) clientSpan的销毁时机,应该在异步调用返回之后。
Versions (各种版本) OS: Compiler: brpc: protobuf:
Additional context/screenshots (更多上下文/截图)
V10 0104 10:54:57.397914 6221 18446744073709551615 src/brpc/span.cpp:316 [destroy] 0x4204240 V10 0104 10:54:57.397921 6221 18446744073709551615 src/brpc/span.cpp:323 [destroy] 0x4204000 V10 0104 10:54:58.394481 5744 4294976000 src/brpc/controller.cpp:1244 [SubmitSpan] this span:0x4204240 V10 0104 10:54:58.394501 5744 4294976000 src/brpc/controller.cpp:1245 [SubmitSpan] parent:0x4204000
这是打印出的日志信息(行号不一致请忽略,有别处的改动,但未影响span),异步情况下, proxy的server span调用destroy,同时destroy了所有的client span,异步调用返回时,又再次打印出这两个已经销毁的span(parent与client都已给出),可以确认是存在问题的。
这是代码位置:
与日志结合看,这里在span销毁后再次操作了span对象,因为returnToObject机制未销毁该指针,所以能够访问,事实上这样的操作应该是在操作野指针。
现在对于这种异步不等待的,如何能正确使用span呢?不等待的可以使用StartCancel+Join快速结束掉吗?@wwbmmm
能定义一个接口类似StartCancel,将不等待的rpc的span删掉吗? 具体步骤 1、使用bthread_id_lock锁住controller, 2、然后设置controller里面的span为空, 3、释放span空间。
现在对于这种异步不等待的,如何能正确使用span呢?不等待的可以使用StartCancel+Join快速结束掉吗?@wwbmmm
是否可以给Controller加一个强制关闭span功能的开关,对于异步不等待的请求可以开启这个开关?
现在对于这种异步不等待的,如何能正确使用span呢?不等待的可以使用StartCancel+Join快速结束掉吗?@wwbmmm
是否可以给Controller加一个强制关闭span功能的开关,对于异步不等待的请求可以开启这个开关?
有时候不知道哪些请求是异步不等待的,比如,向三个副本写数据,回来两个就认为成功了,第三个请求的应答就不需要同步等了,所以这个请求的span信息也就不需要了。这是一种动态的取消某个rpc的span的过程。
现在对于这种异步不等待的,如何能正确使用span呢?不等待的可以使用StartCancel+Join快速结束掉吗?@wwbmmm
是否可以给Controller加一个强制关闭span功能的开关,对于异步不等待的请求可以开启这个开关?
有时候不知道哪些请求是异步不等待的,比如,向三个副本写数据,回来两个就认为成功了,第三个请求的应答就不需要同步等了,所以这个请求的span信息也就不需要了。这是一种动态的取消某个rpc的span的过程。
这种可以用StartCancel+Join吧
现在对于这种异步不等待的,如何能正确使用span呢?不等待的可以使用StartCancel+Join快速结束掉吗?@wwbmmm
是否可以给Controller加一个强制关闭span功能的开关,对于异步不等待的请求可以开启这个开关?
有时候不知道哪些请求是异步不等待的,比如,向三个副本写数据,回来两个就认为成功了,第三个请求的应答就不需要同步等了,所以这个请求的span信息也就不需要了。这是一种动态的取消某个rpc的span的过程。
这种可以用StartCancel+Join吧
这种其实还是想要第三个请求的rpc应答的,只是不需要同步等待它,等这个rpc应答后可以做一些更新的动作。
这种可以用StartCancel+Join吧
这种其实还是想要第三个请求的rpc应答的,只是不需要同步等待它,等这个rpc应答后可以做一些更新的动作。
这个场景的话,感觉第三个请求的span信息也是有用的吧?可能需要实现一个server span延迟submit的逻辑
这种可以用StartCancel+Join吧
这种其实还是想要第三个请求的rpc应答的,只是不需要同步等待它,等这个rpc应答后可以做一些更新的动作。
这个场景的话,感觉第三个请求的span信息也是有用的吧?可能需要实现一个server span延迟submit的逻辑
如果不关心第三个请求的应答的span信息,在同步请求得到应答之后,是否可以按照如下逻辑处理不造成core呢? 具体步骤 1、使用bthread_id_lock锁住controller, 2、然后设置controller里面的span为空, 3、释放span空间。
这种可以用StartCancel+Join吧
这种其实还是想要第三个请求的rpc应答的,只是不需要同步等待它,等这个rpc应答后可以做一些更新的动作。
这个场景的话,感觉第三个请求的span信息也是有用的吧?可能需要实现一个server span延迟submit的逻辑
如果不关心第三个请求的应答的span信息,在同步请求得到应答之后,是否可以按照如下逻辑处理不造成core呢? 具体步骤 1、使用bthread_id_lock锁住controller, 2、然后设置controller里面的span为空, 3、释放span空间。
可以是可以,但是感觉有点trick
这种可以用StartCancel+Join吧
这种其实还是想要第三个请求的rpc应答的,只是不需要同步等待它,等这个rpc应答后可以做一些更新的动作。
这个场景的话,感觉第三个请求的span信息也是有用的吧?可能需要实现一个server span延迟submit的逻辑
如果不关心第三个请求的应答的span信息,在同步请求得到应答之后,是否可以按照如下逻辑处理不造成core呢? 具体步骤 1、使用bthread_id_lock锁住controller, 2、然后设置controller里面的span为空, 3、释放span空间。
可以是可以,但是感觉有点trick
因为我们有需求,所以暂时先这么搞定,然后再讨论怎么处理这样的需求更合理。😂