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

发布于:2024-04-17 ⋅ 阅读:(31) ⋅ 点赞:(0)

一、dubbo简介

1.什么是dubbo

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

2.dubbo基本工作原理

在这里插入图片描述

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

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

文档|Apache Dubbo

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

1.下载注册中心

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的管理控制台)

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接口

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Account implements Serializable {
    private int id;
    private String username;
    private double money;
}
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依赖:
		<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文件
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 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
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

//@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

@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目录下

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

4.2 执行命令./zkCli.sh

./zkCli.sh

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

在这里插入图片描述

4.4 查看消费者命令:

ls /dubbbo/liao.com.service.AccountService/consumers

会看到消费者的信息,截图如下:
在这里插入图片描述

4.5 查看生产者命令:

ls /dubbo/liao.com.common.CommonService/providers

会看到生产者的信息,截图如下:
在这里插入图片描述

OK结束!