== Spring Cloud Alibaba 2021.0.1.0 升级指南

=== 版本号

从 2021.0.1.0 开始，SCA 版本将会对应 Spring Cloud 版本，
前三位为 Spring Cloud 版本，最后一位为扩展版本

=== 升级步骤

升级版本 (注意版本对应关系)
```xml
<dependencyManagement>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>2.6.3</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>2021.0.1</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
        <version>2021.0.1.0</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
</dependencyManagement>
```

*注意事项：* `spring-cloud-starter-alibaba-nacos-config` 模块移除了 `spring-cloud-starter-bootstrap` 依赖，如果你想以旧版的方式使用，你需要手动加上该依赖，现在推荐使用 `spring.config.import` 方式引入配置

完成以上步骤就能无缝切换到 `spring cloud alibaba 2021.0.1.0` 版本

=== 新特性及其使用

==== 支持 spring.config.import

这里假设有一个配置文件(`bootstrap.yml`)，升级到新版本应该怎么配置呢
```yaml
# bootstrap.yml
spring:
  cloud:
    nacos:
      config:
        name: test.yml
        group: DEFAULT_GROUP
        server-addr: 127.0.0.1:8848
        extension-configs:
          - dataId: test01.yml
            group: group_01
          - dataId: test02.yml
            group: group_02
            refresh: false
```

这两个配置是等价的

```yaml
# application.yml
spring:
  cloud:
    nacos:
      config:
        group: DEFAULT_GROUP
        server-addr: 127.0.0.1:8848
  config:
    import:
      - optional:nacos:test.yml  # 监听 DEFAULT_GROUP:test.yml
      - optional:nacos:test01.yml?group=group_01 # 覆盖默认 group，监听 group_01:test01.yml
      - optional:nacos:test02.yml?group=group_02&refreshEnabled=false # 不开启动态刷新
      - nacos:test03.yml # 在拉取nacos配置异常时会快速失败，会导致 spring 容器启动失败
```
注意事项:

- 如果使用 `spring.config.import` 就不能使用 bootstrap.yml/properties 引入配置的方式了 !!!

- 如果引入了 `spring-cloud-starter-alibaba-nacos-config`，并且使用 import 方式导入配置,
项目启动时会自动检测是否引入了 `nacos:` 条目，如果没有 import nacos 条目，会出现如下错误：

----
The spring.config.import property is missing a nacos: entry

Action:

Add a spring.config.import=nacos: property to your configuration.
	If configuration is not required add spring.config.import=optional:nacos: instead.
	To disable this check, set spring.cloud.nacos.config.import-check.enabled=false.
----

你可以手动通设置 `spring.cloud.nacos.config.import-check.enabled=false` 关闭它，但是不建议这么做，这个功能可以帮助你检查是否引入多余依赖

- 假如想保留以前的使用方式 (bootstrap引入配置)，你只需要添加依赖 `spring-cloud-starter-bootstrap` 依赖，不需要修改一行代码

你可以前往 https://github.com/alibaba/spring-cloud-alibaba/tree/2021.x/spring-cloud-alibaba-examples/nacos-example/nacos-config-example[这里] 查看具体example

==== Nacos 容错能力

新增配置项 `spring.cloud.nacos.discovery.failure-tolerance-enabled`，
设置为 true (默认 false) 开启 nacos 服务发现失败容错能力，该功能会在 nacos 获取实例失败时返回上一次获取的实例，可以在 nacos server 网络不稳定时提供容错能力，不会导致请求全部挂掉

==== 支持 feign 灵活的熔断配置

当 Sentinel 作为 Spring Cloud 断路器实现时，支持为每个 FeignClient 添加断路器配置

添加依赖
```xml
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-circuitbreaker-sentinel</artifactId>
</dependency>
```

这里有两个 FeignClient
```java
@FeignClient(value = "user", fallback = UserFallback.class)
public interface UserClient {
    @GetMapping("/{success}")
    String success(@PathVariable Boolean success);
}
@FeignClient(value = "order", fallback = OrderFallback.class)
public interface OrderClient {
    @GetMapping("/{success}")
    String success(@PathVariable Boolean success);

    @GetMapping("/{success}")
    String error(@PathVariable Boolean success);
}
```

现在有这些需求:

1. 我想要对全局的 FeignClient 配置一个默认熔断规则
2. 我想要对 user FeignClient 配置熔断规则
3. 我想要对 order FeignClient 的指定方法(error)配置熔断规则

添加以下配置
```yaml
feign:
   circuitbreaker:
      enabled: true
   sentinel:
      default-rule: default # 全局规则名称
      rules:
         # 全局配置，这些参数的意思请查看 com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule
         # 可配置多条规则
         default:
            - grade: 2
              count: 1
              timeWindow: 1
              statIntervalMs: 1000
              minRequestAmount: 5
            - grade: 2
              count: 1
         # 针对 user FeignClient
         user:
            - grade: 2
              count: 1
              timeWindow: 1
              statIntervalMs: 1000
              minRequestAmount: 5
         # 针对 order FeignClient error 方法，注意中括号，不然会解析出来的值会不一致
         "[order#error(Boolean)]":
            - grade: 2
              count: 1
              timeWindow: 1
              statIntervalMs: 1000
              minRequestAmount: 5
```

该功能还支持从配置中心动态刷新，可以将上述配置放入配置中心(nacos，consul)，修改规则会立刻生效，如果不需要该功能可以通过 `feign.sentinel.enable-refresh-rules=false` 来禁用它

*注意事项：* 如果你使用的是 `spring-cloud-starter-alibaba-sentinel`，请**不要**配置 `feign.sentinel.enable=true`，会使配置失效

你可以前往 https://github.com/alibaba/spring-cloud-alibaba/tree/2021.x/spring-cloud-alibaba-examples/sentinel-example/sentinel-circuitbreaker-example[这里] 查看具体 example

=== 对升级的一点建议
1. 在 spring boot 2.6 之后默认开启了禁止循环引入，建议大家不要关闭，这是一种不好的编码习惯，如果你的项目里出现了循环引用，请选择重构它
2. 抛弃 bootstrap 引入配置的方式，使用 `spring.config.import` 方式引入配置，spring boot 2.4 对这一块做了很大的优化工作，不再需要全量启动一个容器来刷新配置

