Spring Cloud Alibaba 基础(2.1.0.RELEASE)

本文详述了如何在SpringCloudAlibaba项目中集成Nacos进行服务注册与配置管理,Sentinel实现流量控制与服务降级,以及Seata进行分布式事务管理。涉及Nacos的配置、服务端与客户端的启动,Sentinel规则设定,Seata服务端配置及客户端数据源代理等关键步骤。

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

服务端环境搭建

  1. 修改 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"
	}    
}
  1. 向 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
  1. 创建 seata 库。global_table、branch_table、lock_table 表。

建表语句地址:https://github.com/seata/seata/tree/develop/script/server/db

  1. 使用 nacos-config.sh 向 Nacos 中添加配置

nacos-config.sh 地址:https://github.com/seata/seata/tree/develop/script/config-center/nacos

  1. 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 模式
  1. 建立 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;
  1. 在需要使用 seata 的项目中复制 registry.conf 到 resources。
  2. 添加配置
spring:
  cloud:
    alibaba:
      seata:
        # nacos 中: service.vgroupMapping.default_tx_group
        # service.default.grouplist:127.0.0.1:8091
        tx-service-group: default_tx_group
  1. 数据源代理
@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);
    }
}
  1. 在需要添加事务的方法上添加注解
@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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值