dubbo之入门

1:dubbo是什么?

dubbo的是一个基于Java开发的高性能rpc框架,提供了3大功能,如下:

1:基于接口的远程方法调用(依赖于netty)
2:智能容错和负载均衡
3:服务的注册和发现(依赖于zk,nacos等三方组件)

2:dubbo有什么?

在dubbo中一个有5大角色,分别是注册中心Registry,服务提供者Provider,服务消费者Consumer,监控中心Monitor,服务运行容器Container,三者的功能如下:

Registry:服务提供者注册自己的服务,服务消费者发现服务
Provider:提供服务,并将自己的信息注册到Registry
Consumer:服务的调用方,从Registry中获取Provider的信息,直接调用服务
Monitor:统计服务的调用次数,调用时间等信息
Container:启动Provider

需要我们进行编码的只有Provider和Consumer这2个角色,本文我们来重点分析二者。各种的关系可以用下图来表示:

在这里插入图片描述

接下来我们通过xml配置方式和注解配置方式来看下dubbo的基本搭建和使用。

3:XML方式配置

需要依赖zk,关于zk的安装可以参考这篇文章
源码

本实例,我们会定义3个项目,最终效果如下:

在这里插入图片描述

rpc-service-api:用于提供服务的公共接口定义
rpc-service-consumer:服务消费者项目
rpc-service-provider:服务提供者项目

3.1:rpc-service-api

3.1.1:UserDTO
// 因为dubbo的rpc调用涉及到对象的序列化和反序列化,所以需要实现java.io.Serializable接口
public class UserDTO implements Serializable {
    /**
     * 用户编号
     */
    private Integer id;
    /**
     * 昵称
     */
    private String name;
    /**
     * 性别
     */
    private Integer gender;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getGender() {
        return gender;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "UserDTO{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender=" + gender +
                '}';
    }
}
3.1.2:接口定义
public interface UserRpcService {

    /**
     * 根据指定用户编号,获得用户信息
     *
     * @param id 用户编号
     * @return 用户信息
     */
    UserDTO get(Integer id);

}
3.1.3:pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>dubbo-helloworld-with-xml</artifactId>
        <groupId>dongshi.daddy</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>rpc-service-api</artifactId>


</project>

3.2:rpc-service-provider

3.2.1:pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>dubbo-helloworld-with-xml</artifactId>
        <groupId>dongshi.daddy</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>rpc-service-provider</artifactId>

    <dependencies>
        <!-- 引入定义的 Dubbo API 接口 -->
        <dependency>
            <groupId>dongshi.daddy</groupId>
            <artifactId>rpc-service-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!-- 引入 Spring Boot 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!-- 实现对 Dubbo 的自动化配置 -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.7.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.4.1</version>
        </dependency>

        <!-- 使用 Zookeeper 作为注册中心 -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.13.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.13.0</version>
        </dependency>

    </dependencies>
</project>
3.2.2:配置文件

resources/application.yml:

# dubbo 配置项,对应 DubboConfigurationProperties 配置类
dubbo:
  # Dubbo 应用配置
  application:
    name: user-service-provider # 应用名
  # Dubbo 注册中心配
  registry:
    address: zookeeper://127.0.0.1:2181 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。
  # Dubbo 服务提供者协议配置
  protocol:
    port: -1 # 协议端口。使用 -1 表示随机端口。
    name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档
  # Dubbo 服务提供者配置
  provider:
    timeout: 1000 # 【重要】远程服务调用超时时间,单位:毫秒。默认为 1000 毫秒,胖友可以根据自己业务修改
    UserRpcService:
      version: 1.0.0

resources/dubbo.xml:

<?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:service ref="userRpcServiceImpl" interface="dongshi.daddy.api.UserRpcService"
                   version="${dubbo.provider.UserRpcService.version}" />
</beans>

使用了dubbo的自定义标签dubbo:service

3.2.3:服务实现类
@Service
public class UserRpcServiceImpl implements UserRpcService {

