【从0开始搭建微服务并进行部署】SpringBoot+dubbo+zookeeper

文章目录


说明

jdk1.8+SpringBoot2.x+低版本dubbo:请查看之前教程【微服务】SpringBoot+Dubbo+ZooKeeper 实战

关于本教程将采用jdk17+SpringBoot3.x+dubbo3.X,相对之前的感受就是方便了很多,不需要写dubbo配置远程api文件,而是通过注解实现。

同时本教程也使用到了mybatis-plus对mysql数据库表进行操作。

关于mysqlzookeeper环境将搭载在docker环境中,如果需要在win环境中搭建,直接检索相关教程搭建即可。


环境搭建

关于jdk安装,docker部署mysql,已经在教程从0开始搭建一个SpringBoot项目(从环境配置到运行项目)这里不再重复。

安装zookeeper环境:

(1)拉取zookeeper最新的版本镜像:

bash 复制代码
docker pull zookeeper

(2)创建数据存储目录:

bash 复制代码
mkdir docker_data/zookeeper
mkdir docker_data/zookeeper/data
mkdir docker_data/zookeeper/datalog

(3)运行容器:

bash 复制代码
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-dubbo3pom.xml 定义相关库的版本

c 复制代码
<?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

存放实体类和接口文件:

在这之前需要在mysql数据库中构建一张表:

sql 复制代码
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;

实体类与数据库表对应:

java 复制代码
@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;
}

服务接口与数据库对应:

c 复制代码
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:

java 复制代码
<?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 复制代码
<?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

java 复制代码
public interface UserMapper extends BaseMapper<User> {

    void updateUser(User user);

    void deleteUser(String name);

    List<User> getUserByName(String name);

}

UserMapper.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="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

c 复制代码
@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)启动类:

c 复制代码
@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

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 复制代码
<?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

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

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环境:

c 复制代码
docker pull openjdk:17-jdk

(1)依次对provider和consumer进行打包:

如果遇到报错:

对父模块,api模块进行mvn clean install,该模块install,然后进行package即可解决。

查看打包文件:
从classes看,如果配置文件没有加载完全:在pom.xml <build>标签下加入下面信息

c 复制代码
         <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环境:

c 复制代码
docker pull openjdk:17-jdk

第二步:进入包含各自jar包的文件目录编写dockerfile
test/provider:

bash 复制代码
cd test/provider
vim dockerfile
c 复制代码
# 使用官方的 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"]

创建镜像:

bash 复制代码
docker build -t {镜像名称} .

同理,consumer服务:

c 复制代码
cd test/consumer
vim dockerfile
c 复制代码
# 使用官方的 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"]

运行容器进行测试:

c 复制代码
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


相关推荐
世间万物皆对象1 小时前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
qq_17448285753 小时前
springboot基于微信小程序的旧衣回收系统的设计与实现
spring boot·后端·微信小程序
代码小鑫5 小时前
A043-基于Spring Boot的秒杀系统设计与实现
java·开发语言·数据库·spring boot·后端·spring·毕业设计
真心喜欢你吖5 小时前
SpringBoot与MongoDB深度整合及应用案例
java·spring boot·后端·mongodb·spring
周全全5 小时前
Spring Boot + Vue 基于 RSA 的用户身份认证加密机制实现
java·vue.js·spring boot·安全·php
飞升不如收破烂~6 小时前
Spring boot常用注解和作用
java·spring boot·后端
计算机毕设源码qq-38365310416 小时前
(附项目源码)Java开发语言,215 springboot 大学生爱心互助代购网站,计算机毕设程序开发+文案(LW+PPT)
java·开发语言·spring boot·mysql·课程设计
岁岁岁平安7 小时前
springboot实战(15)(注解@JsonFormat(pattern=“?“)、@JsonIgnore)
java·spring boot·后端·idea
码上有前9 小时前
解析后端框架学习:从单体应用到微服务架构的进阶之路
学习·微服务·架构
潜洋11 小时前
Spring Boot教程之五:在 IntelliJ IDEA 中运行第一个 Spring Boot 应用程序
java·spring boot·后端