1.1、[nacos官方文档](https://nacos.io/zh-cn/docs/quick-start.html)
1.2、[nacos下载地址](https://github.com/alibaba/nacos/releases)
1.3、进入到bin目录,打开 start.cmd 文件,将set MODE="cluster"改为set MODE=“sandalone”(将集群启动改为单实例启动)
1.4、新建nacos数据库,导入sql文件(conf/nacos-mysql.sql)
1.5、打开nacos文件下的 /conf/application.properties,配置数据库地址等
1.6、访问nacos,默认地址:http://localhost:8848/nacos,账户名密码为: nacos/nacos
2.1 父工程pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ishz.web</groupId>
<artifactId>springcloud</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>gateway</module>
<module>authentication</module>
</modules>
<packaging>pom</packaging>
<properties>
<!-- 编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- jdk -->
<java.version>1.8</java.version>
<common-version>0.0.1-SNAPSHOT</common-version>
<ishz.version>3.5.0</ishz.version>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.6.6</spring-boot.version>
<spring-cloud.version>2021.0.1</spring-cloud.version>
<spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
<alibaba.nacos.version>2.0.4</alibaba.nacos.version>
<spring-boot-admin.version>2.6.6</spring-boot-admin.version>
<spring-boot.mybatis>2.2.2</spring-boot.mybatis>
<swagger.fox.version>3.0.0</swagger.fox.version>
<swagger.core.version>1.6.2</swagger.core.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- SpringCloud 微服务 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringCloud Alibaba 微服务 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Alibaba Nacos 配置 -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${alibaba.nacos.version}</version>
</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>
<!-- SpringBoot 监控客户端 -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${spring-boot-admin.version}</version>
</dependency>
<!-- Mybatis 依赖配置 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${spring-boot.mybatis}</version>
</dependency>
<!-- Swagger 依赖配置 -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>${swagger.core.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger.core.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- bootstrap 启动器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<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>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.2子工程pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.ishz.web</groupId>
<artifactId>springcloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.ishz.web</groupId>
<artifactId>authentication</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>authentication</name>
<description>Demo project for Spring Boot</description>
<!-- 打包方式 -->
<packaging>jar</packaging>
<repositories>
<repository>
<id>getui-nexus</id>
<url>http://mvn.gt.getui.com/nexus/content/repositories/releases/</url>
</repository>
<repository>
<id>maven_group</id>
<name>maven_group</name>
<url>http://www.nexus.dev.com/repository/maven_group/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.ishz.web</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- springcloud alibaba nacos discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- springcloud loadbalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<!-- SpringBoot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<!--分发管理-->
<distributionManagement>
<!--RELEASE-->
<repository>
<id>maven_pro</id>
<name>maven_pro</name>
<url>http://www.nexus.dev.com/repository/maven_pro/</url>
</repository>
<!--snapshot-->
<snapshotRepository>
<id>maven_dev</id>
<name>maven_dev</name>
<url>http://www.nexus.dev.com/repository/maven_dev/</url>
</snapshotRepository>
</distributionManagement>
</project>
2.3 客户端bootstrap.yml配置文件
server:
port: 9000
# Spring
spring:
application:
# 应用名称
name: service-authentication
profiles:
# 环境配置
active: local
mvc:
pathmatch:
matching-strategy: ANT_PATH_MATCHER
main:
allow-circular-references: true
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
enabled: true
# 配置中心地址
server-addr: localhost:8848
# 配置文件格式
file-extension: yaml
prefix: ${spring.application.name}
# namespace: 8f6fc5c3-f6fd-43f4-ab3b-ca396ee9928f
# group: DEFAULT_GROUP
# 共享配置
shared-configs[0]:
data-id: security-local.yaml
shared-configs[1]:
data-id: datasource-local.yaml
shared-configs[2]:
data-id: security-local.yaml
shared-configs[3]:
data-id: network-local.yaml
shared-configs[4]:
data-id: redis-local.yaml
shared-configs[5]:
data-id: seata-local.yaml
2.4 nacos配置中心文件
2.4 nacos dataId命名规则
在 Nacos Spring Cloud 中,dataId 的完整格式如下:
${prefix}-${spring.profiles.active}.${file-extension}
prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
spring.profiles.active 即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 注意:当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 p r e f i x . {prefix}. prefix.{file-extension}
file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。
<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">
<parent>
<groupId>com.ishz.web</groupId>
<artifactId>springcloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.ishz.web</groupId>
<artifactId>gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gateway</name>
<description>
gateway网关模块
</description>
<dependencies>
<!-- SpringCloud Gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel Gateway -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<!-- Sentinel Datasource Nacos -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<!-- SpringBoot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- SpringCloud Loadbalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<!-- Apache Lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- Swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.fox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.fox.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- Java Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</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>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
# Tomcat
security:
ignore:
whites: /**/v2/api-docs,/**/v3/api-docs,/**/oauth/token,/**/tenant,/**/oauth/check_token
#server:
# port: 8080
# Spring
spring:
application:
# 应用名称
name: gateway
profiles:
# 环境配置
active: local
main:
allow-circular-references: true
allow-bean-definition-overriding: true
mvc:
pathmatch:
matching-strategy: ANT_PATH_MATCHER
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
enabled: true
# 配置中心地址
server-addr: localhost:8848
# prefix: ${spring.application.name}
# 配置文件格式
file-extension: yaml
# namespace: 8f6fc5c3-f6fd-43f4-ab3b-ca396ee9928f
# group: DEFAULT_GROUP
# 共享配置
# shared-configs:
# - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
sentinel:
# 取消控制台懒加载
eager: true
transport:
# 控制台地址
dashboard: 127.0.0.1:8718
# nacos配置持久化
datasource:
ds1:
nacos:
server-addr: 127.0.0.1:8848
dataId: sentinel-ruoyi-gateway
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow
gateway:
globalcors:
add-to-simple-url-handler-mapping: true
cors-configurations:
'[/**]':
allowedOriginPatterns: "*"
allowed-methods: "*"
allowed-headers: "*"
allow-credentials: true
exposedHeaders: "Content-Disposition,Content-Type,Cache-Control"
# default-filters:
# - DedupeResponseHeader=Access-Control-Allow-Origin Access-Control-Allow-Credentials Vary, RETAIN_UNIQUE
# routes:
# # 认证中心
# - id: service-authentication
# uri: lb://service-authentication
# predicates:
# - Path=/service-authentication/**
# filters:
# - StripPrefix=1
server:
port: 8080
spring:
cloud:
gateway:
routes:
# 认证中心
- id: service-authentication
uri: lb://service-authentication
predicates:
- Path=/service-authentication/**
filters:
- StripPrefix=1
- id: service-position-data
uri: lb://service-position-data
predicates:
- Path=/service-position-data/**
filters:
- StripPrefix=1
1.1seata-server下载地址
1.2 修改registry.conf
1.3 将配置导入nacos
1.3.1 创建并修改config.text
config.text下载地址
修改文件内容:
store.mode=db
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=root
将修改后的 config.text 放入seata-server的根目录
nacos-config.sh下载地址
将下载后的nacos-config.sh放入seata的conf目录
使用git执行导入命令: sh nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -t 0af6e97b-a684-4647-b696-7c6d42aecce7 -u nacos -w nacos
命令解析:-h -p 指定nacos的端口地址;-g 指定配置的分组,注意,是配置的分组;-t 指定命名空间id; -u -w指定nacos的用户名和密码,同样,这里开启了nacos注册和配置认证的才需要指定
1、pom.xml中新增
<!-- SpringBoot Seata -->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2021.1</version>
</dependency>
seata:
enabled: true
enable-auto-data-source-proxy: false
# application-id: vforumc-user
tx-service-group: default_tx_group
service:
vgroup-mapping:
default_tx_group: default
grouplist:
seata-server: 127.0.0.1:8091
disable-global-transaction: false
registry:
type: nacos
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
namespace: 790b7580-764e-42c9-84c8-40f5c7ea2aec
group: SEATA_GROUP
username: nacos
password: nacos
config:
nacos:
server-addr: 127.0.0.1:8848
namespace: 790b7580-764e-42c9-84c8-40f5c7ea2aec
group: SEATA_GROUP
username: nacos
password: nacos
3、启动类加注解@EnableAutoDataSourceProxy
4、在需要事务管理的方法上添加 @GlobalTransaction 注解 开启全局事务
5、全局异常拦截处理
在服务A调用服务B时,服务A抛异常可正常回滚;服务B抛异常时,无法进行回滚。解决方法是在服务B加上下面的方法
package com.ishz.web.common.exception;
import io.seata.core.context.RootContext;
import io.seata.core.exception.TransactionException;
import io.seata.tm.api.GlobalTransaction;
import io.seata.tm.api.GlobalTransactionContext;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* @author yaojiaxin
* @description 分布式事务feign全局异常处理,A服务调B服务接口时,
* B服务在有全局异常拦截的情况下抛错,seata不会进行回滚,此类用于解决此问题
* 官方解决方案:https://seata.io/zh-cn/blog/seata-spring-boot-aop-aspectj.html
* @date 2022/5/12 10:26
*/
@Aspect
@Component
public class SeataAspect {
private final static Logger logger = LoggerFactory.getLogger(SeataAspect.class);
@Before("execution(* com.ishz.web.*.service.*.*(..))")
public void before(JoinPoint joinPoint) throws TransactionException {
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Method method = signature.getMethod();
System.out.println("拦截到需要分布式事务的方法," + method.getName());
// 此处可用redis或者定时任务来获取一个key判断是否需要关闭分布式事务
// 模拟动态关闭分布式事务
// if ((int)(Math.random() * 100) % 2 == 0) {
GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();
tx.begin(300000, "test-client");
// } else {
// System.out.println("关闭分布式事务");
// }
}
@AfterThrowing(throwing = "e", pointcut = "execution(* com.ishz.web.*.service.*.*(..))")
public void doRecoveryActions(Throwable e) throws TransactionException {
System.out.println("方法执行异常:{}"+ e.getMessage());
if (!StringUtils.isBlank(RootContext.getXID()))
GlobalTransactionContext.reload(RootContext.getXID()).rollback();
}
// @AfterReturning(value = "execution(* com.ishz.web.*.service.*.*(..))", returning = "result")
// public void afterReturning(JoinPoint point, Object result) throws TransactionException {
//result返回值类型需要修改
// System.out.println("方法执行结束:{}"+result);
// if ((Boolean)result) {
// if (!StringUtils.isBlank(RootContext.getXID())) {
// System.out.println("分布式事务Id:{}"+ RootContext.getXID());
// GlobalTransactionContext.reload(RootContext.getXID()).commit();
// }
// }
// }
}