SpringCloud微服务搭建实战

news/2024/10/4 7:54:00 标签: spring cloud, 微服务, spring

文章目录

  • 前言
  • Nacos配置和项目结构图示
  • 数据库和脚本准备
    • seata数据库
    • transaction_database数据库
  • 一、Spring Boot、Spring Cloud、Sping Cloud Alibaba
  • 二、seata安装
    • seata配置修改
    • Nacos新建配置文件seata-server.properties
  • 三、创建Microservice-Project项目
  • 四、创建api-module聚合Maven
  • 五、创建common-module
  • 六、创建gateway-module模块
    • pom文件内容
    • yml内容
  • 七、创建producer-module
    • pom文件修改
    • 引入nacos依赖
    • bootstrap.yml文件配置
    • 启动类添加注解@EnableDiscoveryClient
    • Nacos新建命名空间microservice-project
    • producer-module-dev.yml配置文件
    • 引入mybatis-plus、mysql、druid依赖
    • 引入openfeign依赖
    • 引入seata依赖
    • 引入sentinel依赖
    • 启动类完善
  • 八、创建consumer-module
    • pom依赖
    • consumer-module-dev.yml
  • 九、功能演示
    • openfeign演示
    • sentinel演示
    • seata分布式事务演示
  • 十、总结


前言

对于练习时长两年半的Java练习生而言,微服务或许是大家接触的最普遍、最火热的软件架构,尤其是Spring Cloud系列技术栈。笔者初学时也是从微服务开始的,然而框架虽然简单易用,但毕竟是架构师或者第三方开源脚手架集成好的,我只会用,想要自己集成一套却没那么容易。本文源于笔者想要在实际项目中集成seata分布式事务的一个本地练习项目,想着干脆从0开始一步步集成一套基本的脚手架吧。

在这里插入图片描述
基础条件准备

IDE工具:IntelliJ IDEA (笔者用的是2024最新版)
JDK:17
Maven:3.6以上
Nacos:2.0以上

上面这些用的基本工具自行安装哈,笔者这里就不展示了,应该没什么问题

主体项目结构

producer-module: 生产者服务模块
consumer-module: 消费者服务模块
gateway-module: 网关模块
api-module: 微服务api接口模块
common-module: 核心库模块

上面的几个模块中只有producer-module、consumer-module、gateway-module是springboot应用,有独立的启动类。本项目完成了gateway网关、openfeign、sentinel、seata分布式事务、mybatis-plus、mysql数据库等常见开发组件的集成整合工作。废话不多说,下面详细展示搭建过程

项目地址microservice-project


Nacos配置和项目结构图示

在这里插入图片描述
笔者创建了一个新的命名空间:microservice-project ,没有使用默认的public

数据库和脚本准备

seata数据库

在你的本地mysql或者你的mysql服务器上创建名字为seata的数据库,在seata数据库中执行如下脚本

-- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data
CREATE TABLE IF NOT EXISTS `global_table`
(
    `xid`                       VARCHAR(128) NOT NULL,
    `transaction_id`            BIGINT,
    `status`                    TINYINT      NOT NULL,
    `application_id`            VARCHAR(32),
    `transaction_service_group` VARCHAR(32),
    `transaction_name`          VARCHAR(128),
    `timeout`                   INT,
    `begin_time`                BIGINT,
    `application_data`          VARCHAR(2000),
    `gmt_create`                DATETIME,
    `gmt_modified`              DATETIME,
    PRIMARY KEY (`xid`),
    KEY `idx_status_gmt_modified` (`status` , `gmt_modified`),
    KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS `branch_table`
(
    `branch_id`         BIGINT       NOT NULL,
    `xid`               VARCHAR(128) NOT NULL,
    `transaction_id`    BIGINT,
    `resource_group_id` VARCHAR(32),
    `resource_id`       VARCHAR(256),
    `branch_type`       VARCHAR(8),
    `status`            TINYINT,
    `client_id`         VARCHAR(64),
    `application_data`  VARCHAR(2000),
    `gmt_create`        DATETIME(6),
    `gmt_modified`      DATETIME(6),
    PRIMARY KEY (`branch_id`),
    KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(
    `row_key`        VARCHAR(128) NOT NULL,
    `xid`            VARCHAR(128),
    `transaction_id` BIGINT,
    `branch_id`      BIGINT       NOT NULL,
    `resource_id`    VARCHAR(256),
    `table_name`     VARCHAR(32),
    `pk`             VARCHAR(36),
    `status`         TINYINT      NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking',
    `gmt_create`     DATETIME,
    `gmt_modified`   DATETIME,
    PRIMARY KEY (`row_key`),
    KEY `idx_status` (`status`),
    KEY `idx_branch_id` (`branch_id`),
    KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

CREATE TABLE IF NOT EXISTS `distributed_lock`
(
    `lock_key`       CHAR(20) NOT NULL,
    `lock_value`     VARCHAR(20) NOT NULL,
    `expire`         BIGINT,
    primary key (`lock_key`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('AsyncCommitting', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryCommitting', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryRollbacking', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('TxTimeoutCheck', ' ', 0);

seata数据库事务相关的脚本在seata安装路径下:D:\devSofts\seata\script\server\db,去自己的seata安装路径下找到执行即可

在这里插入图片描述
注意:这里数据库名为seata,和后面的 seata-server.properties文件中数据库配置命名一致

transaction_database数据库

在自己的mysql服务器上再创建名为transaction_database,执行如下脚本

create table if not exists transaction_database.consumer
(
    id          bigint auto_increment
        primary key,
    name        varchar(100)  not null,
    delete_flag int default 0 not null
)
    charset = utf8mb4;

create table if not exists transaction_database.producer
(
    id          bigint auto_increment
        primary key,
    name        varchar(100)  not null,
    create_time datetime      not null,
    update_time datetime      null,
    delete_flag int default 0 not null
)
    charset = utf8mb4;

create table if not exists transaction_database.undo_log
(
    id            bigint auto_increment comment '主键ID'
        primary key,
    branch_id     bigint       not null comment '分支事务ID',
    xid           varchar(100) not null comment '全局事务唯一标识',
    context       varchar(128) not null comment '上下文',
    rollback_info longblob     not null comment '回滚信息',
    log_status    int          not null comment '状态,0正常,1全局已完成(防悬挂)',
    log_created   datetime     not null comment '创建时间',
    log_modified  datetime     not null comment '修改时间',
    constraint ux_undo_log
        unique (xid, branch_id)
)
    comment 'AT模式回滚日志表';


上面的数据库producer、consumer分别为笔者创建的业务相关的数据库,undo_log也是seata分布式事务用到的数据库


一、Spring Boot、Spring Cloud、Sping Cloud Alibaba

  1. Spring Boot:

    • Spring Boot 是一个基于 Spring 框架的简化新框架,它的设计目的是用来简化新Spring应用的初始搭建以及开发过程。
    • 它使得配置Spring应用变得更加简单,同时也提供了很多非功能性特性,如内嵌服务器、安全、健康检查、指标等。
    • Spring Boot 的主要特点是约定优于配置,通过starter依赖管理简化了第三方库的集成。
  2. Spring Cloud:

    • Spring Cloud 是一系列框架的集合,它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如配置管理、服务发现、断路器、路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话、集群状态等。
    • 它允许开发者将这些功能中的每一个都作为一个独立的服务进行开发,然后添加到应用中,从而避免了复杂的分布式系统开发。
  3. Spring Cloud Alibaba:

    • Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含了一系列已经准备好的微服务组件,包括服务发现注册、分布式配置中心、消息驱动能力等。
    • 它集成了阿里巴巴开源项目Dubbo、Nacos、Sentinel等,提供与Spring Cloud 相似的微服务开发体验,同时利用阿里巴巴在微服务领域的经验提供了更加健壮的服务治理方案。
    • 对于使用Java生态进行微服务开发的团队来说,Spring Cloud Alibaba 提供了一个更贴近中国开发者习惯的工具包。

注意:Spring Cloud 本身并不是一个开箱即用的框架,它是一套微服务规范,共有两代实现。

  • Spring Cloud NetflixSpring Cloud 的第一代实现,主要由 Eureka、Ribbon、Feign、Hystrix 等组件组成。
  • Spring Cloud AlibabaSpring Cloud 的第二代实现,主要由 Nacos、Sentinel、Seata 等组件组成。

说实话,阿里对国内Java相关的技术发展起到了很大的领头作用,提供了很多适合国人的开发工具和开发规范,笔者用的最多的微服务框架即是alibaba的这套。


二、seata安装

seata配置修改

windows下安装seata-server服务,这个网上有很多博客介绍,这里不再展示了,仅上传一个压缩包资源,压缩包中包含了1.7.0和1.8.0两个版本,笔者使用的是1.8.0版本,解压如下

在这里插入图片描述

进入conf目录下,打开application.yml文件

#  Copyright 1999-2019 Seata.io Group.
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

server:
  port: 7091

spring:
  application:
    name: seata-server

logging:
  config: classpath:logback-spring.xml
  file:
    path: ${log.home:${user.home}/logs/seata}
  extend:
    logstash-appender:
      destination: 127.0.0.1:4560
    kafka-appender:
      bootstrap-servers: 127.0.0.1:9092
      topic: logback_to_logstash

console:
  user:
    username: seata
    password: seata
seata:
  config:
    # support: nacos, consul, apollo, zk, etcd3
    type: nacos
    nacos:
      serverAddr: 127.0.0.1:8848
      namespace: microservice-project
      group: SEATA_GROUP
      username: nacos
      password: nacos
      dataId: seata-server.properties
  registry:
    # support: nacos, eureka, redis, zk, consul, etcd3, sofa
    type: nacos
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      namespace: microservice-project
      cluster: default
      username: nacos
      password: nacos
  store:
    # support: file 、 db 、 redis
    mode: db
    session:
      mode: db
    lock:
      mode: db
    db:
      datasource: durid
      db-type: mysql
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/seata?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
      user: root
      password: 123456
      min-conn: 10
      max-conn: 100
      global-table: global-table
      branch-table: branch-table
      lock-table: lock-table
      distributed-lock-table: distributed_lock
      query-limit: 1000
      max-wait: 5000
#  server:
#    service-port: 8091 #If not configured, the default is '${server.port} + 1000'
  security:
    secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
    tokenValidityInMilliseconds: 1800000
    ignore:
      urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.jpeg,/**/*.ico,/api/v1/auth/login

其中的数据库信息,nacos配置相关信息根据自己的配置修改即可,注意上面的命名空间:namespace: microservice-project ,这个是笔者使用的Nacos命名空间,要对应上

Nacos新建配置文件seata-server.properties

#For details about configuration items, see https://seata.io/zh-cn/docs/user/configurations.html
#Transport configuration, for client and server
transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableTmClientBatchSendRequest=false
transport.enableRmClientBatchSendRequest=true
transport.enableTcServerBatchSendResponse=false
transport.rpcRmRequestTimeout=30000
transport.rpcTmRequestTimeout=30000
transport.rpcTcRequestTimeout=30000
transport.threadFactory.bossThreadPrefix=NettyBoss
transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker
transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler
transport.threadFactory.shareBossWorker=false
transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector
transport.threadFactory.clientSelectorThreadSize=1
transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread
transport.threadFactory.bossThreadSize=1
transport.threadFactory.workerThreadSize=default
transport.shutdown.wait=3
transport.serialization=seata
transport.compressor=none
#Transaction routing rules configuration, only for the client
service.vgroupMapping.default_tx_group=default
#If you use a registry, you can ignore it
service.default.grouplist=127.0.0.1:8091
service.enableDegrade=false
service.disableGlobalTransaction=false
#Transaction rule configuration, only for the client
client.rm.asyncCommitBufferLimit=10000
client.rm.lock.retryInterval=10
client.rm.lock.retryTimes=30
client.rm.lock.retryPolicyBranchRollbackOnConflict=true
client.rm.reportRetryCount=5
client.rm.tableMetaCheckEnable=true
client.rm.tableMetaCheckerInterval=60000
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.rm.sagaJsonParser=fastjson
client.rm.tccActionInterceptorOrder=-2147482648
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.defaultGlobalTransactionTimeout=60000
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
client.tm.interceptorOrder=-2147482648
client.undo.dataValidation=true
client.undo.logSerialization=jackson
client.undo.onlyCareUpdateColumns=true
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000
client.undo.logTable=undo_log
client.undo.compress.enable=true
client.undo.compress.type=zip
client.undo.compress.threshold=64k
#For TCC transaction mode
tcc.fence.logTableName=tcc_fence_log
tcc.fence.cleanPeriod=1h
#Log rule configuration, for client and server
log.exceptionRate=100
#Transaction storage configuration, only for the server. The file, db, and redis configuration values are optional.
store.mode=file
store.lock.mode=file
store.session.mode=file
#Used for password encryption
store.publicKey=
#If `store.mode,store.lock.mode,store.session.mode` are not equal to `file`, you can remove the configuration block.
store.file.dir=file_store/data
store.file.maxBranchSessionSize=16384
store.file.maxGlobalSessionSize=512
store.file.fileWriteBufferCacheSize=16384
store.file.flushDiskMode=async
store.file.sessionReloadReadSize=100
#These configurations are required if the `store mode` is `db`. If `store.mode,store.lock.mode,store.session.mode` are not equal to `db`, you can remove the configuration block.
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=123456
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.distributedLockTable=distributed_lock
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000
#These configurations are required if the `store mode` is `redis`. If `store.mode,store.lock.mode,store.session.mode` are not equal to `redis`, you can remove the configuration block.
store.redis.mode=single
store.redis.single.host=127.0.0.1
store.redis.single.port=6379
store.redis.sentinel.masterName=
store.redis.sentinel.sentinelHosts=
store.redis.sentinel.sentinelPassword=
store.redis.maxConn=10
store.redis.minConn=1
store.redis.maxTotal=100
store.redis.database=0
store.redis.password=
store.redis.queryLimit=100
#Transaction rule configuration, only for the server
server.recovery.committingRetryPeriod=1000
server.recovery.asynCommittingRetryPeriod=1000
server.recovery.rollbackingRetryPeriod=1000
server.recovery.timeoutRetryPeriod=1000
server.maxCommitRetryTimeout=-1
server.maxRollbackRetryTimeout=-1
server.rollbackRetryTimeoutUnlockEnable=false
server.distributedLockExpireTime=10000
server.xaerNotaRetryTimeout=60000
server.session.branchAsyncQueueSize=5000
server.session.enableBranchAsyncRemove=false
server.enableParallelRequestHandle=false
#Metrics configuration, only for the server
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898

store相关的信息自行修改,包括db和redis相关连接配置,需要注意的是如下一行

#Transaction routing rules configuration, only for the client
service.vgroupMapping.default_tx_group=default

这个 default_tx_group 是默认的分布式事务组名称,这个可以随便写,但是后面的produle-module-dev.yml中的一些配置需要和此处对应上。


三、创建Microservice-Project项目

笔者要创建的是一个Spring Cloud微服务项目,所以需要一个Maven聚合项目把各个微服务组件聚合起来组成一个完整的项目。

打开IDEA 的New->Project,选择 Maven Archetype,设置好整个微服务项目的名称 Microservice-Project

在这里插入图片描述
JDK版本选择17,右击右边的Add填写Maven项目的GAV坐标信息

  • Group ID:这是项目的唯一标识符,通常采用反向域名的形式来避免冲突,例如com.alibaba。
  • Artifact ID:表示具体项目的名称,它与Group ID一起构成了项目的坐标。
  • Version:指定项目的具体版本号,如1.0.0,2.3.1等

在这里插入图片描述

创建好的Maven项目的pom文件如下,如果groupId不是com.microservice这个值而是其他值,自行修改即可

<?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.microservice</groupId>
    <artifactId>Microservice-Project</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>

比较重要的是 <properties>标签里的内容,下面是一些解释

  • <maven.compiler.source>: 指定了项目编译时所使用的Java源代码版本。在这个例子中,值为17表示使用Java 17的语法和特性。
  • <maven.compiler.target>: 指定了输出的字节码版本。这里同样设置为17,意味着编译后的class文件将兼容Java 17运行环境。
  • <project.build.sourceEncoding>: 定义了项目源代码的字符编码方式。设置为UTF-8确保了对各种字符的良好支持,包括中文和其他多语言文本。

注意:后续的一些依赖库版本管理也会在这里进行,更改版本时可以比较方便的找到

项目结构如下,没什么问题

在这里插入图片描述

注意:我们需要在pom文件中加入如下一行

<packaging>pom</packaging>

在Maven中,packaging 元素指定了构建项目时生成的包的类型。不同的packaging类型决定了Maven如何构建项目及其输出形式。以下是两种常见的packaging类型:

  • pom
    • pom类型的项目主要用于聚合其他Maven项目,本身并不编译任何Java代码或生成可执行 的JAR文件。
    • 它主要用于管理和组织多个子模块或子项目的依赖关系和生命周期。
    • 示例配置:
<packaging>pom</packaging>

- jar

  • jar类型的项目会编译Java源代码,并将编译后的类文件打包成一个JAR文件。
  • 这是最常见的Maven项目类型,适用于大多数Java应用程序和库。
  • 示例配置:
<packaging>jar</packaging>

另外就是我们需要设置下IDEA针对当前项目的文件编码格式,File->Settins->Editor->File Encodings,防止一些文件比如yaml文件出现中文乱码

在这里插入图片描述

最顶级父工程 Microservice-Project 添加一些必要的基础依赖,为了统一子工程中的依赖版本,需要在最顶级父工程的pom文件中做好第三方各种依赖的版本控制,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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.microservice</groupId>
    <artifactId>Microservice-Project</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>pom</packaging>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-cloud.version>2022.0.0</spring-cloud.version>
        <spring-cloud-alibaba.version>2022.0.0.0</spring-cloud-alibaba.version>
        <spring-boot.version>3.0.1</spring-boot.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- SpringCloudAlibaba 依赖配置-->
            <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>
            <!-- SpringCloud 依赖配置 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- SpringBoot 依赖配置 -->
            <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>

</project>

加入了spring-cloud-alibaba-dependencies、spring-cloud-dependencies、spring-boot-dependencies,并在上面的 <properties> 中规定了各个依赖的版本,这三个依赖本身都是一些常用依赖的合集,我们引入时不用担心其内部依赖的版本适配问题,但是这个三个依赖的版本要有一定的适配关系,具体版本适配关系请参考 spring cloud>spring cloud alibaba 官方网址:Spring Cloud Alibaba

在这里插入图片描述

除了以上部分,最顶级父工程文件还需要添加如下部分

 <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                    <basedir/>
                    <buildDirectory/>
                    <mainOutputDirectory/>
                    <outputDirectory/>
                    <projectArtifact/>
                </configuration>
            </plugin>
        </plugins>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>${spring-boot.version}</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
  • maven-compiler-plugin:Maven 构建过程中使用的插件,这个插件主要是编译Java源代码
  • spring-boot-maven-plugin: 这个插件Spring Boot 应用程序的构建和打包,加在这里是为了统一控制版本,方便子模块引用

需要注意的是下面这个部分

 <executions>
      <execution>
           <goals>
                <goal>repackage</goal>
           </goals>
       </execution>
 </executions>

这个配置的作用是让当前模块在打包时打包成一个可执行的jar包,当然是子模块为Spring Boot应用时需要显示的在子模块中加上。笔者使用的Spring Boot版本是3.0.1,如果是3.0.2或者之后的Spring Boot版本时,这个配置甚至直接失效飘红,3.0.1其实也是没必要加的,spring-boot-maven-plugin会自动将其打包成可执行的jar包,前提是你的模块有springboot启动器(即启动类)。


四、创建api-module聚合Maven

笔者为本项目设置了一个api接口模块,由于可能会存在多个模块的接口,所以api-module是一个Maven聚合模块,在其下继续建立各个微服务模块对应的api接口模块

在这里插入图片描述

api-module模块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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.microservice</groupId>
        <artifactId>Microservice-Project</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>api-module</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <modules>
        <module>consumer-api-module</module>
    </modules>
</project>

可以看到其聚合了consumer-api-module模块,consumer-api-module就是consumer-module模块对外提供的远程接口服务consumer-api-module 模块的内容如下

<?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>
    <parent>
        <groupId>com.microservice</groupId>
        <artifactId>api-module</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>consumer-api-module</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>consumer-api-module</name>
    <description>consumer-api-module消费者接口</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <!-- SpringCloud Openfeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- SpringCloud Loadbalancer -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <!--核心库core-->
        <dependency>
            <groupId>com.microservice</groupId>
            <artifactId>common-core</artifactId>
            <scope>compile</scope>
        </dependency>
        <!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>

    </dependencies>

</project>

其中的代码,笔者这里就不展示了,具体从代码库查看即可


五、创建common-module

这个模块是一个核心类库模块,和api-module类似,common-module也是一个Maven聚合模块

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.microservice</groupId>
        <artifactId>Microservice-Project</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>common-module</artifactId>
    <packaging>pom</packaging>

    <modules>
        <module>common-core</module>
    </modules>

</project>

其中的子模块common-core子模块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>
    <parent>
        <groupId>com.microservice</groupId>
        <artifactId>common-module</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>common-core</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>common-core</name>
    <description>common-core核心模块</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <!-- Apache Lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <!-- Commons Io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
        </dependency>
        <!-- Spring Context Support -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <!--mybatis-plus依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
    </dependencies>
</project>

其中的代码笔者不展示了


六、创建gateway-module模块

gateway就是做网关路由转发的,可以用来限流,安全控制等等,笔者这里没有搞得很复杂,单纯只是用来做路由的统一转发

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>
    <parent>
        <groupId>com.microservice</groupId>
        <artifactId>Microservice-Project</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>gateway-module</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gateway-module</name>
    <description>gateway-module网关模块</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <!--gateway网关模块依赖,引入后无须再引入spring-boot-starter-web,否则启动不了-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--包含了很多测试库工具,非必须强制引入-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--nacos服务发现中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--nacos配置中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!--必须引入,否则会无法读取nacos上的配置信息,注意你的配置文件名也要是bootstrap-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
        <!--必须要引入负载均衡,请求通过gateway的路由配置转发到服务提供者时需要负载均衡lb://service-name,否则报错503-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

注意:spring-cloud-starter-gateway依赖引入后无需再引入spring-boot-starter-web,因为前者已经包含了后者,再引入便会发生冲突,启动报错

yml内容

spring:
  application:
    name: gateway-module
  profiles:
    # 环境配置
    active: dev
  cloud:
    nacos:
      discovery:
        username: nacos
        password: nacos
        namespace: microservice-project
        server-addr: localhost:8848
      config:
        file-extension: yml
        username: nacos
        password: nacos
        namespace: microservice-project
        server-addr: localhost:8848
        group: DEFAULT_GROUP
        import-check:
          enabled: false
        # 共享配置
        shared-configs:
          - share-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
server:
  port: 8080


另外在Nacos上建立一个配置文件: gateway-module-dev.yml,配置上需要其他服务的路由转发策略配置

spring:
  cloud:
    gateway:
      discovery:
        locator:
          lowerCaseServiceId: true
          enabled: true
      routes:
        - id: producer-module
          uri: lb://producer-module
          predicates:
            - Path=/producer/**
          filters:
            - StripPrefix=1
        - id: consumer-module
          uri: lb://consumer-module
          predicates:
            - Path=/consumer/**
          filters:
            - StripPrefix=1


七、创建producer-module

鼠标放在 Microservice-Project 文件目录上右击 New->Module,选择Spring Boot应用,填写好关键信息
在这里插入图片描述

pom文件修改

这个producer-module是一个Spring Boot应用了,但是其应该是作为Microservice-Project的一个子模块,所以我们需要对其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>
    <parent>
        <groupId>com.microservice</groupId>
        <artifactId>Microservice-Project</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    
    <artifactId>producer-module</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>producer-module</name>
    <description>producer-module生产者模块</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <!--springboot的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>
    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

可以看到 <parent>标签中的变化,变成其父模块Miroservice-Project的信息,一般来说groupId是整个项目中所有模块统一不变的,而artifactId则根据每个模块自身决定,一般就是模块的名称。

其中的两个spring-boot-starter-web和spring-boot-starter-test也是从父工程pom文件继承下来,不用显示指定版本了。最后的<build>表明这个是一个Spring Boot应用。

<finalName>${project.artifactId}</finalName>则是规定了打包后的jar包名称producer-module.jar,如果不写这个配置,则打包后的名称默认为为artifactId+version.jar,即为 producer-module-0.0.1-SNAPSHOT.jar,很长,所以还是加上的好。

另外,顶级父工程Microservice-Project的pom文件需要加入如下内容,才能真正的作为Maven聚合工程,后续再有其他子模块,也需要加入这个<modules>中

    <modules>
        <module>producer-module</module>
    </modules>

引入nacos依赖

因为所有的配置和服务注册均是放在Nacos上的,所以producer-module模块的pom文件需要引入如下三个依赖

<!--nacos服务发现中心-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--nacos配置中心-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--必须引入,否则会无法读取nacos上的配置信息,注意你的yml配置文件名也要是bootstrap或者bootstrap开头-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>

bootstrap.yml文件配置

点开Resource目录下可以看到applications.properties文件

在这里插入图片描述

将其改名为bootstrap.yml(bootstrap.yaml也可以),并写入如下内容

spring:
  application:
    name: producer-module
  profiles:
    # 环境配置
    active: dev
  cloud:
    nacos:
      discovery:
        username: nacos
        password: nacos
        server-addr: localhost:8848
        namespace: microservice-project
      config:
        username: nacos
        password: nacos
        namespace: microservice-project
        server-addr: localhost:8848
        group: DEFAULT_GROUP
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - share-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
server:
  port: 8081

上面的配置主要是配置了nacos作为服务发现和配置中心的信息,以及一个共享配置shared-configs。

启动类添加注解@EnableDiscoveryClient

@EnableDiscoveryClient 是 Spring Cloud 中的一个注解,用于启用服务发现客户端的功能。具体来说,它有以下几个作用:

  1. 服务注册与发现
    当一个微服务应用使用 @EnableDiscoveryClient 注解时,该应用会自动注册到服务发现服务器(如 Eureka、Consul 或 Nacos)上。
    同时,该应用也可以通过服务发现服务器获取其他服务的信息,并进行调用。
  2. 自动配置
    该注解会自动配置一些必要的组件,例如服务发现客户端实现类和服务实例注册器。
    它会根据配置自动选择合适的服务发现客户端实现,比如 Nacos Discovery Client。
  3. 简化开发
    使用 @EnableDiscoveryClient 可以简化服务发现相关的开发工作,无需手动编写复杂的注册与发现逻辑。

这个注解非常重要,如果不加,就没法使用Nacos实现服务的自动注册发现功能。至于为什么加了@EnableDiscoveryClient注解的启动类,就会自动注册到Nacos,笔者这里不做探讨。原理也不复杂,其实就是我们引入的Nacos服务发现依赖,其中有一个 NacosDiscoveryClient 类实现了DiscoveryClient接口,这个就是Spring Cloud中服务注册与发现相关的处理接口,具体可以阅读这篇文章:深入理解DiscoveryClient

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

Nacos新建命名空间microservice-project

在这里插入图片描述

注意命名空间ID和命名空间名称,笔者这里都是一致的。我们的yml配置中的 namespace: microservice-project其实是指命名空间ID而不是命名空间名称,这点要知晓。

producer-module-dev.yml配置文件

在配置管理中点击选中命名空间 microservice-project

在这里插入图片描述

新建一个Data Id名称为producer-module-dev.yml的配置文件,初步加入数据库连接配置,数据源使用得是阿里巴巴得druid

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/transaction_database?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

在这里插入图片描述

Nacos上创建的默认配置文件名就是<应用名称>.<环境>.<扩展名>,具体如下

在这里插入图片描述

引入mybatis-plus、mysql、druid依赖

由于要使用到数据库,所以需要引入这三个依赖,笔者的习惯是把所有的依赖现在顶级父工程的pom文件中引入,使用<dependencyManagement>统一管理版本,、子模块中需要用到时再引入

以下是Microservice-Project的pom文件引入内容

<!--mysql数据库连接驱动-->
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>${mysql.version}</version>
</dependency>
<!--druid数据源-->
<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid-spring-boot-starter</artifactId>
   <version>${druid.version}</version>
</dependency>
<!--mybatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>${mybaits-plus.version}</version>
</dependency>

上面的本版本<properties>加入如下内容

在这里插入图片描述

producer-module的pom文件下再引入这三个依赖

<!--mysql数据库连接驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<!--druid数据源-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<!--mybatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>

引入openfeign依赖

和上面的操作一样,但是父工程中的**spring-cloud-alibaba-dependencies**依赖集已经包含了,无需在父工程中再显示引入
直接在producer-module子模块中引入依赖即可

<!--openfeign依赖,实现服务的远程调用-->
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--  使用openfeign 负载均衡 必须引入loadbalancer  	-->
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

引入seata依赖

Microservice-Project父工程pom引入如下

 <!--seata依赖-->
<dependency>
   <groupId>io.seata</groupId>
   <artifactId>seata-spring-boot-starter</artifactId>
   <version>${seata.starter.version}</version>
</dependency>
<dependency>
   <groupId>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
   <version>2021.0.5.0</version>
   <exclusions>
      <exclusion>
          <groupId>io.seata</groupId>
          <artifactId>seata-spring-boot-starter</artifactId>
      </exclusion>
   </exclusions>
</dependency>

producer-module模块的pom文件引入内容如下

<!--seata依赖-->
<dependency>
   <groupId>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
<dependency>
   <groupId>io.seata</groupId>
   <artifactId>seata-spring-boot-starter</artifactId>
</dependency>

引入sentinel依赖

本例中需要演示微服务之间接口调用发生异常时服务降级的方法,需要用到alibaba的一款开源工具sentinel(lombok依赖是顺带引入的,不属于sentinel),sentinel也是在**spring-cloud-alibaba-dependencies**中包含了,父模块无需引入

 <!--lombok依赖,简化代码,不用写getter、setter等方法-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <scope>provided</scope>
</dependency>
<!--调用远程服务异常时降级,本依赖一般加在服务调用者模块pom中-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

到这里为止,producer-module模块的依赖集成工作算是结束了,现在回过头再把Nacos上的produce-module-dev.yml配置补充完整

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/transaction_database?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: delete_flag
      logic-delete-value: 2
      logic-not-delete-value: 0 
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  type-aliases-package: com.feign.producer
  mapper-locations: classpath:mapper/**/*.xml



seata:
  registry:
    type: nacos
    nacos:
      server-addr: localhost:8848
      namespace: microservice-project
      group: SEATA_GROUP 
      application: seata-server
      username: nacos
      password: nacos
  tx-service-group: default_tx_group
  service:
    vgroup-mapping:
      default_tx_group: default
  data-source-proxy-mode: AT

注意上面的配置,和文章第二节点中描述的对应上

 service:
    vgroup-mapping:
      default_tx_group: default

启动类完善

package com.microservice.producer;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.microservice.api")
@MapperScan("com.microservice.**.mapper")
public class ProducerModuleApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProducerModuleApplication.class, args);
    }

}

@EnableFeignClients(basePackages = "com.microservice.api")是为了扫描api模块的包

@MapperScan("com.microservice.**.mapper")则是配置扫描持久层对应的Mapper接口


八、创建consumer-module

pom依赖

本模块相对来说就简单了,直接展示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>
    <parent>
        <groupId>com.microservice</groupId>
        <artifactId>Microservice-Project</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>consumer-module</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>consumer-module</name>
    <description>consumer-module消费者模块</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <packaging>jar</packaging>

    <dependencies>
        <!--common core核心模块引入-->
        <dependency>
            <groupId>com.microservice</groupId>
            <artifactId>common-core</artifactId>
        </dependency>
        <!--springboot的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>
        <!--nacos服务发现中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--nacos配置中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!--必须引入,否则会无法读取nacos上的配置信息,注意你的配置文件名也要是bootstrap-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
        <!--lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
        <!--调用远程服务异常时降级,本依赖一般加在服务调用者模块pom中,本模块如果没有调用其他远程服务的模块,可以不引入-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--mysql数据库驱动相关依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--druid驱动-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>
        <!--seata依赖-->
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
        </dependency>
        <!--mybatis-plus依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

注意:consumer-module模块为什么没有引入openfeign相关依赖?因为这个模块只充当了服务提供者的角色,producer-module模块通过调用api-module下的consumer-api-module中提供的远程服务接口来完成请求,所以producer-module模块需要引入openfeign相关依赖

consumer-module-dev.yml

同样的在Nacos上创建consumer-module-dev.yml配置文件

spring:
   datasource:
      url: jdbc:mysql://localhost:3306/transaction_database?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
      username: root
      password: 123456
      driver-class-name: com.mysql.cj.jdbc.Driver
      type: com.alibaba.druid.pool.DruidDataSource
                           
mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: delete_flag
      logic-delete-value: 2
      logic-not-delete-value: 0
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  type-aliases-package: com.microservice.consumer
  mapper-locations: classpath:mapper/**/*.xml


seata:
  registry:
    type: nacos
    nacos:
      server-addr: localhost:8848
      namespace: microservice-project
      group: SEATA_GROUP 
      application: seata-server
      username: nacos
      password: nacos
  tx-service-group: default_tx_group
  service:
    vgroup-mapping:
      default_tx_group: default
  data-source-proxy-mode: AT

到这里所有模块的集成工作已经完成了,接下来的最后一节内容展示sentinel、openfeign、seata的分布式事务


九、功能演示

openfeign演示

在producer-module模块中通过api接口远程调用

在这里插入图片描述

在这里插入图片描述

地址为:http://localhost:8080/producer/message/handle

是通过gateway的8080端口进入,再路由转发到producer-module模块的服务

在这里插入图片描述

sentinel演示

在consumer-module服务编写会抛出异常的代码

在这里插入图片描述

再次调用会发现consumer-module模块抛出异常了

在这里插入图片描述
producer-module模块没有抛出异常
在这里插入图片描述

设置的feign异常降级回调如下
在这里插入图片描述

使用apifox工具请求测试,说明成功使用sentinel降级

在这里插入图片描述

seata分布式事务演示

在这里插入图片描述

调用地址:http://localhost:8080/producer/message/commit

分别在producer和consumer表生成了两条数据

在这里插入图片描述

接着远程调用上面的地址

在这里插入图片描述
把consumer模块的接口中添加上抛出异常的代码
在这里插入图片描述

请求后发现数据并没有生成了,seata分布式事务产生回滚

在这里插入图片描述


十、总结

以上就是笔者搭建微服务过程的教程,步骤稍显杂乱,但整个集成过程是清晰的,有问题评论区找我,尽量回复。


http://www.niftyadmin.cn/n/5689702.html

相关文章

C0005.Clion中移动ui文件到新目录后,报错问题的解决

报错问题如下 AutoUic error ------------- "SRC:/confirmwizardpage.cpp" includes the uic file "ui_confirmwizardpage.h", but the user interface file "confirmwizardpage.ui" could not be found in the following directories"SRC…

Python--解决从Hugging Face的服务器下载某个预训练模型或其相关的文件问题

一.错误信息&#xff1a;ValueError: Connection error, and we cannot find the requested files in the cached path. Please try again or make sure your Internet connection is on. 这个错误信息表明正在尝试从 Hugging Face 的服务器下载某个预训练模型或其相关的文件&…

接口+内部类

接口和内部类是Java中两个重要的概念&#xff0c;可以在代码中使用它们来实现更灵活和模块化的设计。 接口是一种定义了一组抽象方法的特殊类&#xff0c;其中的方法没有具体的实现。通过实现接口&#xff0c;一个类可以获得接口中定义的方法&#xff0c;并提供实际的实现。接…

什么是 HTTP 请求中的 options 请求?

在 Chrome 开发者工具中的 Network 面板看到的 HTTP 方法 OPTIONS&#xff0c;其实是 HTTP 协议的一部分&#xff0c;用于客户端和服务器之间进行“预检”或“协商”。OPTIONS 请求的作用是让客户端能够获取关于服务器支持的 HTTP 方法和其他跨域资源共享 (CORS) 相关的信息&am…

macOS终端配置自动补全功能

如何在macOS终端中配置自动补全功能 终端是一个非常强大的工具&#xff0c;它可以用来完成很多任务&#xff0c;比如创建、复制、移动、删除文件&#xff0c;执行脚本和运行程序。不过它的默认设置对用户不太友好&#xff0c;作为开发者&#xff0c;我们通常习惯代码编辑器的辅…

eNSP网络配置指南:IP设置、DNS、Telnet、DHCP与路由表管理

1.eNSP基本操作和路由器IP配置命令 登录设备&#xff1a;通过Console口或通过eNSP的Telnet/SSH客户端登录到设备。进入特权模式&#xff1a;输入system-view进入系统视图。接口配置&#xff1a; 进入接口视图&#xff0c;例如interface GigabitEthernet0/0/0。配置IP地址和子网…

Kubernetes-环境篇-02-ubuntu开发环境搭建

1、ubuntu基础环境 # 更新apt软件源 sudo apt update# 安装git sudo apt install git# 安装python3 sudo apt install -y python3 python3-pip# 安装vim sudo apt install vim2、安装go 2.1 下载go安装包 wget https://golang.google.cn/dl/go1.23.2.linux-amd64.tar.gz2.2 …

基于matlab的指纹识别

随着科学技术的不断发展&#xff0c;自动化的指纹识别技术如今已经被人们广泛地应用在银行、商业交易、公安部门、海关部门等需要对人的身份进识别的领域&#xff0c;而本文所描述的是对自动化指纹识别系统的研究现状以及自动化指纹识别系统的基本算法和流程&#xff0c;本实验…