深入理解Dubbo原理系列(一)-Dubbo简介和基本使用

一. Dubbo简介

Dubbo是阿里SOA服务化治理方案的一个核心框架,下面是Dubbo的一个架构图:

1.1 Dubbo架构

在这里插入图片描述
角色分配如下:

  • Provider:暴露服务的服务提供方。
  • Consumer:调用远程服务的服务消费方。
  • Registry:服务注册与发现的注册中心。
  • Monitor:统计服务的调用次数和调用时间的监控中心。
  • Container:服务运行的容器。

线条含义如下:

  • 虚线:异步访问。
  • 紫色虚线:在启动时就完成的功能。
  • 青色虚线:程序运行时执行的功能。
  • 实线:同步访问。

图中流程如下:

  1. Provider在启动的时候会向注册中心把自己的元数据注册上去,例如服务的IP、端口。
  2. Consumer在启动的时候从注册中心订阅服务提供方的元数据(第一次订阅则会拉取全量的数据)。
  3. 注册中心中若发生了数据的变更,则会推送给订阅的Consumer。
  4. Consumer可以发起RPC调用,在RPC调用的前后会向监控中心上报统计信息(并发数、调用的接口等)。

1.2 Dubbo的特性

从官网的文档来看,Dubbo的特性是非常丰富的,比如:

  • 面向接口代理的高性能RPC调用。

提供高性能的基于代理的远程调用能力,服务以接口为粒度。

  • 服务自动注册与发现。

支持多种注册中心服务,服务实例上下线实时的感知。

  • 运行期流量的调度。

内置条件、脚本等路由策略,可以通过配置不同的路由规则,实现灰度发布、同机房优先等功能。

  • 智能的负载均衡。

内置多种负载均衡策略,智能感知下游节点的健康状况,显著减少调用延迟,提高系统吞吐量。

  • 高度可扩展能力。

遵循微内核+插件的设计思想,所有核心能力,例如:Protocol、Transport、Serialization。都被设计为扩展点,平等对待内置的实现和第三方实现。

  • 可视化的服务治理和运维。

提供丰富的服务治理、运维工具。随时查询服务的元数据、服务健康状态和调用统计。

1.3 Dubbo总体分层

Dubbo总体上可以分成三层(细分则10层):

  • 业务层(Biz):Service。
  • RPC层:Config、Proxy、Registry、Cluster、Monitor、Protocol。
  • Remote层:Exchange、Transport、Serialize。

如下:
在这里插入图片描述
表面上(即对于我们使用者而言)可以分为:
API层:包括Service和Config两层,因为我们使用者在用Dubbo的时候,只需要进行相关的配置和编写业务代码即可。
SPI层:剩余的所有层结合在一起,主要提供给扩展者使用,即用户可以基于Dubbo做一个二次开发,扩展功能。

具体的每一层做什么,则在下文一一列举。

1.3.1 Dubbo核心组件

上文的每一层其实就是一个个组件,是这些不同的组件构成了整个Dubbo框架。

层次名作用
Service业务层,负责业务代码的编写
Config配置层,负责暴露的服务配置和引用的服务配置,初始化配置信息,负责管理整个Dubbo的配置
Proxy服务代理层,负责自动做远程调用并返回结果,无论是生产者还是消费者,都会生成一个代理类
Registry注册层,负责Dubbo的服务注册和发现。服务的上下线由注册中心感知并且通知给订阅方
Cluster集群容错层,负责调用失败时的容错策略,选择具体调用节点时的负载均衡策略,特殊调用路径的路由策略
Monitor监控层,负责监控统计调用次数和调用时间等信息
Protocol远程调用层,封装RPC调用的具体过程,是Invoker暴露(服务暴露)和引用(引用一个服务到本地)的主功能入口。
Exchange信息交换层,建立Request-Response模型,封装请求的响应模式
Transport网络传输层,将网络传输抽象为统一的接口
Serialize序列化层,若数据要通过网络进行发送,那么需要先做序列化,变成二进制流

