Dubbo3 源码解读-宋小生-19:重新来过从一个服务消费者的Demo说起

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: > 完整电子书下载地址: https://developer.aliyun.com/ebook/7894> Dubbo3 已经全面取代 HSF2 成为阿里的下一代服务框架,2022 双十一基于 Dubbo3 首次实现了关键业务不停推、不降级的全面用户体验提升,从技术上,大幅提高研发与运维效率的同时地址推送等关键资源利用率提升超 40%,基于三位一体的开源中间件体系打造了阿里在云上的单元化最佳实
完整电子书下载地址: https://developer.aliyun.com/ebook/7894

Dubbo3 已经全面取代 HSF2 成为阿里的下一代服务框架,2022 双十一基于 Dubbo3 首次实现了关键业务不停推、不降级的全面用户体验提升,从技术上,大幅提高研发与运维效率的同时地址推送等关键资源利用率提升超 40%,基于三位一体的开源中间件体系打造了阿里在云上的单元化最佳实践和统一标准,同时将规模化实践经验与技术创新贡献开源社区,极大的推动了开源技术与标准的发展。

本文是 Dubbo 社区贡献者宋小生基于 Dubbo3 3.0.8 版本撰写的源码解析博客,在 Dubbo3 开源&内部技术栈统一的情况下,期望能对集团内的开发者了解 Dubbo3 背后的实现原理有所帮助。可点此查看 博客原文

本篇是宋小生系列 19/30 篇。同时,由 Dubbo3 团队领导的源码解读系列也正在进行中,感兴趣的同学可加入钉钉群了解详情: 2816500319

为了更方便了解原理,我们先来编写一个Demo,从例子中来看源码实现:,前面说了提供者现在已经有服务注册上去了,那接下来我们编写一个消费者的例子来进行服务发现与服务RPC调用。

19.1 启动Zookeeper

为了Demo可以正常启动,需要我们先在本地启动一个Zookeeper如下图所示:

19.2 服务消费者

接下来给大家贴一下示例源码,这个源码来源于Dubbo源码目录的 dubbo-demo/dubbo-demo-api 目录下面的dubbo-demo-api-consumer子项目,这里我做了删减,方便看核心代码:
首先我们定义一个服务接口如下所示:

import java.util.concurrent.CompletableFuture;
public interface DemoService {
    /**
     * 同步处理的服务方法
     * @param name
     * @return
     */
    String sayHello(String name);

    /**
     * 用于异步处理的服务方法
     * @param name
     * @return
     */
    default CompletableFuture<String> sayHelloAsync(String name) {
        return CompletableFuture.completedFuture(sayHello(name));
    }
}

服务实现类如下:

import org.apache.dubbo.rpc.RpcContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CompletableFuture;

public class DemoServiceImpl implements DemoService {
    private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class);

    @Override
    public String sayHello(String name) {
        logger.info("Hello " + name + ", request from consumer: " + RpcContext.getServiceContext().getRemoteAddress());
        return "Hello " + name + ", response from provider: " + RpcContext.getServiceContext().getLocalAddress();
    }

    @Override
    public CompletableFuture<String> sayHelloAsync(String name) {
        return null;
    }

}

19.3 启用服务消费者

有了服务接口之后我们来启用服务,启用服务的源码如下:
这里如果要启动消费者,主要要修改QOS端口这里我已经配置可以直接复用


package link.elastic.dubbo.consumer;

import link.elastic.dubbo.entity.DemoService;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.MetadataReportConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.rpc.service.GenericService;

public class ConsumerApplication {
    public static void main(String[] args) {
            runWithBootstrap();
    }
    private static void runWithBootstrap() {
        ReferenceConfig<DemoService> reference = new ReferenceConfig<>();
        reference.setInterface(DemoService.class);
        reference.setGeneric("true");
        reference.setProtocol("");

        DubboBootstrap bootstrap = DubboBootstrap.getInstance();
        ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-demo-api-consumer");
        applicationConfig.setQosEnable(false);
        applicationConfig.setQosPort(-1);
        bootstrap.application(applicationConfig)
            .registry(new RegistryConfig("zookeeper://8.131.79.126:2181"))
            .protocol(new ProtocolConfig(CommonConstants.DUBBO, -1))
            .reference(reference)
            .start();

        DemoService demoService = bootstrap.getCache().get(reference);
        String message = demoService.sayHello("dubbo");
        System.out.println(message);

        // generic invoke
        GenericService genericService = (GenericService) demoService;
        Object genericInvokeResult = genericService.$invoke("sayHello", new String[]{String.class.getName()},
            new Object[]{"dubbo generic invoke"});
        System.out.println(genericInvokeResult);
    }
}

