文章目录
说明
jdk1.8+SpringBoot2.x+低版本dubbo:请查看之前教程【微服务】SpringBoot+Dubbo+ZooKeeper 实战
关于本教程将采用jdk17+SpringBoot3.x+dubbo3.X,相对之前的感受就是方便了很多,不需要写dubbo配置远程api文件,而是通过注解实现。
同时本教程也使用到了mybatis-plus对mysql数据库表进行操作。
关于mysql和zookeeper环境将搭载在docker环境中,如果需要在win环境中搭建,直接检索相关教程搭建即可。
环境搭建
关于jdk安装,docker部署mysql,已经在教程从0开始搭建一个SpringBoot项目(从环境配置到运行项目)这里不再重复。
安装zookeeper环境:
(1)拉取zookeeper最新的版本镜像:
docker pull zookeeper
 
(2)创建数据存储目录:
mkdir docker_data/zookeeper
mkdir docker_data/zookeeper/data
mkdir docker_data/zookeeper/datalog
 
(3)运行容器:
docker run -p 2181:2181 --name zookeeper \
-v /XX/docker_data/zookeeper/data:/data \
-v /XX/docker_data/zookeeper/datalog:/datalog \
-d zookeeper
 
参数说明:
docker run:运行Docker镜像
 -p:映射端口号,宿主机端口映射到容器内部端口
 –name zookeeper:设置容器名称为zookeeper
 -v zookeeper/data:/data:将容器的/data目录挂载到宿主机的/Users/leo/docker/redis/data目录(数据持久化)
 -v zookeeper/datalog:/datalog:同上
 -d zookeeper:选择运行的Docker镜像并指定Tag(不指定的话默认是latest)
创建项目
项目架构

 包括3个maven项目:
 dubbo-api:存放实体类,interface接口,以及其他一些公共部分
 dubbo-provider:生产者,提供服务:实现api模块的interface接口
 dubbo-consumer:消费者,远程调用product的服务。
父模块设置
父模块springboot3-dubbo3:pom.xml 定义相关库的版本
<?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.jnu</groupId>
    <artifactId>springboot3-dubbo3</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <modules>
        <module>dubbo-api</module>
        <module>dubbo-consumer</module>
        <module>dubbo-provider</module>
    </modules>
    <properties>
        <spring-boot.version>3.1.0</spring-boot.version>
        <dubbo.version>3.2.2</dubbo.version>
        <lombok.version>1.18.26</lombok.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- Dubbo -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-dependencies-zookeeper</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <optional>true</optional>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>
 
子模块 dubbo-api
子模块dubbo-api

存放实体类和接口文件:
CREATE TABLE `user_test`  (
  `id` int(0) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL DEFAULT '' COMMENT '名称',
  `age` int(0) NOT NULL COMMENT '年龄',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_unicode_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;
 
实体类与数据库表对应:
@Data
@NoArgsConstructor
@TableName("user_test")
public class User implements Serializable {
    @TableId(type = IdType.AUTO)
    private Integer id;
    @TableField("name")
    private String name;
    @TableField("age")
    private Integer age;
}
 
服务接口与数据库对应:
public interface UserService {
    /**
     * 增加用户
     * @param user
     */
    void addUser(User user);
    /**
     * 更新用户
     * @param user
     */
    void updateUser(User user);
    /**
     * 产出用户
     * @param name
     */
    void deleteUser(String name);
    /**
     * 查询用户
     * @param name
     * @return
     */
    List<User> getUserByName(String name);
}
 
涉及到的库文件pom.xml:
<?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>
    <parent>
        <groupId>com.jnu</groupId>
        <artifactId>springboot3-dubbo3</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>dubbo-api</artifactId>
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!--mysql-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.7</version>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>
 
子模块 dubbo-provider
dubbo-provider子模块需要实现dubbo-api的接口

 使用到的依赖:pom.xml
<?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>
    <parent>
        <groupId>com.jnu</groupId>
        <artifactId>springboot3-dubbo3</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>dubbo-provider</artifactId>
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.jnu</groupId>
            <artifactId>dubbo-api</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!-- dubbo -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>3.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-reload4j</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>zookeeper</artifactId>
                    <groupId>org.apache.zookeeper</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <artifactId>zookeeper</artifactId>
            <groupId>org.apache.zookeeper</groupId>
            <version>3.8.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <layout>ZIP</layout>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
 
(1)涉及到mybatis对数据库mysql操作:
UserMapper.java
public interface UserMapper extends BaseMapper<User> {
    void updateUser(User user);
    void deleteUser(String name);
    List<User> getUserByName(String name);
}
 
UserMapper.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="com.jnu.mapper.UserMapper">
    <update id="updateUser">
        update user_test
        set age=#{user.age}
        where name=#{user.name}
    </update>
    <delete id="deleteUser">
        delete
        from user_test
        where name=#{name}
    </delete>
    <select id="getUserByName">
        select *
        from user_test
        where name LIKE CONCAT('%', #{name}, '%')
    </select>
</mapper>
 
(2)实现api模块的接口:@DubboService注解对远程开放
 UserServiceImpl.java
@DubboService
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public void addUser(User user) {
        userMapper.insert(user);
    }
    @Override
    public void updateUser(User user) {
        userMapper.updateUser(user);
    }
    @Override
    public void deleteUser(String name) {
        userMapper.deleteUser(name);
    }
    @Override
    public List<User> getUserByName(String name) {
        return userMapper.getUserByName(name);
    }
}
 
(3)启动类:
@SpringBootApplication
@EnableDubbo
@MapperScan(basePackages = "com.jnu.mapper")
@EnableScheduling
public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }
}
 