注1(集群容错层):

容错策略:失败重试、快速失败等。
负载均衡策略:随机、一致Hash等。
路由策略:某个消费者只会调用某个IP的生产者等

注2(远程调用层):

1.远程调用层负责管理Invoker的整个生命周期。
2.Invoker是Dubbo的一个核心模型,框架中所有的其他模型都向他靠拢或者转换成他,他代表一个可执行体、
3.允许向Invoker发起一个Invoke调用,Invoker可能是执行一个本地的接口实现、远程实现、集群实现。

1.3.2 Dubbo总体调用过程

首先说下几个重要组件的含义:

  • Proxy组件:Dubbo中需要引用一个接口就可以调用远程的服务。而具体实施时Dubbo为我们生成了一个代理类,调用到方法其实是Proxy组件生成的代理方法,它会自动的发起远程/本地的调用,并返回结果(该过程对用户而言透明)。

  • Protocol组件:是对数据格式统一的一种规定。可以把我们对接口的配置根据不同的协议转换成不同的Invoker对象。

  • Exporter组件:用于暴露到注册中心的对象,他的内部属性中持有Invoker对象。即Invoker的一个二次封装。

  • Registry组件:将Exporter注册到注册中心上。

因此先来看看服务暴露的过程:

  1. 服务端启动时,初始化服务实例,通过Proxy组件调用具体协议(Protocol),将服务端要暴露的接口封装成Invoker(AbstractProxyInvoker对象),然后转换成Exporter。
  2. 框架打开服务端口等并记录服务实例到内存中
  3. 通过Registry将服务元数据注册到注册中心中。

再来看看服务调用的过程:

  1. 前面说过,调用时我们是调用了Proxy的代理方法,而Proxy持有一个Invoker对象。
  2. 然后出发invoke调用,调用过程中,则需要使用Cluster(负责容错)。
  3. Cluster在调用之前会通过Directory获取所有可以调用的远程服务Invoker列表。
  4. 若用户配置了路由规则,那么根据路由规则将Invoker列表进行过滤。
  5. 通过LoadBalance方法做负载均衡,最终选出一个可以调用的Invoker,而该Invoker在调用之前又会经过一个消费者端过滤器链(处理上下文信息、限流、计数等)。
  6. 使用Client进行数据传输,例如Netty Client等。其中会先进行私有协议的构造(调用Codec接口),再对数据包进行序列化处理,然后传输到服务提供者端。
  7. 服务提供者收到数据包后,同样使用Codec接口进行相应的数据处理,处理后再做反序列化处理。
  8. 随后该Request请求被分配到线程池中进行处理,Server根据请求查找对应的Exporter(内部封装了Invoker),并同样经历服务者端过滤器链,最后调用方法得到最终的结果后,原路将结果返回。

二. Dubbo的基本使用

1.首先看下项目的大致结构:
在这里插入图片描述
2.父类dubbo-demo的pom文件:

<modules>
    <module>demo-interface</module>
    <module>demo-provider-xml</module>
    <module>demo-consumer-xml</module>
    <module>demo-provider-api</module>
    <module>demo-consumer-api</module>
    <module>demo-consumer-annotate</module>
    <module>demo-provider-annotate</module>