1.4 启用服务后写入Zookeeper的节点数据

启动服务,这个时候我们打开Zookeeper图形化客户端来看看这个服务在Zookeeper上面写入来哪些数据,如下图:
在这里插入图片描述

写入Zookeper上的节点用于服务在分布式场景下的协调,这些节点是比较重要的。

如果了解过Dubbo的同学,应该会知道Dubbo在低版本的时候会向注册中心中写入服务接口,具体路径在上面的 dubbo目录下 ,然后在 /dubbo/服务接口/ 路径下写入如下信息:

  • 服务提供者配置信息URL形式
  • 服务消费者的配置信息URL形式
  • 服务路由信息
  • 配置信息

上面这个图就是Dubbo3的注册信息了,后面我们也会围绕细节来说明下,这里可以看下新增了:

  • /dubbo/metadata 元数据信息
  • /dubbo/mapping 服务和应用的映射信息
  • /dubbo/config 注册中心配置

    • /services目录应用信息

在这里可以大致了解下,在后面会有更详细的源码解析这个示例代码.通过透析代码来看透Dubbo3服务注册原理,服务提供原理。

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
目录
相关文章
|
2天前
|
XML Dubbo Java
【Dubbo3高级特性】「框架与服务」服务的异步调用实践以及开发模式
【Dubbo3高级特性】「框架与服务」服务的异步调用实践以及开发模式
37 0
|
2天前
|
XML Dubbo Java
【Dubbo3高级特性】「框架与服务」 Nacos作为注册中心-服务分组及服务分组聚合实现
【Dubbo3高级特性】「框架与服务」 Nacos作为注册中心-服务分组及服务分组聚合实现
64 0
|
2天前
|
Cloud Native Dubbo 应用服务中间件
【Dubbo3高级特性】「微服务云原生架构」带你从零基础认识搭建公司内部服务用户中心体系(实战指南-序章)
【Dubbo3高级特性】「微服务云原生架构」带你从零基础认识搭建公司内部服务用户中心体系(实战指南-序章)
66 0
|
2天前
|
Java fastjson 数据安全/隐私保护
【Dubbo3技术专题】「云原生微服务开发实战」 一同探索和分析研究RPC服务的底层原理和实现
【Dubbo3技术专题】「云原生微服务开发实战」 一同探索和分析研究RPC服务的底层原理和实现
49 0
|
2天前
|
XML Dubbo Java
【Dubbo3高级特性】「提升系统安全性」手把手教你如何通过令牌进行Dubbo3服务验证及服务鉴权控制实战指南(二)
【Dubbo3高级特性】「提升系统安全性」手把手教你如何通过令牌进行Dubbo3服务验证及服务鉴权控制实战指南
59 0
|
2天前
|
Dubbo Java 应用服务中间件
微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用
微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用
|
6月前
|
负载均衡 Dubbo 应用服务中间件
微服务技术系列教程(31) - Dubbo-原理及负载均衡分析
微服务技术系列教程(31) - Dubbo-原理及负载均衡分析
57 0
|
6月前
|
Dubbo Java 应用服务中间件
微服务技术系列教程(30) - Dubbo-SpringCloud与Dubbo区别
微服务技术系列教程(30) - Dubbo-SpringCloud与Dubbo区别
48 0
|
6月前
|
Dubbo Java 应用服务中间件
阿里新框架干掉微服务,换下Dubbo,Spring CloudAlibaba王者降临
tm快了,不知不觉中金九银十的秋招已经快结束了,不少同学现在已经拿到offer了吧~现在的面试可是越来越难了,动不动就是“互联网三高”。
阿里新框架干掉微服务,换下Dubbo,Spring CloudAlibaba王者降临
|
2天前
|
Dubbo Java 应用服务中间件
阿里巴巴资深架构师深度解析微服务架构设计之SpringCloud+Dubbo
软件架构是一个包含各种组织的系统组织,这些组件包括Web服务器,应用服务器,数据库,存储,通讯层),它们彼此或和环境存在关系。系统架构的目标是解决利益相关者的关注点。