Dubbo学习笔记(一) 基础知识HelloWorld
阅读原文时间:2022年04月18日阅读:1

Dubbo是由阿里巴巴研发出的一款基于Java实现的RPC框架,现由Apache进行维护管理,笔记中使用zookeeper作为注册中心,dubbo+zookeeper环境安装教程:https://www.cnblogs.com/hanzhe/p/14225399.html

Dubbo笔记基于尚硅谷雷丰阳老师教程的简单总结,教程视频地址:https://www.bilibili.com/video/BV1ns411c7jV


RPC指的是远程调用,简单理解就是我们所写的程序,可以将Controller与Service层分别分放到不同的服务器上运行,通过服务器A的Controller来调用服务器B或服务器C的Service:

Java代码实现远程调用

首先创建一个普通的maven工程,用来封装提供者和消费者都用得到的代码,这里命名为maven-01-api,工程中包含:

// 实体类,这里实体类必须实现序列化接口,否则远程调用失败!
public class UserEntity implements Serializable {
    private String name;
    private String age;
    private String gender;
    // get set toString.....
}


// 通用接口
public interface UserService {
    List<UserEntity> selectList();
}

首先需要引入dubbo相关的maven依赖:

<!-- Dubbo依赖 -->
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.7.5</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>5.1.0</version>
</dependency>
<!-- Zookeeper依赖 -->
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>4.2.0</version>
</dependency>
<!-- 以及编写的通用模块依赖 -->
<dependency>
    <groupId>site.hanzhe</groupId>
    <artifactId>maven-01-commen</artifactId>
    <version>0.0.1</version>
</dependency>

这样依赖提供者就拥有了Dubbo+zookeeper的环境以及实体类和接口了,接下来我们书写一个实现类:

public class UserServiceImpl implements UserService {
    @Override
    public List<UserEntity> selectList() {
        UserEntity entity1 = new UserEntity("马保国", "69", "男");
        UserEntity entity2 = new UserEntity("老八", "31", "男");
        return Arrays.asList(entity1, entity2);
    }
}

想要将服务注册到注册中心,还需要一个配置文件,在引入dubbo依赖的时候,dubbo就帮我们把spring的依赖也一同引入进来了,所以接下来的配置我们要在spring.xml文件中进行配置:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       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="maven-01-provider" />
    <!-- 注册中心地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />
    <!-- 配置通信协议以及当前服务端口号  -->
    <dubbo:protocol name="dubbo" port="20001"/>
    <!-- 配置一个bean -->
    <bean id="userService" class="site.hanzhe.service.impl.UserServiceImpl" />
    <!-- 暴露一个服务接口,对应的实现为userService -->
    <dubbo:service interface="site.hanzhe.service.UserService" ref="userService" />
</beans>

配置文件准备好之后,接下来就需要启动当前程序了,创建一个启动类:

public class Provider01Application {
    public static void main(String[] args) throws IOException {
        // 获取IOC容器并启动
        new ClassPathXmlApplicationContext("spring.xml").start();
        // 读取一个字符:起到阻塞作用防止程序结束运行
        System.in.read();
    }
}

接下来运行main方法,稍等片刻就可以在管理页面中看到注册进来的服务(不要忘记运行Zookeeper)

消费者需要添加的maven依赖同提供者一致,这里就不另写了,配置文件如下所示:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd
                http://code.alibabatech.com/schema/dubbo
                http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!-- 配置消费者应用名称 -->
    <dubbo:application name="maven-01-consumer" />
    <!-- 配置注册中心地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />
    <!-- 在注册中心引用UserService的实现 -->
    <dubbo:reference id="userService" interface="site.hanzhe.service.UserService" />
</beans>

注册中心配置完成之后,无需其他配置,直接在程序中调用即可:

public class Consumer01Application {
    public static void main(String[] args) throws IOException {
        // 启动IOC容器
        ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("spring.xml");
        // 在IOC中获取UserService的Bean
        UserService bean = (UserService) ioc.getBean("userService");
        // 调用接口中的方法
        System.out.println(bean.selectList());
    }
}

可以看到消费者中并没有书写接口的实现类,通过配置文件中的reference引用,从而实现了远程调用!

整合Springboot实现远程调用

Springboot整合Dubbo相比于maven工程简单了不少,这里使用的版本为Springboot2.4.0

首先先将配置搞定,配置信息与spring.xml差距不大:

# Dubbo相关配置
dubbo:
  # 当前应用名称
  application:
    name: boot-01-provider
  # 注册中心配置
  registry:
    protocol: zookeeper
    address: 127.0.0.1
    port: 2181
  # 通信规则
  protocol:
    name: dubbo
    port: 20002

还是先从服务提供者入手,这里肯定先要导入Dubbo的场景启动器了,除此之外commen模块也要导入进来:

<!--
  dubbo starter:
     boot1.5.*需要引用0.1.1版本的启动器
     boot2.0.*需要引用0.2.0版本的启动器
-->
<dependency>
    <groupId>com.alibaba.boot</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>0.2.0</version>
</dependency>
<!-- commen -->
<dependency>
    <groupId>site.hanzhe</groupId>
    <artifactId>maven-01-commen</artifactId>
    <version>0.0.1</version>
</dependency>

依赖引入完毕后,还是一样编写接口的实现类,需要注意的是@Service注解,相对于Java代码编写的Dubbo程序,boot程序将暴露接口的配置直接写在了类中:

// 这个Service注解代表添加到IOC容器
@Service
// 这个Service注解代表向Zookeeper暴露接口
@com.alibaba.dubbo.config.annotation.Service
public class UserServiceImpl implements UserService {
    @Override
    public List<UserEntity> selectList() {
        UserEntity entity1 = new UserEntity("马保国", "69", "男");
        UserEntity entity2 = new UserEntity("张全蛋", "31", "男");
        return Arrays.asList(entity1, entity2);
    }
}

实现类编写完成后,还需要在springboot启动类中使用@EnableDubbo注解来启动Dubbo

@EnableDubbo
@SpringBootApplication
public class Boot01ProviderApplication {
    public static void main(String[] args) {
        // 这里就不同在添加阻塞了,引入场景启动器后程序不会自动结束
        SpringApplication.run(Boot01ProviderApplication.class, args);
    }
}

程序运行起来我们就可以在管理页面看到该服务了:

消费者这边通过web工程进行测试,导入的依赖与服务提供者相同,就不再这里写了,配置文件如下所示:

# 因为Zookeeper会占用8080端口,所以这里将端口修改为8081
server:
  port: 8081
dubbo:
  application:
    name: boot-01-consumer
  registry:
    protocol: zookeeper
    address: 127.0.0.1
    port: 2181
  # 消费者无须提供服务,所以这里可以不配置protocol

然后在Controller中调用Service进行测试,一般来说应该使用@Autowired进行自动注入,这里使用@Reference进行远程调用:

@RestController
public class UserController {

    @Reference
    private UserService userService;

    @GetMapping("/selectUser")
    public List<UserEntity> selectUse() {
        return userService.selectList();
    }

}

经测试消费者可以不适用@EnableDubbo注解,直接启动程序访问接口即可