</modules>
<properties>
    <source.level>1.8</source.level>
    <target.level>1.8</target.level>
    <spring.version>4.3.16.RELEASE</spring.version>
    <dubbo.version>2.6.3</dubbo.version>
    <dubbo.rpc.version>2.6.3</dubbo.rpc.version>
    <curator.version>2.12.0</curator.version>
    <validation-api.version>1.1.0.Final</validation-api.version>
    <hibernate-validator.version>4.2.0.Final</hibernate-validator.version>
    <resteasy.version>3.0.19.Final</resteasy.version>
    <curator-client.version>2.12.0</curator-client.version>
    <swagger.version>1.5.19</swagger.version>
    <spring-boot.version>1.5.13.RELEASE</spring-boot.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-framework-bom</artifactId>
            <version>${spring.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>${dubbo.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo-rpc-rest</artifactId>
            <version>${dubbo.rpc.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>${curator.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>${validation-api.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>${hibernate-validator.version}</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jackson-provider</artifactId>
            <version>${resteasy.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-client</artifactId>
            <version>${curator-client.version}</version>
        </dependency>
        <!-- swagger -->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>${swagger.version}</version>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-jaxrs</artifactId>
            <version>${swagger.version}</version>
        </dependency>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <exclusions>
            <exclusion>
                <groupId>io.netty</groupId>
                <artifactId>netty</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
    </dependency>
</dependencies>

3.提供的接口如下:
在这里插入图片描述
因为消费者生产者都需要到调用到这个UserService接口,因此将它单独做成一个maven项目,让两方的pom文件都引入即可。(也可以打成jar的形式)

public interface UserService {
    String getName(String name);
}

2.1 基于XML实现远程调用

2.1.1 搭建生产者-XML

1.搭建生产者demo-provider-xml,项目结构如下:
在这里插入图片描述
2.pom文件如下,引入接口项目就行,所需的依赖在其父项目dubbo-demo中已经添加了:

<dependencies>
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>demo-interface</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

3.接口的实现类:

public class UserServiceImpl implements UserService {
    @Override
    public String getName(String name) {
        String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        System.out.println(now + ":" + name);
        return name;
    }
}

4.启动类:

public class XmlProvider {
    public static void main(String[] args) throws Exception {
        // #1 指定服务暴露配置文件
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"provider.xml"});
        // #2 启动spring容器并暴露服务
        context.start();

        System.in.read();
    }
}

5.配置文件provider.xml注意改你的zookeeper地址):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- 服务提供方应用名称, 方便用于依赖跟踪 -->
    <dubbo:application name="demo-provider-xml"/>

    <!-- 使用zookeeper作为注册中心,注意改成你自己的IP地址 -->
    <dubbo:registry address="zookeeper://192.168.237.130:2181"/>

    <!-- 只用Dubbo协议并且指定监听端口 20880 -->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!-- 通过xml方式配置为bean, 让spring托管和实例化 -->
    <bean id="userService" class="com.pro.impl.UserServiceImpl"/>

    <!-- 声明服务暴露的接口,并暴露服务 -->
    <dubbo:service interface="com.pro.service.UserService" ref="userService"/>
</beans>

2.1.2 搭建消费者-XML

1.搭建消费者demo-consumer-xml,项目结构如下:
在这里插入图片描述
2.pom文件如上:

<dependencies>
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>demo-interface</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

3.配置文件consumer.xml注意改你的zookeeper地址):

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- 服务消费方应用名称, 方便用于依赖跟踪 -->
    <dubbo:application name="demo-consumer-xml"/>

    <!-- 使用zookeeper作为注册中心,注意改成你自己的IP地址 -->
    <dubbo:registry address="zookeeper://192.168.237.130:2181"/>

    <!-- 指定要消费的服务 -->
    <dubbo:reference id="userService" check="false" interface="com.pro.service.UserService"/>

</beans>

4.启动类:

public class XmlConsumer {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"consumer.xml"});
        context.start();
        UserService userService = (UserService) context.getBean("userService"); // get remote service proxy

        String status = userService.getName("张三");
        System.out.println("远程调用结果:" + status);
    }
}

最后,先启动好生产者provider-xml,再启动消费者consumer-xml
结果如下(服务端):
在这里插入图片描述
消费端:
在这里插入图片描述

2.2 基于注解实现远程调用

pom文件与上文都一致(2.3节不再重复说明)

2.2.1 搭建生产者-annotate

1.搭建demo-provider-annotate,项目结构:
在这里插入图片描述
2.实现类:

import com.pro.service.UserService;
// 注意这里不是Spring下的Service注解,是dubbo下面的Service注解。
import com.alibaba.dubbo.config.annotation.Service;

import java.text.SimpleDateFormat;
import java.util.Date;

@Service
public class UserServiceImpl implements UserService {
    @Override
    public String getName(String name) {
        String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        System.out.println(now + ":" + name);
        return name;
    }
}

3.启动类AnnotateProvider注意改你的zookeeper地址):

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.ProviderConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

public class AnnotateProvider {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class);
        context.start();
        System.in.read();
    }
    @Configuration
    // #1 指定扫描服务的位置
    @EnableDubbo(scanBasePackages = "com.pro")
    static class ProviderConfiguration {
        @Bean
        public ProviderConfig providerConfig() {
            return new ProviderConfig();
        }

        @Bean
        public ApplicationConfig applicationConfig() {
            ApplicationConfig applicationConfig = new ApplicationConfig();
            applicationConfig.setName("demo-annotation-provider");
            return applicationConfig;
        }

        @Bean
        public RegistryConfig registryConfig() {
            RegistryConfig registryConfig = new RegistryConfig();
            // #2 使用zookeeper作为注册中心,同时给出注册中心ip和端口
            registryConfig.setProtocol("zookeeper");
            registryConfig.setAddress("192.168.237.130");
            registryConfig.setPort(2181);
            return registryConfig;
        }

        @Bean
        public ProtocolConfig protocolConfig() {
            ProtocolConfig protocolConfig = new ProtocolConfig();
            // #3 默认服务使用dubbo协议,在20880监听服务
            protocolConfig.setName("dubbo");
            protocolConfig.setPort(20880);
            return protocolConfig;
        }
    }
}

2.2.2 搭建消费者-annotate

1.搭建demo-consumer-annotate,项目结构如下:
在这里插入图片描述
2.UserConsumer

import com.alibaba.dubbo.config.annotation.Reference;
import com.pro.service.UserService;
import org.springframework.stereotype.Component;

@Component
public class UserConsumer {
    @Reference
    private UserService userService;

    public String getName(String name) {
        return userService.getName(name);
    }
}

3.启动类AnnotateConsumer注意改你的zookeeper地址):

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import com.pro.refer.UserConsumer;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

public class AnnotateConsumer {
    public static void main(String[] args) {
        // #1 基于注解配置初始化spring上下文
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class);
        context.start();
        // #2 发起服务调用
        UserConsumer userConsumer = context.getBean(UserConsumer.class);
        String name = userConsumer.getName("张三");
        System.out.println("result: " + name);
    }

    @Configuration
    // #3 指定要扫描的消费注解,会触发注入
    @EnableDubbo(scanBasePackages = "com.pro")
    @ComponentScan(value = {"com.pro"})
    static class ConsumerConfiguration {
        @Bean
        public ApplicationConfig applicationConfig() {
            ApplicationConfig applicationConfig = new ApplicationConfig();
            applicationConfig.setName("demo-annotation-consumer");
            return applicationConfig;
        }

        @Bean
        public ConsumerConfig consumerConfig() {
            return new ConsumerConfig();
        }

        @Bean
        public RegistryConfig registryConfig() {
            RegistryConfig registryConfig = new RegistryConfig();
            // #4 使用zookeeper作为注册中心,同时给出注册中心ip和端口
            registryConfig.setProtocol("zookeeper");
            registryConfig.setAddress("192.168.237.130");
            registryConfig.setPort(2181);
            return registryConfig;
        }
    }
}

2.3 基于API实现远程调用

2.3.1 搭建生产者-api

1.项目结构:
在这里插入图片描述
2.实现类:

public class UserServiceImpl implements UserService {
    @Override
    public String getName(String name) {
        String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        System.out.println(now + ":" + name);
        return name;
    }
}

3.启动类APIProvider