    @Override
    public UserDTO get(Integer id) {
        /*return new UserDTO().setId(id)
                .setName("没有昵称:" + id)
                .setGender(id % 2 + 1); // 1 - 男;2 - 女*/
        UserDTO userDTO = new UserDTO();
        userDTO.setId(id);
        userDTO.setName("没有昵称:" + id);
        userDTO.setGender(id % 2 + 1);
        return userDTO;
    }

}
3.2.4:启动类
@SpringBootApplication
@ImportResource("classpath:dubbo.xml")
public class ProviderApplication {

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

使用了@ImportResource 来导入bubbo.xml配置文件。

启动后输出如下的日志信息,则说明成功了:

...
2021-11-09 18:20:04.719  INFO 17800 --- [pool-1-thread-1] .b.c.e.AwaitingNonWebApplicationListener :  [Dubbo] Current Spring Boot Application is await...

从zk查看注册的信息:

D:\program_files\zookeeper-3.4.12\bin>zkCli.cmd
Connecting to localhost:2181
...
[zk: localhost:2181(CONNECTED) 0] ls /dubbo
[dongshi.daddy.api.UserRpcService]
[zk: localhost:2181(CONNECTED) 1] ls /dubbo/dongshi.daddy.api.UserRpcService
[consumers, routers, providers, configurators]
[zk: localhost:2181(CONNECTED) 2] ls /dubbo/dongshi.daddy.api.UserRpcService/providers
[dubbo%3A%2F%2F192.168.10.119%3A20881%2Fdongshi.daddy.api.UserRpcService%3Fanyhost%3Dtrue%26application%3Duser-service-provider%26bean.name%3Ddongshi.daddy.api.UserRpcService%26deprecated%3Dfalse%26dubbo%3D2.0.2%26dynamic%3Dtrue%26generic%3Dfalse%26interface%3Ddongshi.daddy.api.UserRpcService%26methods%3Dget%26pid%3D17800%26release%3D2.7.4.1%26revision%3D1.0.0%26side%3Dprovider%26timeout%3D1000%26timestamp%3D1636453204287%26version%3D1.0.0]
[zk: localhost:2181(CONNECTED) 3]

3.3:rpc-service-consumer

3.3.1:pom
<dependencies>
    <!-- 引入定义的 Dubbo API 接口 -->
    <dependency>
        <groupId>dongshi.daddy</groupId>
        <artifactId>rpc-service-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

    <!-- 引入 Spring Boot 依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <!-- 实现对 Dubbo 的自动化配置 -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.7.4.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.4.1</version>
    </dependency>

    <!-- 使用 Zookeeper 作为注册中心 -->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>2.13.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>2.13.0</version>
    </dependency>

</dependencies>
3.3.2:配置文件

resource/application.yml:

# dubbo 配置项,对应 DubboConfigurationProperties 配置类
dubbo:
  # Dubbo 应用配置
  application:
    name: user-service-consumer # 应用名
  # Dubbo 注册中心配置
  registry:
    address: zookeeper://127.0.0.1:2181 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。
  # Dubbo 消费者配置
  consumer:
    timeout: 1000 # 【重要】远程服务调用超时时间,单位:毫秒。默认为 1000 毫秒,胖友可以根据自己业务修改
    UserRpcService:
      version: 1.0.0

resource/dubbo.yml:

<?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:reference id="userService" interface="dongshi.daddy.api.UserRpcService"
                     version="${dubbo.consumer.UserRpcService.version}"/>

</beans>

创建了名称为userService的spring bean,就可以像使用本地的一个spring bean一样来调用方法了,内部通过netty的长连接就可以调用到服务提供者的服务了。

3.3.3:启动类
@SpringBootApplication
@ImportResource("classpath:dubbo.xml")
public class ConsumerApplication {

    public static void main(String[] args) {
        // 启动 Spring Boot 应用
        ConfigurableApplicationContext context = SpringApplication.run(ConsumerApplication.class, args);
    }

    @Component
    public class UserRpcServiceTest implements CommandLineRunner {

        private final Logger logger = LoggerFactory.getLogger(getClass());

        @Resource
        private UserRpcService userRpcService;