(4)配置文件:application.yml
server:
  port: 8081
dubbo:
  application:
    name: dubbo-provider
    check-serializable: false
    serialize-check-status: DISABLE
  protocol:
    name: dubbo
    port: -1
  registry:
    address: zookeeper://${zookeeper.address:192.XXX.XX.XXX}:2182
# Logger Config
logging:
  level:
    com.hexadecimal: debug
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.XXX.XX.XXX:3306/数据库名称
    username: root
    password: 123456
    hikari:
      connection-timeout: 30000
      maximum-pool-size: 10
# mybatis-plus 配置内容
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
  global-config:
    db-config:
      id-type: auto # ID 主键自增
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
  mapper-locations: classpath*:mapper/*.xml
  type-aliases-package: com.jnu.entity
 
子模块 dubbo-consumer

dubbo-consumer模块主要是提供web的api服务,通过调用provider提供开放的服务对底层数据进行处理。
 需要使用到的依赖:pom.xml
<?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>
    <parent>
        <groupId>com.jnu</groupId>
        <artifactId>springboot3-dubbo3</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>dubbo-consumer</artifactId>
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.jnu</groupId>
            <artifactId>dubbo-api</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
            <exclusions>
                <exclusion>
                    <groupId>com.mysql</groupId>
                    <artifactId>mysql-connector-j</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- dubbo -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>3.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-reload4j</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>zookeeper</artifactId>
                    <groupId>org.apache.zookeeper</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <artifactId>zookeeper</artifactId>
            <groupId>org.apache.zookeeper</groupId>
            <version>3.8.1</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
 
涉及到对web提供api的服务:UserController.java
@RestController
@RequestMapping("user")
public class UserController {
    @DubboReference
    public UserService userService;
    @RequestMapping(value = "add", method = RequestMethod.POST)
    public Result addUser(@RequestParam("name")String name, @RequestParam("age")Integer age) {
        User user = new User();
        user.setName(name);
        user.setAge(age);
        userService.addUser(user);
        return Result.ok();
    }
    @RequestMapping(value = "select", method = RequestMethod.GET)
    public Result selectUser(@RequestParam("name")String name) {
        List<User> userList = userService.getUserByName(name);
        return Result.ok().data("list", userList);
    }
}
 
启动类:ConsumerApplication.java
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@EnableDubbo
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}
 
测试项目
依次启动provider和consumer。
访问下面接口:
 (1)http://localhost:8082/user/add?name=高兴&age=18
 
 (2)http://localhost:8082/user/select?name=高
 
 到此项目搭建完成。
docker部署项目
上面项目已搭建完成,怎么进行docker部署。
 在这之前,请确保mysql和zookeeper服务正常运行。
(1)docker 安装 Java环境:
docker pull openjdk:17-jdk
 
(1)依次对provider和consumer进行打包:
 
 如果遇到报错:
 
 对父模块,api模块进行mvn clean install,该模块install,然后进行package即可解决。
 查看打包文件:
 
从classes看,如果配置文件没有加载完全:在pom.xml的 <build>标签下加入下面信息
         <resources>
            <!--如果pro和xml文件放在源码java包下,也需要编译-->
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.yml</include>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.yml</include>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
 
确认无误后,对dubbo-provider-1.0-SNAPSHOT.jar上传服务器,为后续部署做准备。
同理对consumer模块进行相同操作。
(2)我们已经将provider和consumer打包成jar包并上传到服务器,注意两个jar包最好放不同的文件目录,方便后续编写dockerfile。

 第一步:docker 安装 Java环境:
docker pull openjdk:17-jdk
 
第二步:进入包含各自jar包的文件目录编写dockerfile
 test/provider:
cd test/provider
vim dockerfile
 
# 使用官方的 OpenJDK 17 镜像作为基础镜像
FROM openjdk:17-jdk
# 作者标签
LABEL maintainer="xiaohe"
# 创建并指定临时文件目录
VOLUME /home/tmp
# 将当前目录下的 dubbo-provider-1.0.0-SNAPSHOT.jar 文件添加到容器的根目录下,并更名为 app.jar
ADD dubbo-provider-1.0-SNAPSHOT.jar /app.jar
# 确保 app.jar 文件是可执行的
RUN bash -c 'touch /app.jar'
# 设置容器启动时执行的命令
# 使用 Java 运行 app.jar 文件
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar"]
 
创建镜像:
docker build -t {镜像名称} .
 

 同理,consumer服务:
cd test/consumer
vim dockerfile
 
# 使用官方的 OpenJDK 17 镜像作为基础镜像
FROM openjdk:17-jdk
# 作者标签
LABEL maintainer="xiaohe"
# 创建并指定临时文件目录
VOLUME /home/tmp
# 将当前目录下的 dubbo-provider-1.0.0-SNAPSHOT.jar 文件添加到容器的根目录下,并更名为 app.jar
ADD dubbo-consumer-1.0-SNAPSHOT.jar /app.jar
# 确保 app.jar 文件是可执行的
RUN bash -c 'touch /app.jar'
# 设置容器启动时执行的命令
# 使用 Java 运行 app.jar 文件
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar"]
 

 运行容器进行测试:
docker run --name test-provider -d -p 9090:8081 test-provider
docker run --name test-consumer -d -p 9091:8082 test-consumer
 

 运行成功,进行测试:将之前localhost换成服务器地址和端口9091:
 http://XXXX:9091/user/select?name=高:
 
 成功部署!
完整项目地址
springboot3-dubbo3










