现象
公司内部采用gRpc作为服务之间的通讯框架, 并且使用skywalking作为链路追踪,来观察服务之间调用的问题,查看skywalking的endpoint数据时,发现gRpc生成的endpoint包含一些 接口名/onHalfClose、接口名/onClose 之类的endpoint,显然endpoint作为入口的展示并不需要这些。
原因
gRpc之间的一次通信并非是同步的,而是通信过程中的不同状态其实都是异步的,也会在不同的线程中执行,
例如上面的截图中,两条记录实际是在不同的线程中执行并记录,但是onHalfClose作为 local span 并非 entry span 也被记录在endpoint中,
因此追踪了一下skywalking对endpoint生成的源码发现有一个叫做 EndpointDepFromCrossThreadAnalysisListener 的类,这个类会对LocalSpan也进行分析,如果LocalSpan中存在跨线程的数据(span.getRefsCount() > 0) ,也会进行endPoint的生成,
进一步发现可以通过设置span的一个属性跳过local span的endpoint分析,如下图:
因此通过在agent sdk中,在创建local span时,设置该属性,即可避免local span也进行end point的生成,如下图:
设置属性前后效果对比