public class APIProvider {
    public static void main(String[] args) throws IOException {
        ServiceConfig<UserService> service = new ServiceConfig<>();
        service.setApplication(new ApplicationConfig("java-demo-provider"));
        service.setRegistry(new RegistryConfig("zookeeper://192.168.237.130:2181"));
        service.setInterface(UserService.class);
        service.setRef(new UserServiceImpl());
        service.export();
        System.out.println("java-echo-provider is running.");
        System.in.read();
    }
}

2.3.2 搭建消费者-api

1.项目结构:
在这里插入图片描述
2.启动类APIConsumer

public class APIConsumer {
    public static void main(String[] args) {
        ReferenceConfig<UserService> reference = new ReferenceConfig<>();
        // #1 设置消费方应用名称
        reference.setApplication(new ApplicationConfig("java-demo-consumer"));
        // #2 设置注册中心地址和协议
        reference.setRegistry(new RegistryConfig("zookeeper://192.168.237.130:2181"));
        // #3 指定要消费的服务接口
        reference.setInterface(UserService.class);
        // #4 创建远程连接并做动态代理转换
        UserService greetingsService = reference.get();
        String message = greetingsService.getName("张三");
        System.out.println(message);
    }
}

三. Dubbo整合SpringBoot

3.1 搭建provider

1.项目结构:
在这里插入图片描述

2.pom文件(引入第二节中的demo-interface项目):

<parent>
   <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>demo-interface</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <!--引入dubbo环境-->
    <dependency>
        <groupId>com.alibaba.boot</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>0.2.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

3.实现类:

import com.pro.service.UserService;
import com.alibaba.dubbo.config.annotation.Service;

import java.text.SimpleDateFormat;
import java.util.Date;

@Service
public class UserServiceImpl implements UserService {
    @Override
    public String getName(String name) {
        String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        System.out.println(now + ":" + name);
        return name;
    }
}

4.启动类:

@SpringBootApplication
@EnableDubbo
public class ProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }
}

5.配置文件:

spring.application.name=boot-provider
#注册中心地址
dubbo.registry.address=zookeeper://192.168.237.130:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
#指定注册到zk上超时时间,ms
dubbo.registry.timeout=10000
#指定实现服务(提供服务)的包
dubbo.scan.base-packages=com.pro
dubbo.application.name=dubbo-provider

3.2 搭建consumer

1.项目结构:
在这里插入图片描述
2.pom文件同上,配置文件如下:

spring.application.name=boot-consumer
#注册中心地址
dubbo.registry.address=zookeeper://192.168.237.130:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
#指定注册到zk上超时时间,ms
dubbo.registry.timeout=10000
#指定实现服务(提供服务)的包
dubbo.scan.base-packages=com.pro
dubbo.application.name=dubbo-consumer

server.port=8000

3.Service层;

import com.alibaba.dubbo.config.annotation.Reference;
import com.pro.service.UserService;
import org.springframework.stereotype.Component;

@Component
public class MyConsumer {
    @Reference
    UserService userService;

    public String getName(String name){
        return userService.getName(name);
    }
}

4.Controller层:

import com.pro.comsumer.service.MyConsumer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {
    @Autowired
    MyConsumer consumer;

    @GetMapping("/{name}")
    public String test(@PathVariable("name") String name) {
        return "远程调用成功!结果:"+consumer.getName(name);
    }
}

5.启动类:

@SpringBootApplication
@EnableDubbo
public class ComsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ComsumerApplication.class, args);
    }
}

完成好后,先启动Provider,在启动Consumer,接着访问路径http://localhost:8000/张三

在这里插入图片描述

文章到这里就结束了,其实,这篇文章并没有涉及太多底层原理的部分,只说明了几个基本的知识点以及Dubbo的用法。我只是希望借此来开个头,对于源码或是重点的分析则放到后续几篇文章来说。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Zong_0915

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

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

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

打赏作者

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

抵扣说明:

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

余额充值