第三章-Nacos配置中心
# 第三章 Nacos 配置中心
微服务的配置文件:
- 不同的微服务可能共享配置文件,只有部分的内容不同
- 同一个微服务集群的配置文件是相同的。
这个时候,对配置文件的更新维护就是一个麻烦的问题,并且某些业务的配置在配置文件中写死了,每次修改配置文件都要重启微服务。
**配置中心**可以解决这些问题,将**同一个集群的相同配置文件**都交给配置中心统一管理,将**不同集群的共享配置文件**也交给配置中心统一管理。
配置中心的产品有很多:Spring Cloud Config、Zookeeper、Apollo、Disconf等。Spring Cloud Alibaba推荐使用Nacos作为微服务的配置中心。
## 配置中心产品
### Spring Cloud Config

我们更新配置文件后,需要手动向Config Client提交POST请求更新配置文件,Config Client通过Config Server从远程库拉取配置文件。
假设向微服务集群a提交POST请求,会分为两步:
1. Config Client a 通过Config Server从远程库拉取配置文件更新到本地。
2. Config Client a 将请求封装,通过消息总线系统告知Config Client b 和 Config Client c,重复上步操作。
存在的问题:
1. Config Client无法主动感知更新
2. 如果只想修改Config Client a的配置文件,会导致注册在消息总线系统上的服务都更新配置文件,羊群效应,影响系统
3. 架构过于复杂,GitLab是集群,Config Server是集群,Config Server 和 Config Client 之间需要 Nginx 反向代理负载均衡,Nginx也是个集群,MQ也是集群。
### Nacos

前提:必须使用外置数据库MySQL
我们更新配置文件后,更新自动推送到**对应的Config Client中**,没有羊群效应。
架构比Apollo简单,支持的类型比Apollo多,可以实时更新。

配置文件交给Nacos保存和管理,在Nacos控制台修改配置后,Nacos自动将配置推送给相关的微服务,无需重启即可生效。
## 一致性问题
配置中心的配置数据一般都是持久化在第三方服务器的,例如MySQL或GitLab。这些配置中心server中没有数据,不存在数据一致性问题
但像zookeeper,作为配置中心时数据是存在zookeeper服务器中的,所以zookeeper集群是存在数据一致性问题的,zookeeper采用的是CP模式,保证了一致性牺牲可用性。
## 当前服务配置文件
微服务会自动拉取和自身相关的配置文件,也就是每个微服务集群独有的配置文件。
在nacos控制台创建**同一个微服务集群使用的相同配置**文件:

注意:
- data id 为 depart-provider.yml
- file-extension 为 yaml/yml
发布之后修改本地的application.yml文件:
```yml
spring:
# 微服务名称
application:
name: depart-provider
```
参照[官网](https://nacos.io/docs/v2/ecology/use-nacos-with-spring-cloud/) - [生态融合-配置中心](https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config)引入依赖:
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
```
### 2021.x之后版本
application.yml:
```yml
#application.yml
spring:
# 微服务名称
application:
name: depart-provider
cloud:
nacos:
#拉取共享配置
config:
server-addr: localhost:8848
# 指定文件格式为yaml
file-extension: yaml
```
> 官网上说明默认的文件格式是properties,需要指定为yaml或yml
在老版本的Spring Cloud中,这样配置就可以了,会自动在nacos中寻找名称为:
**`${spring.application.name}.${spring.cloud.nacos.config.file-extension}` 的文件拉取**,所以不指定file-extension默认拉取的是...properties文件。
但是新版本直接启动会报错:
```sh
***************************
APPLICATION FAILED TO START
***************************
Description:
No spring.config.import property has been defined
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.
```
需要添加一个配置:
```yml
spring:
# 微服务名称
application:
name: depart-provider
cloud:
nacos:
#拉取共享配置
config:
server-addr: localhost:8848
file-extension: yml
username: nacos
password: nacos
config:
import:
- optional:nacos:depart-provider.yml
```
需要指定加载的配置文件名称:depart-provider.yml
此处也可以使用动态配置:
```yml
spring:
# 微服务名称
application:
name: depart-provider
cloud:
nacos:
#拉取共享配置
config:
server-addr: localhost:8848
file-extension: yml
username: nacos
password: nacos
config:
import:
#- optional:nacos:depart-provider.yml
- optional:nacos:${spring.application.name}.${spring.cloud.nacos.config.file-extension}
```
注意:这种方式必须将file-extension配置为yml。
### 2021.x及之前版本
使用Nacos Config拉取配置文件替代本地配置,在[官网](https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config)中说明:
**必须使用 bootstrap.properties 配置文件来配置Nacos Server 地址**,例如:
bootstrap.properties
```ini
spring.application.name=nacos-config
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
```
这个配置对于2021.x及其之前版本有效,2021.x之后版本读取的就是application.yml,不需要配置bootstrap.yml。
- Spring Boot启动流程:

- Spring Cloud启动流程:

我们想拉取Nacos的配置文件并和本地的application.yml合并完成上下文初始化,但是读取Nacos配置是Spring Cloud上下文初始化时完成的,然后才会初始化Spring Boot上下文(读取application.yml文件)。
**在Spring Cloud初始化时,未读取application.yml文件,不知道nacos的地址,如何从配置中心加载文件?**
Spring Cloud上下文初始化时会先加载bootstrap.yml文件,将nacos的地址配置在bootstrap.yml文件中在初始化Spring Cloud时就知道nacos的地址了。

因此,2021.x整合nacos配置的步骤如下:
pom:
```xml
<!--nacos配置管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--读取bootstrap文件-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
```
bootstrap.yml:
```yml
spring:
application:
name: depart-provider
cloud:
naocs:
server-addr: localhost:8848
config:
file-extension: yml
```
此时就会自动在nacos中寻找名称为 `${spring.application.name}.${spring.cloud.nacos.config.file-extension}`的文件拉取。
## 共享配置文件
上例实现的是同一个微服务集群拉取相同的配置文件,拉取的文件名称是默认的
`${spring.application.name}.${spring.cloud.nacos.config.file-extension}`
我们也**可以指定拉取某一个配置**,这样就能实现:**多个微服务集群之间共享配置**
通过shared-config指定要拉取的配置文件:
```yml
spring:
# 微服务名称
application:
name: depart-provider
cloud:
nacos:
#拉取共享配置
config:
server-addr: localhost:8848
file-extension: yml
username: nacos
password: nacos
shared-configs:
- data-id: shared-template.yml
refresh: true
config:
import:
#- optional:nacos:depart-provider.yml
- optional:nacos:shared-template.yml
- optional:nacos:${spring.application.name}.${spring.cloud.nacos.config.file-extension}
```
shared-config配置项会加载指定共享的配置,refresh指定对该配置文件热更新。
## 扩展配置文件
在某些版本的Spring Cloud中,shared-config拉取的配置文件只能是和当前微服务处于同一个三元组中的,如果要拉取其他三元组的配置文件需要使用extension-config:
```yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/rc2?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=true
password: root
username: root
driver-class-name: com.mysql.cj.jdbc.Driver
# 微服务名称
application:
name: depart-provider
#nacos注册中心地址
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
username: nacos
password: nacos
config:
server-addr: 127.0.0.1:8848
username: nacos
password: nacos
file-extension: yml
# 共享配置
shared-configs:
- data-id: shared-template.yml
refresh: true
# 扩展配置
extension-configs:
- data-id: extension-template.yml
```
## 配置文件优先级
微服务会加载三类配置文件:自己的配置文件,shared-config共享配置文件,extension-config扩展配置文件
如果这三类配置文件中设置了同一个属性,例如:server.port,但是这三类配置文件的值都不相同,最终的值是哪个?
当前服务配置、共享配置、扩展配置加载顺序是:
- 共享配置
- 扩展配置
- 当前服务配置
**后加载的会覆盖之前加载的内容**。
优先级由高到低是:
- 当前服务配置
- 扩展配置
- 共享配置
并且如果Nacos和本地有相同的配置,会以Nacos的配置为主。
当前服务配置 > 扩展配置 > 共享配置 > 本地配置
## 配置动态更新
在nacos中添加一个配置:

### @ConfirguationProperties读取数据
```java
@Data
//@RefreshScope 2021.x不需要添加
@ConfigurationProperties(prefix = "depart")
public class DepartProperties {
private String name;
}
```
```java
@RestController
@RequestMapping("/provider/depart")
@EnableConfigurationProperties(DepartProperties.class)
public class DepartController {
@Resource
private DepartService departService;
@Value("${server.port}")
private String port;
@Autowired
private DepartProperties departProperties;
@GetMapping("/{id}")
public ResponseResult<Depart> getHandler(@PathVariable Long id){
Depart depart = departService.getById(id);
depart.setName(depart.getName() + " this provider port:" + port + " this depart name:" + departProperties.getName());
return ResponseResult.success(depart);
}
}
```
在nacos控制台修改了共享配置后,此处自动会更新,2021.x版本不需要添加@RefreshScope
### @Value读取数据
如果使用@Value读取数据:
```java
//provider#DepartController
@Value("${server.port}")
private String port;
@Value("${depart.name}")
private String departName;
@GetMapping("/{id}")
public ResponseResult<Depart> getHandler(@PathVariable Long id){
Depart depart = departService.getById(id);
depart.setName(depart.getName() + " this provider port:" + port + " this depart name:" + departName);
return ResponseResult.success(depart);
}
```
第一次访问得到的是销售部,将nacos中的配置文件更换为行政部,再次访问,得到的还是销售部。
**使用@Value读取的配置文件数据需要在类上标注@RefreshScope才能动态刷新**
```java
@RestController
@RefreshScope
@RequestMapping("/provider/depart")
public class DepartController {
@Resource
private DepartService departService;
@Value("${server.port}")
private String port;
@Value("${depart.name}")
private String departName;
@GetMapping("/{id}")
public ResponseResult<Depart> getHandler(@PathVariable Long id){
Depart depart = departService.getById(id);
depart.setName(depart.getName() + " this provider port:" + port + " this depart name:" + departName);
return ResponseResult.success(depart);
}
}
```
## 多环境选择
dev、local、test
前文中说明了微服务会自动拉取当前服务的配置文件:`${spring.application.name}.${spring.cloud.nacos.config.file-extension}`
如果要区分不同的环境,在nacos中配置文件的命名是:
`${spring.application.name}-${spring.profiles.activity}.${spring.cloud.nacos.config.file-extension}`
例如:
- depart-provider-dev.yml
- depart-provider-test.yml
在application.yml/bootstrap.yml中指定要激活的环境:
```yml
spring:
# 微服务名称
application:
name: depart-provider
cloud:
nacos:
#拉取共享配置
config:
server-addr: localhost:8848
file-extension: yml
username: nacos
password: nacos
shared-configs:
- data-id: shared-template.yml
refresh: true
extension-configs:
- data-id: extension-config.yml
config:
import:
#- optional:nacos:depart-provider.yml
- optional:nacos:shared-template.yml
- optional:nacos:${spring.application.name}-${spring.profiles.active}
.${spring.cloud.nacos.config.file-extension}
profiles:
active: dev
```
此时就会去nacos中拉取depart-provider-dev.yml的配置文件。
在开发时,如果要修改环境配置,不必修改这个配置文件,直接修改edit-config的active profiles即可
## 配置隔离
微服务的配置文件:
- 不同的微服务可能共享配置文件,只有部分的内容不同
- 同一个微服务集群的配置文件是相同的。
这个时候,对配置文件的更新维护就是一个麻烦的问题,并且某些业务的配置在配置文件中写死了,每次修改配置文件都要重启微服务。
**配置中心**可以解决这些问题,将**同一个集群的相同配置文件**都交给配置中心统一管理,将**不同集群的共享配置文件**也交给配置中心统一管理。
配置中心的产品有很多:Spring Cloud Config、Zookeeper、Apollo、Disconf等。Spring Cloud Alibaba推荐使用Nacos作为微服务的配置中心。
## 配置中心产品
### Spring Cloud Config

我们更新配置文件后,需要手动向Config Client提交POST请求更新配置文件,Config Client通过Config Server从远程库拉取配置文件。
假设向微服务集群a提交POST请求,会分为两步:
1. Config Client a 通过Config Server从远程库拉取配置文件更新到本地。
2. Config Client a 将请求封装,通过消息总线系统告知Config Client b 和 Config Client c,重复上步操作。
存在的问题:
1. Config Client无法主动感知更新
2. 如果只想修改Config Client a的配置文件,会导致注册在消息总线系统上的服务都更新配置文件,羊群效应,影响系统
3. 架构过于复杂,GitLab是集群,Config Server是集群,Config Server 和 Config Client 之间需要 Nginx 反向代理负载均衡,Nginx也是个集群,MQ也是集群。
### Nacos

前提:必须使用外置数据库MySQL
我们更新配置文件后,更新自动推送到**对应的Config Client中**,没有羊群效应。
架构比Apollo简单,支持的类型比Apollo多,可以实时更新。

配置文件交给Nacos保存和管理,在Nacos控制台修改配置后,Nacos自动将配置推送给相关的微服务,无需重启即可生效。
## 一致性问题
配置中心的配置数据一般都是持久化在第三方服务器的,例如MySQL或GitLab。这些配置中心server中没有数据,不存在数据一致性问题
但像zookeeper,作为配置中心时数据是存在zookeeper服务器中的,所以zookeeper集群是存在数据一致性问题的,zookeeper采用的是CP模式,保证了一致性牺牲可用性。
## 当前服务配置文件
微服务会自动拉取和自身相关的配置文件,也就是每个微服务集群独有的配置文件。
在nacos控制台创建**同一个微服务集群使用的相同配置**文件:

注意:
- data id 为 depart-provider.yml
- file-extension 为 yaml/yml
发布之后修改本地的application.yml文件:
```yml
spring:
# 微服务名称
application:
name: depart-provider
```
参照[官网](https://nacos.io/docs/v2/ecology/use-nacos-with-spring-cloud/) - [生态融合-配置中心](https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config)引入依赖:
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
```
### 2021.x之后版本
application.yml:
```yml
#application.yml
spring:
# 微服务名称
application:
name: depart-provider
cloud:
nacos:
#拉取共享配置
config:
server-addr: localhost:8848
# 指定文件格式为yaml
file-extension: yaml
```
> 官网上说明默认的文件格式是properties,需要指定为yaml或yml
在老版本的Spring Cloud中,这样配置就可以了,会自动在nacos中寻找名称为:
**`${spring.application.name}.${spring.cloud.nacos.config.file-extension}` 的文件拉取**,所以不指定file-extension默认拉取的是...properties文件。
但是新版本直接启动会报错:
```sh
***************************
APPLICATION FAILED TO START
***************************
Description:
No spring.config.import property has been defined
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.
```
需要添加一个配置:
```yml
spring:
# 微服务名称
application:
name: depart-provider
cloud:
nacos:
#拉取共享配置
config:
server-addr: localhost:8848
file-extension: yml
username: nacos
password: nacos
config:
import:
- optional:nacos:depart-provider.yml
```
需要指定加载的配置文件名称:depart-provider.yml
此处也可以使用动态配置:
```yml
spring:
# 微服务名称
application:
name: depart-provider
cloud:
nacos:
#拉取共享配置
config:
server-addr: localhost:8848
file-extension: yml
username: nacos
password: nacos
config:
import:
#- optional:nacos:depart-provider.yml
- optional:nacos:${spring.application.name}.${spring.cloud.nacos.config.file-extension}
```
注意:这种方式必须将file-extension配置为yml。
### 2021.x及之前版本
使用Nacos Config拉取配置文件替代本地配置,在[官网](https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config)中说明:
**必须使用 bootstrap.properties 配置文件来配置Nacos Server 地址**,例如:
bootstrap.properties
```ini
spring.application.name=nacos-config
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
```
这个配置对于2021.x及其之前版本有效,2021.x之后版本读取的就是application.yml,不需要配置bootstrap.yml。
- Spring Boot启动流程:

- Spring Cloud启动流程:

我们想拉取Nacos的配置文件并和本地的application.yml合并完成上下文初始化,但是读取Nacos配置是Spring Cloud上下文初始化时完成的,然后才会初始化Spring Boot上下文(读取application.yml文件)。
**在Spring Cloud初始化时,未读取application.yml文件,不知道nacos的地址,如何从配置中心加载文件?**
Spring Cloud上下文初始化时会先加载bootstrap.yml文件,将nacos的地址配置在bootstrap.yml文件中在初始化Spring Cloud时就知道nacos的地址了。

因此,2021.x整合nacos配置的步骤如下:
pom:
```xml
<!--nacos配置管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--读取bootstrap文件-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
```
bootstrap.yml:
```yml
spring:
application:
name: depart-provider
cloud:
naocs:
server-addr: localhost:8848
config:
file-extension: yml
```
此时就会自动在nacos中寻找名称为 `${spring.application.name}.${spring.cloud.nacos.config.file-extension}`的文件拉取。
## 共享配置文件
上例实现的是同一个微服务集群拉取相同的配置文件,拉取的文件名称是默认的
`${spring.application.name}.${spring.cloud.nacos.config.file-extension}`
我们也**可以指定拉取某一个配置**,这样就能实现:**多个微服务集群之间共享配置**
通过shared-config指定要拉取的配置文件:
```yml
spring:
# 微服务名称
application:
name: depart-provider
cloud:
nacos:
#拉取共享配置
config:
server-addr: localhost:8848
file-extension: yml
username: nacos
password: nacos
shared-configs:
- data-id: shared-template.yml
refresh: true
config:
import:
#- optional:nacos:depart-provider.yml
- optional:nacos:shared-template.yml
- optional:nacos:${spring.application.name}.${spring.cloud.nacos.config.file-extension}
```
shared-config配置项会加载指定共享的配置,refresh指定对该配置文件热更新。
## 扩展配置文件
在某些版本的Spring Cloud中,shared-config拉取的配置文件只能是和当前微服务处于同一个三元组中的,如果要拉取其他三元组的配置文件需要使用extension-config:
```yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/rc2?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=true
password: root
username: root
driver-class-name: com.mysql.cj.jdbc.Driver
# 微服务名称
application:
name: depart-provider
#nacos注册中心地址
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
username: nacos
password: nacos
config:
server-addr: 127.0.0.1:8848
username: nacos
password: nacos
file-extension: yml
# 共享配置
shared-configs:
- data-id: shared-template.yml
refresh: true
# 扩展配置
extension-configs:
- data-id: extension-template.yml
```
## 配置文件优先级
微服务会加载三类配置文件:自己的配置文件,shared-config共享配置文件,extension-config扩展配置文件
如果这三类配置文件中设置了同一个属性,例如:server.port,但是这三类配置文件的值都不相同,最终的值是哪个?
当前服务配置、共享配置、扩展配置加载顺序是:
- 共享配置
- 扩展配置
- 当前服务配置
**后加载的会覆盖之前加载的内容**。
优先级由高到低是:
- 当前服务配置
- 扩展配置
- 共享配置
并且如果Nacos和本地有相同的配置,会以Nacos的配置为主。
当前服务配置 > 扩展配置 > 共享配置 > 本地配置
## 配置动态更新
在nacos中添加一个配置:

### @ConfirguationProperties读取数据
```java
@Data
//@RefreshScope 2021.x不需要添加
@ConfigurationProperties(prefix = "depart")
public class DepartProperties {
private String name;
}
```
```java
@RestController
@RequestMapping("/provider/depart")
@EnableConfigurationProperties(DepartProperties.class)
public class DepartController {
@Resource
private DepartService departService;
@Value("${server.port}")
private String port;
@Autowired
private DepartProperties departProperties;
@GetMapping("/{id}")
public ResponseResult<Depart> getHandler(@PathVariable Long id){
Depart depart = departService.getById(id);
depart.setName(depart.getName() + " this provider port:" + port + " this depart name:" + departProperties.getName());
return ResponseResult.success(depart);
}
}
```
在nacos控制台修改了共享配置后,此处自动会更新,2021.x版本不需要添加@RefreshScope
### @Value读取数据
如果使用@Value读取数据:
```java
//provider#DepartController
@Value("${server.port}")
private String port;
@Value("${depart.name}")
private String departName;
@GetMapping("/{id}")
public ResponseResult<Depart> getHandler(@PathVariable Long id){
Depart depart = departService.getById(id);
depart.setName(depart.getName() + " this provider port:" + port + " this depart name:" + departName);
return ResponseResult.success(depart);
}
```
第一次访问得到的是销售部,将nacos中的配置文件更换为行政部,再次访问,得到的还是销售部。
**使用@Value读取的配置文件数据需要在类上标注@RefreshScope才能动态刷新**
```java
@RestController
@RefreshScope
@RequestMapping("/provider/depart")
public class DepartController {
@Resource
private DepartService departService;
@Value("${server.port}")
private String port;
@Value("${depart.name}")
private String departName;
@GetMapping("/{id}")
public ResponseResult<Depart> getHandler(@PathVariable Long id){
Depart depart = departService.getById(id);
depart.setName(depart.getName() + " this provider port:" + port + " this depart name:" + departName);
return ResponseResult.success(depart);
}
}
```
## 多环境选择
dev、local、test
前文中说明了微服务会自动拉取当前服务的配置文件:`${spring.application.name}.${spring.cloud.nacos.config.file-extension}`
如果要区分不同的环境,在nacos中配置文件的命名是:
`${spring.application.name}-${spring.profiles.activity}.${spring.cloud.nacos.config.file-extension}`
例如:
- depart-provider-dev.yml
- depart-provider-test.yml
在application.yml/bootstrap.yml中指定要激活的环境:
```yml
spring:
# 微服务名称
application:
name: depart-provider
cloud:
nacos:
#拉取共享配置
config:
server-addr: localhost:8848
file-extension: yml
username: nacos
password: nacos
shared-configs:
- data-id: shared-template.yml
refresh: true
extension-configs:
- data-id: extension-config.yml
config:
import:
#- optional:nacos:depart-provider.yml
- optional:nacos:shared-template.yml
- optional:nacos:${spring.application.name}-${spring.profiles.active}
.${spring.cloud.nacos.config.file-extension}
profiles:
active: dev
```
此时就会去nacos中拉取depart-provider-dev.yml的配置文件。
在开发时,如果要修改环境配置,不必修改这个配置文件,直接修改edit-config的active profiles即可
## 配置隔离
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)