分布式调用与高并发处理 Dubbo分布式调用(三)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 分布式调用与高并发处理 Dubbo分布式调用(三)

五、Dubbo实战

5.1 项目介绍

需求

完成用户表的CRUD操作。

技术架构

项目结构设计

本项目采用maven分模块开发方式,即对整个项目拆分为几个maven工程,每个maven工程存放特定的一类代码。

解释:

  • user_api:公共接口
  • user_consumer:服务消费者
  • user_provider:服务生产者

项目目的

了解分布式项目的构建方式。

5.2 构建dubbo_parent工程

修改pom文件,因为是父项目,所有将项目的打包类型设置为pom

<packaging>pom</packaging>

设置项目依赖

<?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.zj</groupId>
    <artifactId>dubbo_parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--如果是maven项目的花,在创建子项目的时候会自动在父项目指定子项目
    如果是springboot项目的话需要手动指定子项目-->
    <modules>
        <module>user_api</module>
        <module>user_provider</module>
    </modules>
    <packaging>pom</packaging>
    <properties>
        <dubbo.spring.starter.version>2.7.6</dubbo.spring.starter.version>
        <dubbo.registry.zookeeper.version>2.7.6</dubbo.registry.zookeeper.version>
        <mybatisplus.spring.starter.version>3.5.0</mybatisplus.spring.starter.version>
        <mysql.connector.version>5.1.49</mysql.connector.version>
    </properties>
    <dependencyManagement>
<!-- dependencyManagement 这个标签的作用就是给定版本的,所以不会下载的,都是从仓库获取依赖,但是你是第一次,仓库没有这些依赖,所以先下载之后在将这个标签注解解-->
        <dependencies>
            <!-- Dubbo 依赖 -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>2.7.6</version>
            </dependency>
            <!-- zookeeper 注册中心 依赖 -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-registry-zookeeper</artifactId>
                <version>2.7.6</version>
            </dependency>
            <!-- Mybatis plus 依赖 -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatisplus.spring.starter.version}</version>
            </dependency>
            <!--MySQL 数据库依赖 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.connector.version}</version>
            </dependency>
            <!--lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.22</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <!--设置JDK版本-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

5.3 构建user_api工程

该工程存放的是公共的接口

设置依赖,在父项目中已经指定了版本因此不需要再子项目设置版本啦。

<?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_parent</artifactId>
        <groupId>com.zj</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>user_api</artifactId>
    <dependencies>
        <!-- Dubbo 依赖 -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>
        <!-- zookeeper 注册中心 依赖 -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-registry-zookeeper</artifactId>
        </dependency>
    </dependencies>
</project>

父项目指定子项目

<!--如果是maven项目的花,在创建子项目的时候会自动在父项目指定子项目
    如果是springboot项目的话需要手动指定子项目-->
    <modules>
        <module>user_api</module>
    </modules>

5.4 构建user_consumer工程

引入dubbo_parent父工程

<!--引入父工程-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.zj</groupId>
                <artifactId>dubbo_parent</artifactId>
                <version>1.0-SNAPSHOT</version>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

因为在该项目中默认的父工程是:spring-boot-starter-parent,但是项目还有一个父工程是dubbo_parent,当一个项目出现两个以及以上的父项目的时候使用dependencyManagement标签引入其他父项目。

5.5 构建user_provider工程

因为该项目是个逻辑工程因此也需要i指定项目的打包方式为pom,并删除src

<packaging>pom</packaging>

5.5.1 创建pojo,mapper,provider工程

5.6 构建实体类

5.6.1 Docker构建Mysql数据库

#创建并启动数据库MySQL
docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

参数:

-d:后台运行

--name:数据库名称

-p :端口映射

-e : 设置数据库密码

#如果数据库已经在之前创建好了,只需要启动数据库即可。
ocker start 43(容器ID)
#通过命令行操作mysql
docker exec -it mysql /bin/bash
#登录到mysql容器
mysql -uroot -p123456

5.6.2 创建数据库test

create database test;
#选择test数据库
use test;
#创建用户表
CREATE TABLE user
(
   id BIGINT(20) NOT NULL COMMENT '主键ID',
   name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
   age INT(11) NULL DEFAULT NULL COMMENT '年龄',
  PRIMARY KEY (id)
);
#查看全部表
show tabloes;

注意分号

5.6.3 在pojo项目中创建用户实体类

