[apache/dubbo]Filter中Rpc参数传递问题

2024-05-30 706 views
0

因为要做服务链路追踪,所以想直接使用filter传递标识,但是发现有些问题 没有深追代码,不知道是不是我写的有问题,特来请教:)

发现invocation转为RpcInvocation后调用setAttachment无法传递自定义的参数 使用RpcContext.getContext().setAttachment可以传递

另外,例如A服务调用B服务中的两个方法,只有第一个方法在filter中有自定义的rpc传递的参数,在第二个方法中只有dubbo默认的如版本,方法名等

最后,如果我要做服务调用的链路跟踪,是否有更好的方法或思路?

回答

9

还有一个问题,就是一个应用(injvm)内现在是用ThreadLocal的方式去处理无rpc参数的记录,有无更合适的方式?

9

服务追踪 好像 有个 大众点评开源的CAT 来监控服务的东东 我们公司之前在用 每个请求在各个平台的响应时间 QPS 都有

0

dubbo的monitor接口可以用吧,我用了一个韩都衣舍开源的Monitor,感觉还可以

1

韩都衣舍还有开源的?0,0 找了一下没找到 求链接

9

@jj009 类似于CAT中的部分功能,主要是查看服务间调用情况,直观的展示服务瓶颈之类的 不过暂时只针对于dubbo的,所以希望基于其扩展去实现

2

@justein thanks~ 我看看~

6

@justein 简单看了一下实现,还是监控部分的,基本上是吧dubbo-monitor-simple美化了一下 我这边现在想做这样一个功能,就是服务间的调用全部记录下来,形成一个调用链路记录,可以用来分析某服务的瓶颈。 目前实现思路是使用dubbo的filter,在每个请求上加入tracing参数,根据该标识形成一个树状调用链。 现阶段问题就是,rpc传参有些问题(或者说我写的有问题~),导致某些情况下参数无法传递

5

大体明白你的意思了,也就用filter来实现了,还有别的方式么?

2

@justein 暂时没想到基于dubbo的其他方法,所以最后也请教这个问题了:) 类似于cat之类的在rpc外层集成去做,应该有一些其他的思路,但是现在主要还是针对dubbo,尽可能简单快速实现,所以还是偏向于filter的方案~

2

看下文档, 记得有说RpcContext在 A 传 B 完成后清空。B传 C 继续通过 filter 重新设置rpccontext

服务链路跟踪 根据 Dapper 设计 traceId/id/pid 字段入库 ELKStack 做跟踪

4

@jik1992 设计基本一致,traceId/id/pid 形成一个树状 就是rpc传参某些特定情况下会丢失,所以来问问~ thanks~ A传B 传C 确实可以解决 因为在B的filter我可以获取并且再次设置 现在问题是 如果A调用B的两个方法,第二个方法无法获取自定义rpc参数 T-T 而且我尝试使用ThreadLocal去实现,发现两个方法执行时不是一个线程=。= 另外RpcContext也是基于ThreadLocal实现的,invoke的时候又set进去的

0

最好的方法就是在服务端执行方法体之前,通过filter获取attachment数据

8

@teaey 谢谢~已经搞定,虽然方式有点诡异~ :)

6

@gr1532879 那个我也遇到了这个问题,在RpcContext中设置的attachment,在另一端获取不到,你采用何种方式传递呢

9

@zengzonghou 后来发现有一个ConsumerContextFilter会在rpc执行完之后将attachments都清掉. 所以自己写了一个CONSUMER的filter,调整filter顺序, 在执行之前将attachments拿到,在执行完成之后再put进去. 没有深入理解为什么要清掉,推断是为了不影响调用链上的下次rpc请求. 基本代码如下(kotlin写的,跟java差距也不大): @Activate(group = arrayOf(Constants.CONSUMER), order = -10001) class ConsumerAfterFilter : Filter { override fun invoke(invoker: Invoker<*>, invocation: Invocation): Result { val attachments = mutableMapOf<String, String>() attachments.putAll(RpcContext.getContext().attachments) try { return invoker.invoke(invocation) } finally { RpcContext.getContext().attachments.putAll(attachments) } } }

6

@summerpotato 大概看了一下,代码比我想想中的要多.... 我实现思路比较简单,rpc只传parentId作为追踪标识,加上本次调用的信息(appKey,interface,status什么的),缓存起来定时推(udp)到server server通过parentId吧链路串起来,我看你好像也有类似实现,一个servlet的filter. 这些数据server会扔到时序数据库,基本就差不多了

7

MDC +dubbo 扩展 filter