springboot整合dubbo实现RPC服务远程调用

一、dubbo简介

1.什么是dubbo

Apache Dubbo是一款微服务开发框架,他提供了RPC通信与微服务治理两大关键能力。有着远程发现与通信的能力,可以实现服务注册、负载均衡、流量调度等服务治理诉求。

2.dubbo基本工作原理

  • Contaniner:容器
  • Provider:服务提供者
  • Consumer:服务消费者
  • Registry:注册中心
  • Monitor:统计服务调用次数和调用时间的监控中心

3.具体介绍参考官方文档

文档|Apache Dubbo

二、准备dubbo-admin(管理控制台)和zookeeper(注册中心)

1.下载注册中心

bash 复制代码
docker pull zookeeper//拉取zookeeper镜像

docker run -d \
​	-p 2181:2181 \
​	-v /mydata/zookeeper/data:/data  \
​	--name zookeeper \
 	 zookeeper:latest
 	 这里我的端口号为2181,我的服务器地址为192.168.31.130
 	 yml配置文件里dubbo配置应该为:dubbo.registry.address=zookeeper://192.168.31.130:2181

-d:后台启动

-p:暴露端口号

-v:数据卷挂载

--name:指定容器名称

2.下载安装dubbo-admin(dubbo的管理控制台)

bash 复制代码
docker pull dubbo-admin //拉取镜像

//运行镜像
docker run -it -d \
	--name dubbo-admin \
	-v /mydata/zookeeper/dubbo-admin/data:/data \
	-p 9952:8080 \
	-e dubbo.registry.address=zookeeper://192.168.31.130:2181 \
	-e dubbo.admin.root.password=root -e dubbo.admin.guest.password=root \
	chenchuxin/dubbo-admin:latest
 

三、SpringBoot整合dubbo+zookeeper

分布式微服务主要是将应用的各项功能拆分成不同的模块,(根据不同的功能模块划分成不同的项目)发布在不同的服务器上,然后将需要向外提供的服务api做成分包,模块之间的相互调用通过分包api完成,dubbo的作用在于我们只需要将服务提供者的接口暴露给dubbo托管,服务消费者只要向registry注册中心注册并指定需要调用的服务,即可完成服务间调用,无需关心服务提供者的内部结构是怎样的,用户也感知不到调用了任何外部服务。

创建一个空项目,并创建commons-api、dubbo-provider、dubbo-consumer三个模块

3.1 在commons-api模块创建Account实体类和AccountService接口

java 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Account implements Serializable {
    private int id;
    private String username;
    private double money;
}
java 复制代码
package liao.com.service;
import liao.com.entity.Account;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface AccountService {
    /**
     * @Description:获取所有账户信息
     * @Params: []
     * @return java.util.List<liao.com.entity.Account>
     */

    List<Account> getAllAccounts();
    /**
     * @Description:根据用户名获取账户余额
     * @Params: [username]
     * @return double
     */
    Account getMoney(String username);

    /**
     * @Description:增加账户余额
     * @Params: [username, money]
     * @return int
     */
    int updateAddMoney(@Param("username") String username, @Param("money") double money);

    /**
     * @Description:减少账户余额
     * @Params: [username, money]
     * @return int
     */

    int updateSubMoney(@Param("username") String username, @Param("money") double money);
}

最后记得install打包到本地maven仓库里,provider服务提供者和consumer服务消费者需要用到

3.2创建provider服务提供者

3.2.1添加pom.xml依赖:
xml 复制代码
		<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.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--        数据库-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.20</version>
        </dependency>


        <!-- Dubbo Spring Boot Starter -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.8</version>
        </dependency>
        <dependency><!--zookerper版本一定要匹配! -->
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-registry-zookeeper</artifactId>
            <version>2.7.8</version>
        </dependency>
        <!--这个是commons-api的maven依赖-->
        <dependency>
            <groupId>liao.com</groupId>
            <artifactId>commons-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
  
3.2.2application.properties文件
bash 复制代码
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/demo?userSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver


server.port=8887
mybaits.mapper-locations=classpath:dao/*.xml
mybatis.type-aliases-package=liao.com.entity
mybatis.configration-log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

dubbo.application.name=dubbo-provider-service
dubbo.registry.address=zookeeper://192.168.31.130:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20887
dubbo.scan.base-packages=liao.com
dubbo.registry.timeout=30000
3.2.3AccountDao.xml文件
xml 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="liao.com.dao.AccountDao">
    <select id="getAccountByName" resultType="liao.com.entity.Account" parameterType="String">
        select id, username, money from account where username = #{username}
    </select>

    <update id="updateAddMoney">
        update account set money = money + #{money} where username = #{username}
    </update>

    <update id="updateSubMoney">
        update account set money = money - #{money} where username = #{username}
    </update>

    <select id="getAllAccounts" resultType="liao.com.entity.Account">
        select id, username, money from account
    </select>
</mapper>
3.2.4创建AccountDao
java 复制代码
package liao.com.dao;

import liao.com.entity.Account;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @author: lehu
 * @Description:账户类接口
 * @Params:
 * @return
 * @date 2024-04-13 02:38
 */

@Mapper
@Repository
public interface AccountDao {
    /**
     * @Description:获取所有账户信息
     * @Params: []
     * @return java.util.List<liao.com.entity.Account>
     */