pojo项目引入lombok依赖

<dependencies>
        <dependency>
            <groupId>com.zj</groupId>
            <artifactId>pojo</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
package com.zj.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
    // 用户id
    private Long id;
    // 用户名字
    private String name;
    // 用户年纪
    private Integer age;
}

mapper工程引入pojo工程

<dependency>
            <groupId>com.zj</groupId>
            <artifactId>pojo</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

5.7 整合Mybaits-plus配置

5.7.1 修改mapper工程pom文件

<!-- Mybatis plus 依赖 -->
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
    </dependency>
    <!--MySQL 数据库依赖 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>

在父工程中定义过版本了。

5.7.2 在mapper工程中定义好接口UserMapper

package com.zj;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zj.pojo.User;
/*持久层*/
public interface UserMapper extends BaseMapper<User> {
}

在provider项目引入mapper项目

<dependencies>
        <dependency>
            <groupId>com.zj</groupId>
            <artifactId>mapper</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

5.7.3 在provider项目中配置

该项目依赖两个父项目,分别是user_provider和springboot

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
    </parent>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <artifactId>user_provider</artifactId>
                <groupId>com.zj</groupId>
                <version>1.0-SNAPSHOT</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

在该项目中引入springboot核心依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

在该项目中创建启动类providerApplication,添加 @MapperScan 注解,扫描 Mapper 文件夹

package com.zj;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.zj.mapper")
public class providerApplication {
    public static void main(String[] args) {
        SpringApplication.run(providerApplication.class);
    }
}

创建配置文件application.properties并配置数据源

################ 配置MySQL数据源 ##############
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.66.100:3306/test?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456

5.8 创建添加用户接口

5.8.1 在user_api工程引入pojo工程

<dependency>
            <groupId>com.zj</groupId>
            <artifactId>pojo</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

5.8.2 在user_api项目中创建添加用户接口

package com.zj.api;
import com.zj.pojo.User;
public interface addUserService {
    int addUser(User user);
}

5.8.3 在provider工程中引入user_api工程并实现user_api中的接口

<dependency>
            <groupId>com.zj</groupId>
            <artifactId>user_api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
package com.zj.service;
import com.zj.mapper.UserMapper;
import com.zj.api.AddUserService;
import com.zj.pojo.User;
import org.apache.dubbo.config.annotation.Service;
import javax.annotation.Resource;
/*将服务信息注册到zookeeper*/
@Service(timeout = 50000)
public class AddUserServiceImpl implements AddUserService {
    @Resource
    private UserMapper userMapper;
    @Override
    public int addUser(User user) {
        return userMapper.insert(user);
    }
}

5.8.4 在provider工程中配置Dubbo服务并启动zookeeper容器

################ Dubbo 配置 ####################
#服务的名称
dubbo.application.name=Provider
#  注册中心地址(单机)
dubbo.registry.address=zookeeper://192.168.66.100:2181
#  注册中心地址(集群)
#dubbo.registry.address=zookeeper://192.168.233.130:2181?backup=192.168.233.130:2182,192.168.233.130:2183
dubbo.registry.timeout=50000
#协议
dubbo.protocol.name=dubbo
#dubbo服务端口
dubbo.protocol.port=20880
#包扫描
dubbo.scan.base-packages=com.zj.provider.service

启动provider项目打开即可。

5.9 创建查询用户接口

5..9.1在user_api项目中创建查询全部用户接口

package com.zj.api;
import com.zj.pojo.User;
import java.util.List;
public interface FindUserService {
    List<User> findAll();
}

5.9.2在 provider中实现查询用户业务接口

package com.zj.service;
import com.zj.api.FindUserService;
import com.zj.mapper.UserMapper;
import com.zj.pojo.User;
import org.apache.dubbo.config.annotation.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class FindUserServiceImpl implements FindUserService {
    @Resource
    private UserMapper userMapper;
    @Override
    public List<User> findAll() {
        return userMapper.selectList(null);
    }
}

启动项目,查看dubbo控制台。

5.10 创建更新用户接口

5.10.1 在 user_api 项目中添加更新用户业务接口

package com.zj.api;
import com.zj.pojo.User;
public interface UpdateUserService {
    /*先查*/
    User preUpdateUser(Integer userId);
    /*再更新*/
    void updateUser(User user);
}

5.10.2 在 provider 中实现更新用户业务接口

