【Dubbo3高级特性】「框架与服务」RPC全链路调用追踪参数传递(OpenTracing)

上一节【RPC调用上下文的介绍】中建立了全链路调用的环境中必需的环境信息,例如应用名、调用的ip、等其他信息属性等。本节主要会建立相关的

特性说明

通过 Dubbo 中的 Attachment 在服务消费方和提供方之间隐式传递参数。

使用场景

上下文信息是RPC框架很重要的一个功能,使用RpcContext可以为单次调用指定不同配置。如分布式链路追踪场景,其实现原理就是在全链路的上下文中维护一个traceId,Consumer和Provider通过传递traceId来连接一次RPC调用,分别上报日志后可以在追踪系统中串联并展示完整的调用流程,这样可以更方便地发现异常,定位问题。

上一节的复用

Dubbo中的RpcContext是一个ThreadLocal的临时状态记录器,当接收到RPC请求,或发起RPC请求时,RpcContext的状态都会变化。比如:A调B,B调C,则B机器上,在B调C之前,RpcContext记录的是A和B的信息,在B调C之后,RpcContext记录的是B和C的信息。

上下文的种类

Dubbo3中,RpcContext被拆分为四大模块(ServerContext、ClientAttachment、ServerAttachment和ServiceContext),它们分别承担了不同的指责:

  • ServiceContext:在 Dubbo 内部使用,用于传递调用链路上的参数信息,如 invoker 对象等
  • ClientAttachment:在 Client 端使用,往 ClientAttachment 中写入的参数将被传递到 Server 端
  • ServerAttachment:在 Server 端使用,从 ServerAttachment 中读取的参数是从 Client 中传递过来的
  • ServerContext:在 Client 端和Server端使用,用于从 Server 端回传 Client 端使用,Server 端写入到 ServerContext 的参数在调用结束后可以在 Client 端的 ServerContext 获取到。

链路调用中上下文的使用流程

@SPI
public interface PenetrateAttachmentSelector {
    /**
     * Select some attachments to pass to next hop.
     * These attachments can fetch from {@link RpcContext#getServerAttachment()} or user defined.
     *
     * @return attachment pass to next hop
     */
    Map<String, Object> select();
}
  • 覆盖及实现PenetrateAttachmentSelector 的实现,可以在方法中RpcContext.getServerAttachment()调用获取参数,然后我们可以手动将此实现类过滤掉所有value为null的数据,所以通过此方法可以实现防止参数污染。

  • 返回值
    Map类型数据值,key:参数传递的key,value:参数传递作为数据的值。

@Activate(group = {Constants.PROVIDER, Constants.CONSUMER})
public class DefaultPenetrateAttachmentSelector implements PenetrateAttachmentSelector {
    @Override
    public Map<String, Object> select() {
        String traceParameter = RpcContext.getServerAttachment().getAttachment("traceId");
        System.out.println(" parameter:"+traceParameter);
        return RpcContext.getServerAttachment().getObjectAttachments();
    }
}

其中属性说明
  • Constants.PROVIDER:代表着作用于服务提供者端
  • Constants.CONSUMER:代表着作用于服务消费者端
服务提供者
public class ContextServiceImpl implements ContextService {

    @Override
    public String context(String name) {
        RpcContext.getServerAttachment().setAttachment("traceId", UUID.randomUUID().toString());
        return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress() +
                ", client: " + clientIP + ", local: " + application + ", remote: " + remoteApplication +
                ", isProviderSide: " + isProviderSide;
    }
}
服务消费者
        RpcContext.getServerAttachment().setAttachment("traceId", UUID.randomUUID().toString());
展示效果

在这里插入图片描述

可以看到在作为服务提供这段还没有traceId,但是作为服务消费者的时候,由于Provider注入了traceId,所以就可以获取到了uuid。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的RPC实现服务的输出和输入功能,可以和Spring 框架无缝集成。 Dubbo主要核心部件: Remoting:网络通信框架,实现了sync-over-async和request-response消息机制 RPC:一个远程过程调用的抽象,支持负载均衡、容灾和集群功能 Registry:服务目录框架用于服务的注册和服务事件发布和订阅 Dubbo功能特点: (1) 连通性: 注册中心负责服务地址的注册与查找,相当于目录服务服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小 监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示 服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销 服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销 注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外 注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者 注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表 注册中心和监控中心都是可选的,服务消费者可以直连服务提供者 (2) 健状性: 监控中心宕掉不影响使用,只是丢失部分采样数据 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务 注册中心对等集群,任意一台宕掉后,将自动切换到另一台 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯 服务提供者无状态,任意一台宕掉后,不影响使用 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复 (3) 伸缩性: 注册中心为对等集群,可动态增加机器部署实例,所有客户端将自动发现新的注册中心 服务提供者无状态,可动态增加机器部署实例,注册中心将推送新的服务提供者信息给消费者

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洛神灬殇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值