四时宝库

程序员的知识宝库

Dubbo快速入门(dubbo基础)

概述

Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载 Dubbo 的配置即可,Dubbo基于Spring的 Schema扩展 进行加载。

在应用中使用Dubbo,常用的方式有中三种方法,一种是API的方式,一种是注解,一种是Spring的xml配置。

下面将使用Spring的xml配置的方式演示如何快速的在应用中使用Dubbo。

准备工作

  • 环境

操作系统:Win10专业版

IDE:IDEA CE 2020.1

JDK:ORACLE JDK8

Maven :3.6.2

ZooKeeper:3.4.14

  • 需求

提供对用户的增删改查的服务。用户信息只有姓名、性别,根据id对用户进行删改查。简单起见,这里忽略权限认证等步骤。

  • 工程规划

根据微服务架构规划,定义三个工程,实际应用中,服务API和服务提供者,很多时候可能是合并在一起的。

服务API工程coffee-api

定义用户服务接口,由服务提供者实现,并由服务消费者引用。

服务提供者工程coffee-provider

实现用户服务,真正对外提供用户服务的应用。

服务消费者工程coffee-consumer

消费用户服务,实际应用中,可能是个人中心、也可能是登录认证中心等

搭建ZooKeeper注册中心

Dubbo可以是zookeeper也可以使用redis作为注册中心,这里使用zookeeper作为注册中心。

  • CentOS7虚拟机安装zookeeper
  • 下面是在Win10专业版中使用Hyper-V管理器创建的centos7.5虚拟机中安装zookeeper的简单步骤,供参考。假设虚拟主机ip为192.168.8.156,下面配置时会用到

    
    -- 下载zookeeper
    sudo wget https://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz
    
    --- 解压到/opt/apache目录下
    sudo mkdir /opt/apache
    sudo tar -vxzf zookeeper-3.4.14.tar.gz -C /opt/apache/
      
    -- 添加配置文件
    sudo cp /opt/apache/zookeeper-3.4.14/conf/zoo_sample.cfg  /opt/apache/zookeeper-3.4.14/conf/zoo.cfg
    
    -- 启动zookeeper
    cd /opt/apache/zookeeper-3.4.14/bin
    // -- 如果是window操作系统 直接运行zkServer.cmd即可
    sudo sh zkServer.sh start
    • Window安装zookeeper

    下载zookeeper压缩包后,window系统安装的话,直接解压到某个目录下即可。然后使用命令行工具运行bin目录下的zkServer.cmd即可启动zookeeper

    zkServer.cmdzkServer.cmd

    搭建服务API工程coffee-api

    使用IDEA创建Maven工程。由于工程只是定义用户服务API,也就是用户服务接口,所以并不需要引入Dubbo依赖。

    • 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">
        <modelVersion>4.0.0</modelVersion>
               
        <groupId>com.fandou.coffee</groupId>
    		<artifactId>coffee-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
    
    </project>
    • 定义用户服务接口

    用户服务接口如下

    package com.fandou.coffee.api.user;
    
    /**
     * 用户服务接口
     */
    public interface UserService {
        // 创建新用户
        void create(User user);
        // 更新用户信息
        void update(User user);
        // 根据id获取用户信息
        User get(int id);
        // 根据id删除用户
        void delete(int id);
    }

    还有一个用户信息接口

    /**
     * 基本用户信息接口
     */
    public interface User {
        // 唯一id
        int getId();
        void setId(int id);
    
        // 姓名
        String getName();
        void setName(String name);
    
        // 性别
        int getSex();
        void setSex(int sex);
    }

    另外,提供一个缺省的用户实现类

    package com.fandou.coffee.api.user;
    
    import java.io.Serializable;
    
    /**
     * 缺省用户实现类
     */
    public class DefaultUser implements User, Serializable {
        private int id;
        private String name;
        private int sex;
    
        @Override
        public int getId() {
            return id;
        }
    
        @Override
        public void setId(int id) {
            this.id = id;
        }
    
        @Override
        public String getName() {
            return name;
        }
    
        @Override
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public int getSex() {
            return sex;
        }
    
        @Override
        public void setSex(int sex) {
            this.sex = sex;
        }
    
        @Override
        public String toString() {
            return "{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", sex=" + sex +
                    '}';
        }
    }

    搭建服务提供者工程coffee-provider

    使用IDEA创建Maven工程。需要添加用户服务API和Dubbo、zookeeper客户端以及日志依赖。

  • 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">
        <modelVersion>4.0.0</modelVersion>
    
    		<groupId>com.fandou.coffee</groupId>
        <artifactId>coffee-provider</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <!-- 依赖coffee-api -->
            <dependency>
                <groupId>com.fandou.coffee</groupId>
                <artifactId>coffee-api</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
    
            <!-- 依赖dubbo -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo</artifactId>
                <version>2.7.7</version>
            </dependency>
    
            <!-- zookeeper客户端依赖 -->
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
                <version>2.13.0</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>2.13.0</version>
            </dependency>
    
            <!-- 日志 -->
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>1.2.3</version>
            </dependency>
    
        </dependencies>
    </project>
    • 实现用户服务
    package com.fandou.coffee.provider.user;
    
    import com.fandou.coffee.api.user.User;
    import com.fandou.coffee.api.user.UserService;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * 用户服务实现类
     */
    public class UserServiceImpl implements UserService {
        // 日志
        private static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
    
        @Override
        public void create(User user) {
            // TODO 实际开发应保存到数据库,这里只是模拟
            logger.info("创建用户成功 => {}",user);
        }
    
        @Override
        public void update(User user) {
            logger.info("更新用户成功 => {}",user);
        }
    
        @Override
        public User get(int id) {
            logger.info("查询用户信息 => {}",id);
            return null;
        }
    
        @Override
        public void delete(int id) {
            logger.info("用户已删除 => {}",id);
        }
    }
    • Spring配置

    在工程资源resources目录下创建spring目录,并在spring目录下创建xml配置文件user-service-provider.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">
    
        <!-- 服务提供方应用名称,方便用于依赖跟踪,另外,指定使用slf4j日志而非默认的log4j-->
        <dubbo:application name="user-service-provider.xml" logger="slf4j"/>
    
        <!-- 使用本地zookeeper作为注册中心 -->
        <dubbo:registry address="zookeeper://192.168.8.156:2181"/>
    
        <!-- 使用dubbo协议,不指定port属性,默认监听20880端口:协议可以不配置,默认dubbo协议及监听20880端口-->
        <dubbo:protocol name="dubbo" port="20880"/>
    
        <!-- 定义服务实现:通过xml方式配置userService的实现bean,让Spring托管和实例化 -->
        <bean id="userService" class="com.fandou.coffee.provider.user.UserServiceImpl"/>
    
        <!-- 定义要发布/提供的服务 -->
        <dubbo:service interface="com.fandou.coffee.api.user.UserService" ref="userService"/>
    
    </beans>
    • 服务提供者容器启动类
    package com.fandou.coffee.provider;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import java.io.IOException;
    
    /**
     * 启动服务提供者容器
     */
    public class Application {
        // 日志
        private static Logger logger = LoggerFactory.getLogger(Application.class);
    
        public static void main(String[] args) throws IOException {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring/user-service-provider.xml"});
            context.start();
            logger.info("用户服务提供者已启动...");
            System.in.read();
        }
    }
    • 日志文件

    在工程资源resources目录下日志配置文件logback.xml,配置如下

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    
        <appender name="DefaultConsoleAppender" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>[%d{HH:mm:ss.SSS,GMT+8}] %p %t %c{0}#%M@%L - %m%n</pattern>
                <charset class="java.nio.charset.Charset">UTF-8</charset>
            </encoder>
        </appender>
    
        <root>
            <level value="INFO"/>
            <appender-ref ref="DefaultConsoleAppender"/>
        </root>
    
        <!-- 关闭某个包下的日志 level="OFF" -->
        <logger name="io.netty" level="OFF" />
    
        <logger name="org.springframework" level="ERROR" />
    </configuration>

    搭建服务消费者工程coffee-consumer

    使用IDEA创建Maven工程。需要添加用户服务API和Dubbo、zookeeper客户端、日志、junit测试依赖,不需要依赖服务提供者。

    • 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">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.fandou.coffee</groupId>
        <artifactId>coffee-consumer</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <!-- 依赖coffee-api -->
            <dependency>
                <groupId>com.fandou.coffee</groupId>
                <artifactId>coffee-api</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
    
            <!-- 依赖dubbo -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo</artifactId>
                <version>2.7.7</version>
            </dependency>
    
            <!-- zookeeper客户端依赖 -->
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
                <version>2.13.0</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>2.13.0</version>
            </dependency>
    
            <!-- 日志 -->
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>1.2.3</version>
            </dependency>
    
            <!-- 测试 -->
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter-api</artifactId>
                <version>5.5.2</version>
                <scope>test</scope>
            </dependency>
    
        </dependencies>
    </project>

    消费用户服务

    package com.fandou.coffee.consumer.user.controller;
    
    import com.fandou.coffee.api.user.User;
    import com.fandou.coffee.api.user.UserService;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * 用户注册功能,将调用远程的用户服务来实现
     * 这里假设是SpringMVC的一个Controller类
     */
    public class UserController {
        // 日志
        private static Logger logger = LoggerFactory.getLogger(UserController.class);
    
        // 引用用户服务
        private UserService userService;
    
        /**
         * 注册一个新用户
         */
        public void registerUser(User user){
            logger.info("发起注册用户请求...");
            // 像本地方法一样调用远程服务
            userService.create(user);
            logger.info("注册用户请求完成...");
        }
    
        public UserService getUserService() {
            return userService;
        }
    
        public void setUserService(UserService userService) {
            this.userService = userService;
        }
    }
    

    Spring配置

    在工程资源resources目录下创建spring目录,并在spring目录下创建xml配置文件user-service-consumer.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:application name="user-service-consumer" logger="slf4j">
            <dubbo:parameter key="qos.enable" value="true" />
            <dubbo:parameter key="qos.accept.foreign.ip" value="false" />
            <!-- 配置QOS端口,由于服务提供方端已经使用了默认的22222,这里需要改用以下,否则在同一个机器同时将出现端口占用问题 -->
            <dubbo:parameter key="qos.port" value="33333" />
        </dubbo:application>
    
        <!-- 使用本地zookeeper作为注册中心 -->
        <dubbo:registry address="zookeeper://192.168.8.156:2181"/>
    
        <!-- 声明或指定要消费的服务 -->
        <dubbo:reference id="userService" check="false" interface="com.fandou.coffee.api.user.UserService"/>
    
        <!-- 本地服务中调用远程服务 -->
        <bean id="userController" class="com.fandou.coffee.consumer.user.controller.UserController">
            <property name="userService" ref="userService" />
        </bean>
    </beans>

    日志文件

    参考服务提供者工程coffee-provider。

    运行测试

    • 创建测试类

    在服务消费者工程coffee-consumer创建测试类UserControllerTest

    package com.fandou.coffee.consumer.user.controller;
    
    import com.fandou.coffee.api.user.DefaultUser;
    import com.fandou.coffee.api.user.User;
    import com.fandou.coffee.api.user.UserService;
    import org.junit.jupiter.api.Test;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    class UserControllerTest {
        // 日志
        private static Logger logger = LoggerFactory.getLogger(UserControllerTest.class);
    
        @Test
        void testRegisterUser(){
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring/echo-consumer.xml"});
            context.start();
            logger.info("用户服务消费方已启动...");
    
            // 消费方其它服务调用用户服务
            UserController userController = (UserController)context.getBean("userController");
            User user = new DefaultUser();
            user.setId(1);
            user.setName("蕃豆咖啡");
            user.setSex(1);
            userController.registerUser(user);
    
            // 任何地方都可以直接调用
            UserService userService = (UserService)context.getBean("userService");
            User anotherUser = new DefaultUser();
            anotherUser.setId(2);
            anotherUser.setName("Coffee");
            anotherUser.setSex(2);
            userService.create(anotherUser);
        }
    }
    • 运行测试

    首先,确保zookeeper正确启动,然后运行服务提供者容器启动类Application类(即启动服务),接着运行UserControllerTest测试,控制台正常打印如下信息,说明测试成功

    -- 服务消费者控制台打印
    ...
    [18:28:05.047] INFO main UserControllerTest#testRegisterUser@19 - 用户服务消费方已启动...
    [18:28:05.047] INFO main UserController#registerUser@25 - 发起注册用户请求...
    [18:28:05.372] INFO main UserController#registerUser@28 - 注册用户请求完成...
    ...
    
    --服务提供者控制台打印
    ...
    [18:27:41.703] INFO main Application#main@19 - 用户服务提供者已启动...
    [18:28:04.797] INFO NettyServerWorker-5-1 NettyServerHandler#channelActive@76 -  [DUBBO] The connection of /169.254.186.134:53913 -> /169.254.186.134:20880 is established., dubbo version: 2.7.7, current host: 192.168.8.100
    [18:28:05.328] INFO DubboServerHandler-169.254.186.134:20880-thread-2 UserServiceImpl#create@18 - 创建用户成功 => {id=1, name='蕃豆咖啡', sex=1}
    [18:28:05.372] INFO DubboServerHandler-169.254.186.134:20880-thread-3 UserServiceImpl#create@18 - 创建用户成功 => {id=2, name='Coffee', sex=2}
    ...

    总结

    在应用中集成Dubbo其实比较简单,特别和Spring一起使用,很快就可以上手,核心步骤就是规划好注册中心、定义好服务接口api、构建服务提供者、构建服务消费者。Dubbo还有很多高级特性,后续在使用过程中结合业务需要去熟悉和配置。

    #java开发工程师# #架构师#

    发表评论:

    控制面板
    您好,欢迎到访网站!
      查看权限
    网站分类
    最新留言
      友情链接