【从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


相关推荐
用户908324602738 小时前
Spring AI 1.1.2 + Neo4j:用知识图谱增强 RAG 检索(上篇:图谱构建)
java·spring boot
用户8307196840821 天前
Spring Boot 集成 RabbitMQ :8 个最佳实践,杜绝消息丢失与队列阻塞
spring boot·后端·rabbitmq
Java水解1 天前
Spring Boot 视图层与模板引擎
spring boot·后端
clamlss1 天前
💥 踩坑实录:Dubbo 为什么把我的自定义异常“吃”了?
dubbo
Java水解1 天前
一文搞懂 Spring Boot 默认数据库连接池 HikariCP
spring boot·后端
洋洋技术笔记1 天前
Spring Boot Web MVC配置详解
spring boot·后端
初次攀爬者2 天前
Kafka 基础介绍
spring boot·kafka·消息队列
用户8307196840822 天前
spring ai alibaba + nacos +mcp 实现mcp服务负载均衡调用实战
spring boot·spring·mcp
Java水解2 天前
SpringBoot3全栈开发实战:从入门到精通的完整指南
spring boot·后端
初次攀爬者3 天前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq