Dubbo中重要的概念Invoker、Invocation、Protocol和URL。Dubbo异步调用中的Bug及处理方式

dubbo的调用过程如下图所示

Dubbo中重要的概念Invoker、Invocation、Protocol和URL。Dubbo异步调用中的Bug及处理方式_第1张图片
dubbo的调用过程

1:URL
定义了调用的url如协议、协议、参数等信息。还有在拓展加载中选择对应的拓展类如下代码片段所示(isActive(activate, url))

public List getActivateExtension(URL url, String[] values, String group) {
    List exts = new ArrayList();
    List names = values == null ? new ArrayList(0) : Arrays.asList(values);
    if (! names.contains(Constants.REMOVE_VALUE_PREFIX + Constants.DEFAULT_KEY)) {
        getExtensionClasses();
        for (Map.Entry entry : cachedActivates.entrySet()) {
            String name = entry.getKey();
            Activate activate = entry.getValue();
            if (isMatchGroup(group, activate.group())) {
                T ext = getExtension(name);
                if (! names.contains(name)
                        && ! names.contains(Constants.REMOVE_VALUE_PREFIX + name) 
                        && isActive(activate, url)) {
                    exts.add(ext);
                }
            }
        }

dubbo已知的调用传递bug(dubbo.2.5.3)

服务A异步调用服务B再同步调用服务C这种情况下服务A将获取不到结果。原因是在传递async参数的过程中将B同步调用C修改为异步调用。

Dubbo中重要的概念Invoker、Invocation、Protocol和URL。Dubbo异步调用中的Bug及处理方式_第2张图片
dubbo已知的调用传递bug(版本2.5.3)

传递bug导致具体代码位置


Dubbo中重要的概念Invoker、Invocation、Protocol和URL。Dubbo异步调用中的Bug及处理方式_第3张图片
传递bug导致具体代码位置

如何解决传递问题
添加Filter在调用前把async属性重置为默认值。如下所示

@Activate(value = {Constants.CONSUMER,Constants.PROVIDER} ,order = -1000000)
public class RmAsync implements Filter {

    public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {
        invocation.getAttachments().put("async", "false");
        return invoker.invoke(invocation);
    }
}

URl中实际开发中应用

服务跟踪同一笔请求从源头服务开始把日志ID传递到服务方,根据日志id跟踪调用流程具体实现如下

public class ConsumerTrackingFilter implements Filter {
    private Logger logger = LoggerFactory.getLogger(ConsumerTrackingFilter.class);

    public ConsumerTrackingFilter() {
    }

    public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {
        try {
            String unique = LogUniqueKeyUtil.getKeyFromLog();
            if (StringUtils.isEmpty(unique)) {
                LogUniqueKeyUtil.generateKeyToLog();
            }

            RpcContext.getContext().setAttachment(LogUniqueKeyUtil.LOG_KEY, unique);
        } catch (Throwable var4) {
            this.logger.warn("ConsumerTrackingFilter error", var4);
        }

        Result result = invoker.invoke(invocation);
        return result;
    }
}

2:Invoker

是实体域,它是 Dubbo 的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起 invoke 调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。
服务提供者暴露一个服务的详细过程


Dubbo中重要的概念Invoker、Invocation、Protocol和URL。Dubbo异步调用中的Bug及处理方式_第4张图片
服务提供者暴露一个服务的详细过程

服务消费者消费一个服务的详细过程


Dubbo中重要的概念Invoker、Invocation、Protocol和URL。Dubbo异步调用中的Bug及处理方式_第5张图片
服务消费者消费一个服务的详细过程

3:Invocation
是会话域,它持有调用过程中的变量,比如方法名,参数等。
4:Protocol
是服务域,它是 Invoker 暴露和引用的主功能入口,它负责 Invoker 的生命周期管理。

你可能感兴趣的:(Dubbo中重要的概念Invoker、Invocation、Protocol和URL。Dubbo异步调用中的Bug及处理方式)