SpringCloud微服务搭建实战

news2024/11/23 12:21:17

文章目录

  • 前言
  • 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 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.coloradmin.cn/o/2188596.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【HTML5】html5开篇基础(5)

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…

使用MTVerseXR SDK实现VR串流

1、概述​ MTVerseXR SDK 是摩尔线程GPU加速的虚拟现实&#xff08;VR&#xff09;流媒体平台&#xff0c;专门用于从远程服务器流式传输基于标准OpenXR的应用程序。MTVerseXR可以通过Wi-Fi和USB流式将VR内容从Windows服务器流式传输到XR客户端设备, 使相对性能低的VR客户端可…

芯片公司产品简介

台湾新唐科技:ARM内核-nuvoTon stc&#xff08;宏晶&#xff09;&#xff1a;STC 8051 系列、STC32 8051系列、STC32 ARM系列 兆易&#xff1a;Arm Cortex-M内核和RISC-V内核 意法&#xff1a; 乐鑫科技&#xff1a; MCU厂家 GPU厂家 MCU与MPU 引用链接&#xff1a; http://…

AutoCAD学习

AutoCAD学习 最基本操作 命令用途说明空格键确认键也可以是重复刚才的命令回车键也是确认键鼠标右键也可以选择确认LINE、L直线命令绘制直线DLI线性尺寸标注DIMLINEAR鼠标滚轮滚动放大缩小视图界面鼠标中键按住移动视图DAL对齐线性标注DIMALIGNED F8 正交模式ORTHOMODE Tab 切换…

漆包线称重系统/自动称重/项目合作

万界星空科技漆包线行业称重系统实现自动称重的方式主要依赖于现代数字电子称重技术、计算机网络技术以及相关的软件系统的集成。以下是对该系统如何实现自动称重的详细解释&#xff1a; 一、硬件基础 称重设备&#xff1a; 系统采用高精度的电子秤作为称重设备&#xff0c;这…

TOGAF框架中的最佳实践与实施技巧:推动企业数字化转型的实战指南

企业的数字化转型已经成为全球商业界的一大趋势&#xff0c;而实现这一转型不仅需要技术的创新&#xff0c;还需要清晰的架构规划和实施策略。TOGAF&#xff08;The Open Group Architecture Framework&#xff09;作为全球广泛应用的企业架构标准&#xff0c;为企业提供了行之…

Pikachu-File Inclusion- 本地文件包含

前端每次挑选篮球明星&#xff0c;都会通过get请求&#xff0c;传了文件名&#xff0c;把页面展示出来&#xff0c;由于文件名时前端传给后台;并且查看源码&#xff0c;没有对参数做限制&#xff1b; 尝试直接从前端修改filename 参数&#xff1b; filename../../../../../../…

24-10-3-读书笔记(二十三)-《一个孤独漫步者的遐想》上([法] 让·雅克·卢梭 [译]陈阳)

文章目录 《一个孤独漫步者的遐想》上&#xff08;[法] 让雅克卢梭 [译]陈阳&#xff09;卢梭生平大事年表总结 《一个孤独漫步者的遐想》上&#xff08;[法] 让雅克卢梭 [译]陈阳&#xff09; 十月第三篇&#xff0c;看书看个爽&#xff0c;今天是法国哲学家卢梭晚年的著作《一…

【C++】—— vector模拟实现

vector 接口预览 namespace HL {template<class T>class vector{//迭代器iteratortypedef T* iterator;typedef const T* const_iterator;public://默认成员函数vector();vector(size_t n, const T& val T());vector(int n, const T& val T());vector(const v…

【学习资源】人在环路的机器学习

说明&#xff1a;本文图片和内容来源 Human-in-the-Loop Machine Learning Human-in-the-Loop Machine Learning Active learning and annotation for human-centered AI by Robert (Munro) Monarch, June 2021 介绍Human-in-the-Loop的目标&#xff0c;学习过程&#xff0c…

Redis:通用命令 数据类型

Redis&#xff1a;通用命令 & 数据类型 通用命令SETGETKEYSEXISTSDELEXPIRETTLTYPEFLUSHALL 数据类型 Redis的客户端提供了很多命令用于操控Redis&#xff0c;在Redis中&#xff0c;key的类型都是字符串&#xff0c;而value有多种类型&#xff0c;每种类型都有自己的操作命…

DMA 正点原子版

就是介绍一下dma&#xff0c;只能内存到外设&#xff0c;外设到内存&#xff0c;内存到内存&#xff0c;不能外设到外设这样进行数据传输 这个是 可以看这个表来查&#xff0c;哪个dma的哪个通道用来传输什么数据&#xff0c;这个是芯片固定好的&#xff0c;只能看表查&#xf…

Geogebra基础篇002—关于Geogebra软件的介绍及与MatLab的区别

为什么要学Geogebra&#xff1f; 因为和MatLab的科学计算相比&#xff0c;GeoGebra重点突出教学展示&#xff0c;对于教师、学生人群来讲再合适不过了&#xff0c;尤其是可以融入到PPT里边呈现交互式动画&#xff0c;想想听众的表情&#xff01;这不就弥补了看到PPT播放数学公…

Python+Matplotlib-高等数学上-P7-例如部分可视化

import numpy as np import matplotlib.pyplot as plt# 设置中文字体&#xff0c;确保中文显示正确 plt.rcParams[font.sans-serif] [SimHei] # 用黑体显示中文 plt.rcParams[axes.unicode_minus] False # 正常显示负号# 设置图形和子图 fig, (ax1, ax2) plt.subplots(2, …

Qt 5开发步骤及实例

目录 界面设计编写相应的计算圆面积代码 界面设计 创建桌面应用程序 得到这样一个树形视图 双击界面文件中的dialog.ui 直接双击控件label改名&#xff0c;然后修改最后一个label的属性 修改这个标签的样式&#xff0c;把frameshape改成Panel&#xff0c;frameshadow改…

LC刷题专题:二叉树;迭代;递归(897、1372、208)

文章目录 897.递增顺序搜索树1372. 二叉树中的最长交错路径208. 实现 Trie (前缀树) 897.递增顺序搜索树 https://leetcode.cn/problems/increasing-order-search-tree/description/ 这道题目本身就是一个简单题&#xff1a;非常容易实现&#xff1a;只需要在递归或者迭代中序…

【Java的SPI机制】Java SPI机制:实现灵活的服务扩展

在Java开发中&#xff0c;SPI&#xff08;Service Provider Interface&#xff0c;服务提供者接口&#xff09;机制是一种重要的设计模式&#xff0c;它允许在运行时动态地插入或更换组件实现&#xff0c;从而实现框架或库的扩展点。本文将深入浅出地介绍Java SPI机制&#xff…

【Godot4.3】复合路径类myPath

概述 之前编写过一个基于指令绘图的类交myPoint&#xff0c;但是只涉及折线段生成。这次我基于SVG的<path>标签路径指令的启发&#xff0c;实现了一个能够获得连续绘制的直线段、圆弧和贝塞尔复合路径的类型myPath。 可以使用绘图指令方法或字符串形式的绘图指令解析来…

hbuilderx+uniapp+Android宠物用品商城领养服务系统的设计与实现 微信小程序沙箱支付

目录 项目介绍支持以下技术栈&#xff1a;具体实现截图HBuilderXuniappmysql数据库与主流编程语言java类核心代码部分展示登录的业务流程的顺序是&#xff1a;数据库设计性能分析操作可行性技术可行性系统安全性数据完整性软件测试详细视频演示源码获取方式 项目介绍 顾客 领养…

OpenCAEPoro优化(1)

核心目的&#xff1a;减少运行时的 object time 方法一&#xff1a;改变运行的进程数 进入OpenCAEPoro目录下运行下述代码&#xff08;进程数为4&#xff09; mpirun -np 4 ./testOpenCAEPoro ./data/case1/case1.data verbose1结果如下 可以看到&#xff0c;object time是…