    List<Account> getAllAccounts();
    /**
     * @Description:根据用户名获取账户余额
     * @Params: [username]
     * @return double
     */
    /*@Select("SELECT id, username,money FROM account WHERE username = #{username}")*/
    Account getMoney(String username);

    /**
     * @Description:增加账户余额
     * @Params: [username, money]
     * @return int
     */
    /*@Select("UPDATE account SET money = money + #{param2} WHERE username = #{param1}")*/
    int updateAddMoney(@Param("username") String username, @Param("money") double money);

    /**
     * @Description:减少账户余额
     * @Params: [username, money]
     * @return int
     */

    int updateSubMoney(@Param("username") String username, @Param("money") double money);
}
3.2.5创建AccountServiceImpl
java 复制代码
//@DubboService注解标识该服务是服务提供者provider
@DubboService(version = "1.0.0")
//实现的AccountService接口导入Commons-api模块下的
public class AccountServiceImplPlus implements AccountService {
    @Resource
    private AccountDao accountDao;
    @Override
    public List<Account> getAllAccounts() {
        return accountDao.getAllAccounts();
    }

    @Override
    public Account getMoney(String username) {
        return accountDao.getAccountByName(username);
    }

    @Override
    public int updateAddMoney(String username, double money) {
        return accountDao.updateAddMoney(username, money);
    }

    @Override
    public int updateSubMoney(String username, double money) {
        return accountDao.updateSubMoney(username, money);
    }


}

3.3创建consumer服务消费者

依赖和provider服务提供者一样

application.properties配置文件也类似

创建AccountController
java 复制代码
@RestController
@Slf4j
public class AccountController {

	//@Reference代表是服务消费者,这里的AccountService接口也是导入的Commons-api模块里的
    @Reference(version = "1.0.0")
    private AccountService accountService;

    @RequestMapping("/getAccounts")
    public List<Account> getAccounts() {
        List<Account> allAccounts = accountService.getAllAccounts();
        log.info("allAccounts:{}", allAccounts);
        return allAccounts;
    }

    @RequestMapping("/getMoenyByUsername")
    public void addAccount(String username, String param1, double param2) {
        Account account = accountService.getMoney(username);
        log.info("account:{}", account);
        if (account.getMoney() > 10000) {
            accountService.updateAddMoney(param1, param2);
        }
    }

    @RequestMapping("/getAccountByUsername")
    public Account getAccountByUsername(@Param("username") String username) {
        Account account = accountService.getMoney(username);
        log.info("account:{}", account);
        return account;
    }

    @RequestMapping("/addAccount")
    public String addAccount(@Param("username") String username, @Param("money") Double money) {
        int i = accountService.updateAddMoney(username, money);
        if (i > 0) {
            return "success";
        } else {
            return "fail";
        }
    }

    @RequestMapping("/subAccount")
    public String subAccount(@Param("username") String username, @Param("money") Double money) {
        int i = accountService.updateSubMoney(username, money);
        if (i > 0) {
            return "success";
        } else {
            return "fail";
        }
    }

}
3.3测试

先启动服务提供者,再启动服务消费者

用postman测试一下基于Dubbo+Zookeeper的RPC远程服务调用

查询所有账户信息:

根据用户名来查询Account账户信息:

根据用户名来给用户转账:

再来查询不良帅的余额:

四、在zookeeper客户端命令查看dubbo服务的生产者与消费者

现在我的zookeeper注册中心部署在docker容器里,需要通过命令:docker exec -it 容器id /bin/bash进入容器内部

4.1进入容器内部后切换到bin目录下

bash 复制代码
docker exec -it 容器id /bin/bash //进入容器内部
cd bin //切换到bin目录

4.2 执行命令./zkCli.sh

bash 复制代码
./zkCli.sh

4.3 在命令行输入ls /dubbo,即可查到dubbo服务对外提供的接口,如下图:

4.4 查看消费者命令:

bash 复制代码
ls /dubbbo/liao.com.service.AccountService/consumers

会看到消费者的信息,截图如下:

4.5 查看生产者命令:

bash 复制代码
ls /dubbo/liao.com.common.CommonService/providers

会看到生产者的信息,截图如下:

OK结束!

相关推荐
bing_1584 小时前
为什么选择 Spring Boot? 它是如何简化单个微服务的创建、配置和部署的?
spring boot·后端·微服务
三个蔡6 小时前
Java求职者面试:从Spring Boot到微服务的技术深度探索
java·大数据·spring boot·微服务·kubernetes
小鸡脚来咯7 小时前
SpringBoot 常用注解通俗解释
java·spring boot·后端
创码小奇客7 小时前
MongoDB 事务:数据世界的守护者联盟全解析
spring boot·mongodb·trae
中国lanwp7 小时前
springboot logback 默认加载配置文件顺序
java·spring boot·logback
cherishSpring8 小时前
在windows使用docker打包springboot项目镜像并上传到阿里云
spring boot·docker·容器
苹果酱05678 小时前
【Azure Redis 缓存】在Azure Redis中,如何限制只允许Azure App Service访问?
java·vue.js·spring boot·mysql·课程设计
慧一居士10 小时前
Kafka HA集群配置搭建与SpringBoot使用示例总结
spring boot·后端·kafka
uncofish10 小时前
springboot不连接数据库启动(原先连接了mysql数据库)
数据库·spring boot·mysql