== Spring Cloud Alibaba 2021.0.1.0 Upgrade Guide

=== Version Number

Starting from 2021.0.1.0, the SCA version will correspond to the Spring Cloud version, the first three are the Spring Cloud version, and the last one is the extended version.

=== Upgrade Steps

Upgrade version (note the version correspondence)
```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>
```

*Note:* The `spring-cloud-starter-alibaba-nacos-config` module removes the `spring-cloud-starter-bootstrap` dependency. If you want to use with the bootstrap way, you need to manually add this dependency, now recommended to import configuration using `spring.config.import`.

After completing the above steps, you can smoothly switch to the `Spring Cloud Alibaba 2021.0.1.0` version.

=== New Features and Usage

==== Support `spring.config.import`

Suppose there is a configuration file (`bootstrap.yml`) here, how should it be configured to upgrade to a new version?

```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
```

The two configurations are equivalent.

```yaml
# application.yml
spring:
  cloud:
    nacos:
      config:
        group: DEFAULT_GROUP
        server-addr: 127.0.0.1:8848
  config:
    import:
      - optional:nacos:test.yml  # Listening DEFAULT_GROUP:test.yml
      - optional:nacos:test01.yml?group=group_01 # Override default group，listening group_01:test01.yml
      - optional:nacos:test02.yml?group=group_02&refreshEnabled=false # Do not enable dynamic refresh
      - nacos:test03.yml # When the nacos configuration is pulled abnormally, it will fail quickly, which will cause the Spring container to fail to start.
```

Note:

- If you use `spring.config.import`, you can't use bootstrap.yml/properties.

- If `spring-cloud-starter-alibaba-nacos-config` is using and the configuration is imported using the `spring.config.import` way, the project will automatically detect whether the `nacos:` entry has been imported. If there is no import nacos entry, the following error will occur:

----
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.
----

You can manually turn it off by setting `spring.cloud.nacos.config.import-check.enabled=false`, but it is not recommended to do so, this function can help you check whether to introduce unnecessary dependencies.

- If you want to keep the previous usage (bootstrap way), you only need to add the dependency `spring-cloud-starter-bootstrap` dependency and don't need modifying a line of code.

you can go https://github.com/alibaba/spring-cloud-alibaba/tree/2021.x/spring-cloud-alibaba-examples/nacos-example/nacos-config-example[here] to see the complete example.

==== Nacos Failure Tolerance

Add new configuration item `spring.cloud.nacos.discovery.failure-tolerance-enabled`. Set to true (default false) to enable acos service discovery failure fault tolerance. This feature will return the last instance obtained when nacos fails to get instances. It can provide fault tolerance when the nacos server network is unstable, and will not cause all requests to hang up.

==== Support Feign Circuit Breaker Configuration

When Sentinel is implemented as a Spring Cloud circuit breaker, support for adding circuit breaker configuration for each FeignClient.

Add dependency.
```xml
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-circuitbreaker-sentinel</artifactId>
</dependency>
```

And here are two 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);
}
```

Now there are these requirements:

1. I want to configure a default circuit breaker for the global FeignClient.
2. I want to configure a circuit breaker rule for user FeignClient.
3. I want to configure a circuit breaker for the specified method (error) of order FeignClient.

Add the following configuration.
```yaml
feign:
   circuitbreaker:
      enabled: true
   sentinel:
      default-rule: default # global rule name
      rules:
         # global configuration, the meaning of these parameters, please see com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule
         # you can configure multiple rules
         default:
            - grade: 2
              count: 1
              timeWindow: 1
              statIntervalMs: 1000
              minRequestAmount: 5
            - grade: 2
              count: 1
         # for user FeignClient
         user:
            - grade: 2
              count: 1
              timeWindow: 1
              statIntervalMs: 1000
              minRequestAmount: 5
         # for order FeignClient 'error' method，note the square brackets, otherwise the parsed value will be inconsistent.
         "[order#error(Boolean)]":
            - grade: 2
              count: 1
              timeWindow: 1
              statIntervalMs: 1000
              minRequestAmount: 5
```

This feature also supports dynamic refresh from the configuration center. You can put the above configuration into the configuration center (nacos, consul), and the modified rules will take effect immediately. If you do not need this feature, you can set `feign.sentinel.enable-refresh-rules=false` to disable it.

*Note:* If you are using `spring-cloud-starter-alibaba-sentinel`, please *DO NOT* configure `feign.sentinel.enable=true`, it will invalidate the configuration.

You can go https://github.com/alibaba/spring-cloud-alibaba/tree/2021.x/spring-cloud-alibaba-examples/sentinel-example/sentinel-circuitbreaker-example[here] to see the complete example.

=== Little Advice For Upgrading
1. After Spring Boot 2.6, the prohibition of circular reference is enabled by default. It is recommended that you do not change it. This is a bad coding practice. If there is a circular reference in your project, please choose to refactor it.
2. Abandoning the way of importing configuration from the bootstrap way and using `spring.config.import` to import configuration, Spring Boot 2.4 has done a lot of optimization work on this, and it is no longer necessary to start a full container to refresh the environment.