        @Override
        public void run(String... args) throws Exception {
            UserDTO user = userRpcService.get(1);
            logger.info("[run][发起一次 Dubbo RPC 请求,获得用户为({})", user);
        }

    }

}

这里使用CommandLineRunner只是为了方便启动时就看到调用的效果。

启动后查看zk的注册信息:

D:\program_files\zookeeper-3.4.12\bin>zkCli.cmd
Connecting to localhost:2181
...
[zk: localhost:2181(CONNECTED) 3] ls /
[dubbo, zookeeper]
[zk: localhost:2181(CONNECTED) 4] ls /dubbo
[dongshi.daddy.api.UserRpcService]
[zk: localhost:2181(CONNECTED) 5] ls /dubbo/dongshi.daddy.api.UserRpcService
[consumers, routers, providers, configurators]
[zk: localhost:2181(CONNECTED) 7] ls /dubbo/dongshi.daddy.api.UserRpcService/consumers
[consumer%3A%2F%2F192.168.10.119%2Fdongshi.daddy.api.UserRpcService%3Fapplication%3Duser-service-consumer%26category%3Dconsumers%26check%3Dfalse%26dubbo%3D2.0.2%26interface%3Ddongshi.daddy.api.UserRpcService%26lazy%3Dfalse%26methods%3Dget%26pid%3D18988%26qos.enable%3Dfalse%26release%3D2.7.4.1%26revision%3D1.0.0%26side%3Dconsumer%26sticky%3Dfalse%26timeout%3D1000%26timestamp%3D1636454208368%26version%3D1.0.0]
[zk: localhost:2181(CONNECTED) 8]

如果看到如下的输出信息,则说明调用成功了:

...
2021-11-09 18:36:49.191  INFO 18988 --- [           main] c.ConsumerApplication$UserRpcServiceTest : [run][发起一次 Dubbo RPC 请求,获得用户为(UserDTO{id=1, name='没有昵称:1', gender=2})
2021-11-09 18:36:49.193  INFO 18988 --- [pool-1-thread-1] .b.c.e.AwaitingNonWebApplicationListener :  [Dubbo] Current Spring Boot Application is await...

4:注解方式配置

需要依赖zk,关于zk的安装可以参考这篇文章
源码

本实例,我们会定义3个项目,最终效果如下:
在这里插入图片描述

rpc-service-api-02:用于提供服务的公共接口定义
rpc-service-consumer-02:服务消费者项目
rpc-service-provider-02:服务提供者项目

4.1:rpc-service-api-02

4.1.1 UserDTO
// 因为dubbo的rpc调用涉及到对象的序列化和反序列化,所以需要实现java.io.Serializable接口
public class UserDTO implements Serializable {
    /**
     * 用户编号
     */
    private Integer id;
    /**
     * 昵称
     */
    private String name;
    /**
     * 性别
     */
    private Integer gender;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getGender() {
        return gender;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "UserDTO{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender=" + gender +
                '}';
    }
}
4.1.2 UserRpcService
public interface UserRpcService {

    /**
     * 根据指定用户编号,获得用户信息
     *
     * @param id 用户编号
     * @return 用户信息
     */
    UserDTO get(Integer id);

}

4.2: rpc-service-provider-02

4.2.1: pom
<dependencies>
    <!-- 引入定义的 Dubbo API 接口 -->
    <dependency>
        <groupId>dongshi.daddy</groupId>
        <artifactId>rpc-service-api-02</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

    <!-- 引入 Spring Boot 依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <!-- 实现对 Dubbo 的自动化配置 -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.7.4.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.4.1</version>
    </dependency>

    <!-- 使用 Zookeeper 作为注册中心 -->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>2.13.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>2.13.0</version>
    </dependency>

</dependencies>
4.2.2 application.yml
# dubbo 配置项,对应 DubboConfigurationProperties 配置类
dubbo:
  # Dubbo 应用配置
  application:
    name: user-service-provider02 # 应用名
  # Dubbo 注册中心配
  registry:
    address: zookeeper://127.0.0.1:2181 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。
  # Dubbo 服务提供者协议配置
  protocol:
    port: -1 # 协议端口。使用 -1 表示随机端口。
    name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档
  # Dubbo 服务提供者配置
  provider:
    timeout: 1000 # 【重要】远程服务调用超时时间,单位:毫秒。默认为 1000 毫秒,胖友可以根据自己业务修改
    UserRpcService:
      version: 1.0.0
  # 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者
  scan:
    base-packages: dongshi.daddy.service

注意这里增加了dubbo.scan.base-packages定义了服务提供类的自动扫描路径,需要配合dubbo的自定义注解org.apache.dubbo.config.annotation.Service使用。所以就不需要bubbo.xml了。

3.2.3: UserRpcServiceImpl
@Service(version = "${dubbo.provider.UserRpcService.version}")
public class UserRpcServiceImpl implements UserRpcService {

    @Override
    public UserDTO get(Integer id) {
        /*return new UserDTO().setId(id)
                .setName("没有昵称:" + id)
                .setGender(id % 2 + 1); // 1 - 男;2 - 女*/
        UserDTO userDTO = new UserDTO();
        userDTO.setId(id);
        userDTO.setName("没有昵称:" + id);
        userDTO.setGender(id % 2 + 1);
        return userDTO;
    }
}

注意这里的@Service注解是dubbo自定义的org.apache.dubbo.config.annotation.Service,而非spring中的org.springframework.stereotype.Service

4.2.4: ProviderApplication
@SpringBootApplication
// @ImportResource("classpath:dubbo.xml")
public class ProviderApplication {

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

这里就不需要@ImportResource注解来引入xml配置文件了,因为使用了基于注解的自动扫描。

启动,如下就是启动成功了:

...
2021-11-10 11:17:20.033  INFO 17332 --- [pool-1-thread-1] .b.c.e.AwaitingNonWebApplicationListener :  [Dubbo] Current Spring Boot Application is await...

5.3: rpc-service-consumer-02

5.3.1: pom
<dependencies>
    <!-- 引入定义的 Dubbo API 接口 -->
    <dependency>
        <groupId>dongshi.daddy</groupId>
        <artifactId>rpc-service-api-02</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

    <!-- 引入 Spring Boot 依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <!-- 实现对 Dubbo 的自动化配置 -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.7.4.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.4.1</version>
    </dependency>

    <!-- 使用 Zookeeper 作为注册中心 -->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>2.13.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>2.13.0</version>
    </dependency>
</dependencies>
5.3.2 application.yml
# dubbo 配置项,对应 DubboConfigurationProperties 配置类
dubbo:
  # Dubbo 应用配置
  application:
    name: user-service-consumer02 # 应用名
  # Dubbo 注册中心配置
  registry:
    address: zookeeper://127.0.0.1:2181 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。
  # Dubbo 消费者配置
  consumer:
    timeout: 1000 # 【重要】远程服务调用超时时间,单位:毫秒。默认为 1000 毫秒,胖友可以根据自己业务修改
    UserRpcService:
      version: 1.0.0
5.3.3 ConsumerApplication
@SpringBootApplication
//@ImportResource("classpath:dubbo.xml")
public class ConsumerApplication {

    public static void main(String[] args) {
        // 启动 Spring Boot 应用
        ConfigurableApplicationContext context = SpringApplication.run(ConsumerApplication.class, args);
    }

    @Component
    public class UserRpcServiceTest implements CommandLineRunner {

        private final Logger logger = LoggerFactory.getLogger(getClass());

        // @Resource
        @Reference(version = "${dubbo.consumer.UserRpcService.version}")
        private UserRpcService userRpcService;

        @Override
        public void run(String... args) throws Exception {
            UserDTO user = userRpcService.get(1);
            logger.info("[run][发起一次 Dubbo RPC 请求,获得用户为({})", user);
        }

    }

}

这里就不需要@ImportResource注解来引入dubbo.xml了,并且通过dubbo的自定义注解com.alibaba.dubbo.config.annotation.Reference来引用用来调用dubbo服务提供者服务的spring bean。

启动,如下就是启动并调用成功了:

2021-11-10 11:47:22.914  INFO 22476 --- [           main] dongshi.daddy.ConsumerApplication        : Started ConsumerApplication in 1.537 seconds (JVM running for 2.054)
2021-11-10 11:47:22.967  INFO 22476 --- [           main] d.ConsumerApplication$UserRpcServiceTest : [run][发起一次 Dubbo RPC 请求,获得用户为(UserDTO{id=1, name='没有昵称:1', gender=2})
2021-11-10 11:47:22.969  INFO 22476 --- [pool-1-thread-1] .b.c.e.AwaitingNonWebApplicationListener :  [Dubbo] Current Spring Boot Application is await...
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值