package com.zj.service;
import com.zj.api.UpdateUserService;
import com.zj.mapper.UserMapper;
import com.zj.pojo.User;
import org.apache.dubbo.config.annotation.Service;
import javax.annotation.Resource;
@Service
public class UpdateUserServiceImpl implements UpdateUserService {
    @Resource
    private UserMapper userMapper;
    @Override
    public User preUpdateUser(Integer userId) {
        return userMapper.selectById(userId);
    }
    @Override
    public void updateUser(User user) {
         userMapper.updateById(user);
    }
}

启动项目。

5.11 创建删除用户接口

5.11.1 在user_api项目中添加删除用户业务接口

package com.zj.api;
public interface DeleteUserService {
    int  deleteUser(Long userId);
}

5.11.2 在provider中实现删除用户业务接口

package com.zj.service;
import com.zj.api.DeleteUserService;
import com.zj.mapper.UserMapper;
import org.apache.dubbo.config.annotation.Service;
import javax.annotation.Resource;
@Service
public class DeleteUserServiceImpl implements DeleteUserService {
    @Resource
    private UserMapper userMapper;
    @Override
    public int deleteUser(Long userId) {
        return userMapper.deleteById(userId);
    }
}

启动项目。


相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
4月前
|
消息中间件 Java Linux
2024年最全BATJ真题突击:Java基础+JVM+分布式高并发+网络编程+Linux(1),2024年最新意外的惊喜
2024年最全BATJ真题突击:Java基础+JVM+分布式高并发+网络编程+Linux(1),2024年最新意外的惊喜
|
4月前
|
监控 Dubbo 前端开发
快速入门分布式系统与Dubbo+zookeeper Demo
快速入门分布式系统与Dubbo+zookeeper Demo
469 0
|
3月前
|
消息中间件 数据挖掘 程序员
【建议收藏】高并发下的分布式事务:如何选择最优方案?
本文介绍了分布式事务的三种常见解决方案。在分布式系统中,事务处理变得复杂,需确保ACID特性。TCC(Try-Confirm-Cancel)方案适用于严格资金要求的场景,如银行转账,通过预留、确认和取消步骤确保一致性。可靠消息最终一致性方案适合一致性要求较低的场景,如电商积分处理,通过消息中间件实现最终一致性。最大努力通知方案则用于允许不一致的场景,如数据分析,通过重复通知尽可能达成一致性。选择合适的方案取决于具体应用场景。
107 5
|
2月前
|
存储 缓存 NoSQL
高并发架构设计三大利器:缓存、限流和降级问题之Redis用于搭建分布式缓存集群问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之Redis用于搭建分布式缓存集群问题如何解决
|
2月前
|
消息中间件 缓存 监控
如何设计一个秒杀系统,(高并发高可用分布式集群)
【7月更文挑战第4天】设计一个高并发、高可用的分布式秒杀系统是一个非常具有挑战性的任务,需要从架构、数据库、缓存、并发控制、降级限流等多个维度进行考虑。
84 1
|
3月前
|
存储 NoSQL Java
探索Java分布式锁:在高并发环境下的同步访问实现与优化
【6月更文挑战第30天】Java分布式锁在高并发下确保数据一致性,通过Redis的SETNX、ZooKeeper的临时节点、数据库操作等方式实现。优化策略包括锁超时重试、续期、公平性及性能提升,关键在于平衡同步与效率,适应大规模分布式系统的需求。
88 1
|
2月前
|
设计模式 安全 NoSQL
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
43 0
|
2月前
|
设计模式 存储 缓存
Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
42 0
|
2月前
|
存储 NoSQL Java
探索Java分布式锁:在高并发环境下的同步访问实现与优化
【7月更文挑战第1天】在分布式系统中,Java分布式锁解决了多节点共享资源的同步访问问题,确保数据一致性。常见的实现包括Redis的SETNX和过期时间、ZooKeeper的临时有序节点、数据库操作及Java并发库。优化策略涉及锁超时、续期、公平性及性能。选择合适的锁策略对高并发系统的稳定性和性能至关重要。
119 0
|
3月前
|
缓存 NoSQL 数据库
分布式系统面试全集通第一篇(dubbo+redis+zookeeper----分布式+CAP+BASE+分布式事务+分布式锁)
分布式系统面试全集通第一篇(dubbo+redis+zookeeper----分布式+CAP+BASE+分布式事务+分布式锁)
83 0