【从0开始搭建微服务并进行部署】SpringBoot+dubbo+zookeeper
文章目录
- 说明
- 环境搭建
- 创建项目
- 父模块设置
- 子模块 dubbo-api
- 子模块 dubbo-provider
- 子模块 dubbo-consumer
- 测试项目
- docker部署项目
- 完整项目地址
说明
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
存放实体类和接口文件:
在这之前需要在mysql数据库中构建一张表:
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