一,项目总体介绍
在本项目中,我将使用alibabba的 nacos 作为项目的注册中心,使用 spring cloud gateway 做为项目的网关,用 openfeign 作为服务间的调用组件。
项目总体架构图如下:
注意:我的Java环境是17,下面的pom 中默认的是1.8,大家可以自己修改一下
在这里我使用了mysql 的主从复制,当然你怎么用都可以,取决于你的项目,或者使用 canal 更加方便,当然后续我也会使用canal同步数据,解决缓存一致性问题,nginx这里我会使用openresty,至于介绍和安装请看 openresty安装
1.1、组件介绍、安装
nacos:
1.1.1、介绍:
- 动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。
- 动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。
- 配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。
- Nacos 提供了一个简洁易用的UI (控制台样例 Demo) 帮助您管理所有的服务和应用的配置。
- Nacos 还提供包括配置版本跟踪、金丝雀发布、一键回滚配置以及客户端配置更新状态跟踪在内的一系列开箱即用的配置管理特性,帮助您更安全地在生产环境中管理配置变更和降低配置变更带来的风险。(官网介绍)地址:官网
1.1.2、安装: 这里使用 docker 安装 (docker 不会安装的看我“微服务监控”第五章)
1.1.2.1、docker 镜像拉取
docker pull nacos/nacos-server
1.1.2.2、创建挂载目录
mkdir -p /mydata/nacos/logs/ #新建logs目录
mkdir -p /mydata/nacos/conf/ #新建conf目录
1.1.2.3、启动容器(拷贝文件)
docker run -p 8848:8848 --name nacos -d nacos/nacos-server
复制文件
docker cp nacos:/home/nacos/logs/ /mydata/nacos/
docker cp nacos:/home/nacos/conf/ /mydata/nacos/
删除容器
docker rm -f nacos
1.1.2.4、mysql 中创建 nacos 所需要的库 nacos-config(随意)
在拷贝的 conf 文件夹下会有 mysql 的 sql 文件,执行一下就 OK 了
docker run -d --name nacos -p 8848:8848 -p 9848:9848 -p 9849:9849
--privileged=true -e JVM_XMS=1g -e JVM_XMX=2g -e MODE=standalone
-v /mydata/nacos/logs/:/home/nacos/logs -v /mydata/nacos/conf/:/home/nacos/conf/
--restart=always nacos/nacos-server
参数介绍:
1、docker run -d : 启动容器 -d是后台启动并返回容器id的意思
2、–name nacos :为容器指定一个名称
3、-p 8848:8848 -p 9848:9848 -p 9849:9849 : 指定端口映射,注意这里的p不能大写,大写是随机端口映射
4、–privileged=true : 扩大容器内的权限,将容器内的权限变为root权限,不加的话就是普通用户权限,可能会出现cannot open directory
5、-e JVM_XMS=1g : 为jvm启动时分配的内存
6、-e JVM_XMX=2g : 为jvm运行过程中分配的最大内存
7、-e MODE=standalone : 使用 standalone模式(单机模式),MODE值有cluster(集群)模式/standalone模式两种,MODE必须大写
8、-v /mydata/nacos/logs/:/home/nacos/logs : 将容器的/home/nacos/logs目录挂载到 /mydata/nacos/logs
9、-v /mydata/nacos/conf/:/home/nacos/conf/: 将容器的/home/nacos/conf目录挂载到 /mydata/nacos/conf
10、–restart=always :重启docker时,自动启动相关容器
注意:开放端口 8848 9848 9849
1.1.2.4、修改配置文件(宿主机)
vim /mydata/nacos/conf/application.properties
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://localhost:3306/nacos-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=30000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=root
db.password=root
重启 nacos 容器
docker restart nacos
安装 nacos 搞定!!!
其他组件在使用到时会介绍
二、项目创建
2.1、在 idea 中创建一个 spring 项目,删除 src 作为聚合目录,这个就不过多赘述
接下来看 pom 文件的配置
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.siyu</groupId>
<artifactId>study</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>study</name>
<!--描述-->
<description>study</description>
<!-- 子模块 这里你有那些子模块就有那些 moudle-->
<modules>
<module>common-api</module>
<module>common-utils</module>
<module>service</module>
<module>gateway</module>
</modules>
<!-- 打包方式-->
<packaging>pom</packaging>
<!-- 属性配置 spring boot spring cloud spring cloud alibaba 版本一定要兼容,否则会失败-->
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>3.0.2</spring-boot.version>
<spring-cloud-alibaba.version>2022.0.0.0</spring-cloud-alibaba.version>
<spring-cloud.version>2022.0.0</spring-cloud.version>
</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>
<!-- spring cloud alibaba 版本管理 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.siyu.StudyApplication</mainClass>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2.2、版本对应详情
在这里我给出版本对应截图,一定要版本对应哦,不然不兼容会报错
2.3、创建二级聚合模块
创建子模块 file ——> new ——> Module——> spring 脚手架创建就可以(创建完成后你可以删掉 src作为二级聚合)
子模块创建完毕后,我们看一下pom(我这里做了二级聚合),在这里贴一下我的项目结构如图
首先我们看看sercvie 的 pom
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.siyu</groupId>
<artifactId>service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>service</name>
<!--描述-->
<description>service</description>
<!--打包方式-->
<packaging>pom</packaging>
<!--子模块-->
<modules>
<module>user-service</module>
<module>homework-service</module>
<module>student-service</module>
</modules>
<!--父模块-->
<parent>
<groupId>com.siyu</groupId>
<artifactId>study</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<!--版本-->
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>3.0.2</spring-boot.version>
</properties>
<dependencies>
<!--spring boot web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--测试包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--Java 连接 mysql jar-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!--mybatis plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3</version>
</dependency>
<!--openfeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--nacos discovery-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--nacos config-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--nacos 客户端-->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.siyu.service.ServiceApplication</mainClass>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2.4、创建子模块
创建过程和上面创建方式一样,不过多赘述。看看 user-service 的 pom
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.siyu</groupId>
<artifactId>user-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>user-service</name>
<!--描述-->
<description>user-service</description>
<!--父模块-->
<parent>
<groupId>com.siyu</groupId>
<artifactId>service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<!--版本-->
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>3.0.2</spring-boot.version>
</properties>
<dependencies>
<!-- user-api 在common-api中,主要定义entity 和 feign接口 -->
<dependency>
<groupId>com.siyu</groupId>
<artifactId>user-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--common-utils 主要定义一些公共工具-->
<dependency>
<groupId>com.siyu</groupId>
<artifactId>common-utils</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.siyu.UserServiceApplication</mainClass>
<skip>false</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
看看 appliction.yml (后期会迁移到 nacos)
server:
port: 8080
spring:
config:
import: "nacos:user-service.yaml" # nacos 中的配置文件
application:
name: user-service #服务名
cloud:
nacos:
discovery:
server-addr: ip:8848 #nacos地址
config:
server-addr: ip:8848
import-check:
enabled: false
file-extension: yaml # nacos 配置文件类型
datasource: # datasource 不过多解释
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://ip:33061/study?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false&allowPublicKeyRetrieval=true
password: root
username: root
# mybatis plus 不过多解释
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
type-aliases-package: com.siyu.entity
global-config:
db-config:
id-type: auto
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
接下来看看启动类 UserServiceApplication.java
@EnableDiscoveryClient //启动服务发现(nacos)
@EnableFeignClients // 启动 openfeign
@SpringBootApplication
@MapperScan(basePackages = "com.siyu.mapper")
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
2.5、创建common-api
创建过程一样,不做过多介绍(删掉启动类,这个模块不需要启动),一起看看 common-api 的目录结构
看看 common-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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.siyu</groupId>
<artifactId>common-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>common-api</name>
<description>common-api</description>
<packaging>pom</packaging>
<parent>
<groupId>com.siyu</groupId>
<artifactId>study</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modules>
<module>user-api</module>
<module>homework-api</module>
</modules>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>3.0.2</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>com.siyu</groupId>
<artifactId>common-utils</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2.6、feign接口编写
创建 feign接口
package com.siyu.feign;
import com.siyu.util.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "homework-service") //微服务服务名
public interface HomeWorkFeign {
@GetMapping("homework/list") // 要访问的微服务路径和请求方式
Result getHomeworkList(); // 方法名和返回结果
}
调用 feign 接口
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private UserService userService;
@Autowired
private HomeWorkFeign homeWorkFeign; // 导入feign 接口
@GetMapping("/{id}")
public Result<Object> getUserById(@PathVariable("id") Integer id){
return Result.ok("查询成功",userService.getById(id));
}
@GetMapping("/list")
public Result<Object> getUserById(){
return Result.ok("查询成功",homeWorkFeign.getHomeworkList()); //调用feign 接口
}
}
2.7、网关 gateway 模块
首先创建一个gateway模块 (要注意的是不要导入 spring boot we 包,具体原因就不解释了,自行了解)
看看 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.siyu</groupId>
<artifactId>gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gateway</name>
<description>gateway</description>
<parent>
<groupId>com.siyu</groupId>
<artifactId>study</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>3.0.2</spring-boot.version>
</properties>
<dependencies>
<!--网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--服务注册与发现依赖-->
<dependency>
<groupId>com.alibaba.cloud </groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--nacos 客户端-->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>2.3.2</version>
</dependency>
<!--负载均衡-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.siyu.gateway.GatewayApplication</mainClass>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
看看 gateway 的 application.yml
server:
port: 8088
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
discovery:
server-addr: ip:8848
gateway:
discovery:
locator:
enabled: false
routes: # 网关路由配置
- id: user-service # 路由id, 自定义,唯一即可
uri: lb://user-service # 路由的目的地,lb是负载均衡,后面跟服务名称
predicates: # 路由断言,也就是判断是否符合路由规则的条件
- Path=/user-service/** # path 按照路径进行匹配,只要以/order-service/开头就符合规则
filters:
- StripPrefix=1 # 过滤器,去除请求的前缀路径,StripPrefix=1 表示去除请求路径的第一个路径片段
- id: homework-service
uri: lb://homework-service
predicates:
- Path=/homework-service/**
filters:
- StripPrefix=1
在注释里基本都有详细的解释,这里就不过多赘述
在这里我们给大家贴一张nacos的截图,服务注册列表
至此,项目搭建就完毕了!!!