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


相关推荐
lang201509282 小时前
Spring Boot优雅关闭全解析
java·spring boot·后端
二宝1522 小时前
黑马商城day4-微服务02
微服务·云原生·架构
刘一说3 小时前
Spring Boot 启动慢?启动过程深度解析与优化策略
java·spring boot·后端
lang201509284 小时前
Spring Boot缓存机制全解析
spring boot·后端·缓存
摇滚侠4 小时前
Spring Boot 3零基础教程,WEB 开发 默认页签图标 Favicon 笔记29
java·spring boot·笔记
lang201509284 小时前
Spring Boot SQL数据库全攻略
数据库·spring boot·sql
是梦终空6 小时前
计算机毕业设计241—基于Java+Springboot+vue的爱心公益服务系统(源代码+数据库+11000字文档)
java·spring boot·vue·毕业设计·课程设计·毕业论文·爱心公益系统
java_logo6 小时前
Docker 部署微服务项目保姆级教程
java·运维·docker·微服务·容器·eureka·架构
泉城老铁9 小时前
springboot 对接发送钉钉消息,消息内容带图片
前端·spring boot·后端
qq_124987075310 小时前
基于Spring Boot的高校实习实践管理系统(源码+论文+部署+安装)
java·spring boot·后端·毕业设计