Spring Cloud Alibaba 基础(2.1.0.RELEASE)
pom.xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
Nacos
服务注册
服务端
# windows 下单例模式启动
# 默认 8848 端口启动
# 默认用户密码 nacos/nacos
startup.cmd -m standalone
客户端
pom.xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
application.yml
spring:
application:
name: user-demo
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
Nacos 数据模型
| 模型 | 描述 |
|---|---|
| namespace | 通常代表不同的开发环境。 |
| group | 通常代表某个项目。 |
| service | 通常代表某个项目中具体的微服务。 |
| dataId | 通常代表某个项目中具体的配置文件。 |
配置中心
pom.xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
配置文件需要修改为 bootstrap.yml
# data Id => user-demo.yaml
spring:
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
group: DEFAULT_GROUP
file-extension: yaml
一个服务如何锁定配置文件:prefix−{prefix}-prefix−{spring.profile.active}.${file-extension}
- prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix 来配置
- spring.profile.active 为当前环境对应的 profifile
- file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置
bootstrap.yml
# 将服务注册到自定义的命名空间中 配置文件只能读取同一命名空间下的内容
spring:
application:
name: user-demo
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: 70839889-3879-496f-918c-515ed99a8750
config:
server-addr: 127.0.0.1:8848
group: DEFAULT_GROUP
file-extension: yaml
namespace: 70839889-3879-496f-918c-515ed99a8750
一个项目如何如何锁定多个配置文件
bootstrap.yml
spring:
cloud:
nacos:
config:
# 多个配置文件的配置
ext-config[0]:
# 多个配置文件的 id
data-id: user-demo-custom.yaml
group: DEFAULT_GROUP
# 开启自定义配置文件自动刷新功能
refresh: true
优先级:根据规则⽣成的 dataId > 扩展的dataId。对于扩展的 dataId,[n] 越⼤优先级越⾼。
自动刷新配置:@RefreshScope
Nacos 基于 MySQL 实现持久化
Nacos 默认使用嵌入式数据库进行数据存储。它支持改为外部 MySQL 存储。
- 新建数据库 nacos_confifig,数据库初始化脚本文件:${nacoshome}/conf/nacos-mysql.sql
- 修改 ${nacoshome}/conf/application.properties,增加Mysql数据源配置
#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=123456
Dubbo
pom.xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
bootstrap.yml
spring:
# main:
# allow-bean-definition-overriding: true
dubbo:
scan:
# dubbo 扫描 @Service 注解
base-packages: com.demo.service
registry:
# dubbo 服务注册到 nacos 上
address: nacos://127.0.0.1:8848
服务提供方
import org.apache.dubbo.config.annotation.Service;
@Service
public class UserService implements UserApi {}
服务消费方
import org.apache.dubbo.config.annotation.Reference;
@Reference
private UserApi userApi;
Sentinel
服务端
# 默认 8080 端口启动
# 默认用户密码 sentinel/sentinel
java -jar sentinel-dashboard-1.7.1.jar &
客户端
bootstrap.yml
spring:
cloud:
sentinel:
transport:
# sentinel 的地址
dashboard: 127.0.0.1:8080
流控
| 规则名 | 描述 |
|---|---|
| 资源名 | 默认请求路径 |
| 针对来源 | Sentinel 可以针对调⽤者进⾏限流,填写微服务名称,默认default(不区分来源) |
| 阈值类型/单机阈值 | QPS:每秒钟请求数量; 线程数:调⽤该资源的线程数(某个线程请求的时间过长会一直占用资源) |
| 流控模式 | 直接:达到限流条件,直接限流; 关联:关联的资源调用达到限流条件,限流自己; 链路:只记录指定链路上的流量 |
| 流控效果 | 快速失败:直接失败,抛出异常; Warm Up:经过预热时长慢慢达到设置的 QPS 值 排队等待:让请求匀速通过,阈值类型需要设置为 QPS |
降级
| 规则名 | 描述 |
|---|---|
| 资源名 | 默认请求路径 |
| 降级策略 | RT:平均响应时间 异常比例 异常数 |
| 时间窗口 | 时间窗⼝内拒绝请求,时间窗⼝后就恢复 |
自定义降级后兜底方法
@SentinelResource
- value:定义资源名
- blockHandlerClass:指定 Sentinel 规则异常兜底逻辑所在 class 类
- blockHandler:指定 Sentinel 规则异常兜底逻辑具体哪个⽅法
- fallbackClass:指定 Java 运⾏时异常兜底逻辑所在 class 类
- fallback:指定 Java 运⾏时异常兜底逻辑具体哪个⽅法
public class SentinelFallbackClass {
public static User handleException(BlockException blockException) {
User user = new User();
user.setName("兜底数据");
System.out.println(blockException.getRule());
return user;
}
public static User handleError() {
User user = new User();
user.setName("异常数据");
return user;
}
}
注意:
- @SentinelResource 的 value 值不要和 @GetMapping 的 value 值一样,否则识别不到兜底方法
- 配置 sentine l的流控或者降级的资源名应和 @SentinelResource 的 value 值一样
- 不配置降级规则,可以单独使用 blockHandler
@RequestMapping("/find")
@SentinelResource(value = "findUser",
fallbackClass = SentinelFallbackClass.class, fallback = "handleError",
blockHandlerClass = SentinelFallbackClass.class, blockHandler = "handleException")
public User findUser() {
int i = 1 / 0;
return userApi.findUser();
}
Sentinel 基于 Nacos 实现持久化
pom.xml
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
bootstrap.yml
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080
datasource:
# 流控
flow:
nacos:
server-addr: 127.0.0.1:8848
data-id: user-demo-flow-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow # 类型来自RuleType类
# 降级
degrade:
nacos:
server-addr: 127.0.0.1:8848
data-id: user-demo-degrade-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: degrade # 类型来自RuleType类
注意:第一次请求没有。请求之后才会从 Nacos 自动配置到 Sentinel。
Seata
服务端环境搭建
- 修改 registry.conf 注册到 nacos
registry {
type = "nacos"
nacos {
application = "seata-server"
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = ""
cluster = "default"
username = "nacos"
password = "nacos"
}
}
config {
type = "nacos"
nacos {
serverAddr = "127.0.0.1:8848"
namespace = ""
group = "SEATA_GROUP"
username = "nacos"
password = "nacos"
}
}
- 向 nacos 中添加配置信息
- 获取 config.txt 文件。放到 bin 文件夹同级目录。
- config.txt 地址:https://github.com/seata/seata/tree/develop/script/config-center
- config.txt 中的配置项:https://seata.io/zh-cn/docs/user/configurations.html
- 修改 config.txt。用 db 方式存储全局事务会话信息。
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.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
- 创建 seata 库。global_table、branch_table、lock_table 表。
建表语句地址:https://github.com/seata/seata/tree/develop/script/server/db
- 使用 nacos-config.sh 向 Nacos 中添加配置
nacos-config.sh 地址:https://github.com/seata/seata/tree/develop/script/config-center/nacos
- seata-server.bat 启动。默认端口 8091。
客户端
pom.xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.4.2</version>
</dependency>
AT 模式
- 建立 undo_log 表。
CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
- 在需要使用 seata 的项目中复制 registry.conf 到 resources。
- 添加配置
spring:
cloud:
alibaba:
seata:
# nacos 中: service.vgroupMapping.default_tx_group
# service.default.grouplist:127.0.0.1:8091
tx-service-group: default_tx_group
- 数据源代理
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DruidDataSource druidDataSource() {
return new DruidDataSource();
}
// 需要将 DataSourceProxy 设置为主数据源,否则事务无法回滚
@Primary
@Bean("dataSource")
public DataSource dataSource(DruidDataSource druidDataSource) {
return new DataSourceProxy(druidDataSource);
}
}
- 在需要添加事务的方法上添加注解
@GlobalTransactional(name = "addGift", timeoutMills = 100000, rollbackFor = Exception.class)
TCC 模式
TCC 模式需要三个方法:
- Try:资源的检测和预留
- Confirm:执行的业务操作提交;要求 Try 成功 Confirm ⼀定要能成功;
- Cancel:预留资源释放。
// @LocalTCC 注解开启 TCC 模式
@LocalTCC
public interface GiftApi {
// Try 方法
@TwoPhaseBusinessAction(name = "addGift", commitMethod = "addCommit", rollbackMethod = "addRollBack")
void addGift(@BusinessActionContextParameter(paramName = "cardNo") String cardNo,
@BusinessActionContextParameter(paramName = "giftNum") Integer giftNum);
// Confirm 方法,返回值为 true
boolean addCommit(BusinessActionContext context);
// Cancel 方法,返回值为 true
boolean addRollBack(BusinessActionContext context);
}
参考git:https://gitee.com/zhangyizhou/learning-spring-cloud-alibaba-demo.git
本文详述了如何在SpringCloudAlibaba项目中集成Nacos进行服务注册与配置管理,Sentinel实现流量控制与服务降级,以及Seata进行分布式事务管理。涉及Nacos的配置、服务端与客户端的启动,Sentinel规则设定,Seata服务端配置及客户端数据源代理等关键步骤。
520

被折叠的 条评论
为什么被折叠?



