SpringCloud Alibaba使用Nacos作为服务注册及配置中心
Nacos简介
Nacos是阿里巴巴开源的服务注册中心以及配置中心,致力于给开发者提供一款便捷、简单上手的开源框架。
nacos和eureka功能对比:
Nacos注册中心原理
注册流程
整个注册中心的注册和发现流程主要有三个方面来完成:服务的提供方(以下简称server)、服务的消费者(以下简称client)、注册中心(nacos)。首先我们来探讨server与nacos的交互过程。
server需要通过nacos官方的OpenApi提供的接口来发起服务注册请求,随后server会定时向nacos发送心跳信息来进行心跳检测,对于使用者来说这一步可以采用ScheduledExecutorService创建定时任务来完成。nacos会异步的处理注册请求任务和心跳任务。
nacos心跳机制
nacos和client之间采取推拉结合的交互方式,一方面client可以通过定时任务每隔10s向nacos发起查询请求,如果服务列表改变nacos就会返回新列表,另一方面当本地服务实例发生变化时(即server实例注册成功或者心跳停止断开链接),nacos会主动通过UDP协议推送到client,udp协议非常快,不需要保持长连接。在注册中心的场景中client数量往往多于server,如果每一次服务更新,nacos要和成千上万的服务消费者去建立Tcp的话性能肯定是不行的。而如果UDP通知失败,客户端每10秒还会主动去拉一次,客户端拉取和服务器推送是互补的,这样既能保证server实例更新的时效性,又能提高效率。
Nacos配置中心原理
- 在nacos上修改配置。
- nacos客户端中ClientWorker会每隔10ms异步读取一次配置中心文件md5值。
- 和本地md5值比较,有变化的从服务器拉取。
- 将文件保存/缓存到本地。
- 通知NacosContextRefresher配置文件有变化。
- NacosContextRefresher判断是否需要更新配置。
- 发送事件通知ContextRefresher去更新。
- 这里是更新配置的关键步骤。
- 准备一份before配置,然后通过构建新的Environment的方式拿到新的配置, 接着比较变化,得到有变化的keys。
- 构建Environment时会去读取配置文件,文件优先读本地,如果本地没有通过Http请求服务商。
- 构建NacosPropertiesSource,并重新生成ConfigurationProperties对象。
- 通知RefreshScope去更新。
- 销毁scope='refresh'的bean。
- 通知bean容器去构建新的bean(懒加载)。
- 将属性(@Value注解)注入到新的bean。
集成Nacos
安装Nacos Server
下载软件,安装完成后,访问地址:http://127.0.0.1:8848/nacos/index.html ,默认的账号密码:nacos/nacos
服务注册
前面我们已经搭建好Nacos Server。接下来我们新建module,名称alibaba-cloud-user。
1、引入相关依赖
<!--boot web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2、启动类上可以不用写注解@EnableDiscoveryClient
3、配置文件
spring:
application:
name: alibaba-cloud-user
cloud:
nacos:
discovery:
enabled: true
#nacos地址
server-addr: http://localhost:8848
#当前应用是否注册到注册中心
register-enabled: true
#注册到注册中心的服务名,不配置的话就是spring.application.name的值。一般我们不会特殊指定
#service: alibaba-cloud-user
4、服务启动后可以在nacos管理界面查看注册成功的服务。
5、可以通过发现客服端搜索实例名的形式查看服务是否注册成功,并查看注册具体信息
@RequestMapping("/user")
@RestController
public class UserController {
@Autowired
public DiscoveryClient discoveryClient;
@RequestMapping("/getServiceList")
public List<ServiceInstance> getServiceList(){
return discoveryClient.getInstances("alibaba-cloud-user");
}
}
项目启动后,访问:http://localhost:5555/user/getServiceList
配置中心
引入配置中心的目的
- 配置属性的动态刷新
- 配置文件的集中管理
接入配置中心
1、引入相关依赖
<!-- nacos config-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2、编写一个bootstrap.yml配置文件(不用application.yml配置了)
server:
port: 5555
spring:
application:
name: alibaba-cloud-user
cloud:
nacos:
#服务注册
discovery:
enabled: true
#nacos地址
server-addr: http://localhost:8848
#当前应用是否注册到注册中心,默认是true
register-enabled: true
#配置中心
config:
enabled: true
#nacos地址
server-addr: http://localhost:8848
#配合文件后缀
file-extension: yaml
nacos配置中心默认是拿文件名与spring.application.name值一样的文件。例如,上面我们匹配的文件名就是:alibaba-cloud-user.yml。
3、我们在nacos server上创建一个alibaba-cloud-user.yml文件
Data Id类似于文件名。
内容如下:
user:
name: linhongwei
password: 123456
4、创建controller获取配置文件的user.name和user.password
@RequestMapping("/user")
@RestController
public class UserController {
@Value("${user.name}")
private String userName;
@Value("${user.password}")
private String password;
//private String userName;
//@Value("${user.name}")
//public void setUserName(String userName) {
// this.userName = userName;
//}
@RequestMapping("/getUserInfo")
public String getUserInfo() {
return "userName:" + userName + ", password:" + password;
}
}
项目启动后,访问:http://localhost:5555/user/getUserInfo
配置文件的匹配规则
1、配置微服务配置中⼼⽂件
在 Nacos Spring Cloud 中,数据集(Data Id) 的配置完整格式如下:
{prefix}-${spring.profile.active}.${file-extension}
1)prefix:就是配置的服务名,默认是你配置的,通俗的说就是服务注册时注册到服务中⼼的服务名的值
spring:
application:
name: alibaba-cloud-user
2)spring.profile.active:是配置开发环境的值,⼀个程序不可能总是在开发环境,可能需要切换到测试环境,上线环境,它们的配置⽂件都是不同的,所以为了⽅便环境切换,我们配置不同的开发环境⽂档。⽐如在bootstrap.yml中有配置dev,就是开发环境:
spring:
profiles:
active: dev #表⽰开发环境
生效的文件就是alibaba-cloud-user-dev.yml。
我们在nacos再创建一个名为alibaba-cloud-user-dev.yml的配置文件
内容如下:
user:
name: zhangsan
password: 654321
访问 http://localhost:5555/user/getUserInfo
说明环境的切换生效了。
3)最后我们需要指定配置⽂件类型,默认是properties。我们可以⾃⼰指定⽂件类型,⽐如配置:
spring:
cloud:
nacos:
config:
file-extension: yaml #指定配置⽂件类型为yaml⽂件
命名空间的隔离
public是保留空间,默认新增的所有配置都在public空间。常用来隔离开发,测试,⽣产环境。
可以添加命名空间,然后在bootstrap.yml配置⽂件添加命名空间的id即可切换到对应的命名空间,使⽤对应空间下的配置⽂件:
spring:
cloud:
nacos:
config:
namespace: 2f7930c8-ccae-4577-bdcd-0cf874cf1297 #对应创建的命名空间的ID
也可以基于微服务来创建命名空间,⽤每⼀个微服务名来命名,达到隔离每⼀个微服务的⽬的,哪⼀个微服务需要配置直接去对应的微服务空间下找配置即可,使得项⽬更加结构化。
配置分组Group
按时间等因素影响,可以去分组配置,⽐如双11组,双12组等等。
默认所有的配置集都属于: DEFAULT_ GROUP。我们也可以⾃⼰适配。
⼀般的建议是使⽤命名空间来隔离服务,即每个微服务创建⼀个命名空间,使⽤配置分组来区分环境:dev、test、prod等。
从⼀个配置中⼼加载多个配置集
将⼀个配置⽂件按功能拆分成不同的⽂件,然后在程序组合加载到⼀起组成⼀个完整的配置⽂件。
⽐如拆分⼀下配置:
pring:
profiles:
active: dev #表⽰开发环境
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://139.224.67.81:3306/zunhui_sms?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: root
application:
name: shop-coupon
spring:
application:
name: shop-coupon
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yaml #指定配置⽂件类型为yaml⽂件
discovery:
server-addr: 127.0.0.1:8848
mybatis-plus:
mapper-locations: classpath/mapper/**/*.xml
global-config:
db-config:
id-type: auto #配置id⾃增
就可以拆分成三个⽂件,⼀个关务数据源的datasource.yml的,⼀个关于mybatis的,剩下的⼀个other配置:
只需要在配置⽂件中使⽤ext-config就可以加载多个配置⽂件:
spring:
cloud:
nacos:
#配置中心
config:
# 扩展配置 老版本是 ext-config,其余的没什么变化
extension-configs:
- dataId: datasource.yml
group: dev
refresh: true #是否刷新, 默认是false
- dataId: mybatis.yml
group: dev
refresh: true
- dataId: other.yml
group: dev
refresh: true
不同服务存在相同的配置
通过spring.cloud.nacos.config.shared-configs ,配置文件中增加各个微服务共享的配置,注意越排到后面的公共配置yml优先级越高
注:extension-configs的优先级高于shared-configs
扩展的配置文件加载优先级
Spring Cloud Alibaba Nacos Config 目前提供了三种配置能力从 Nacos 拉取相关的配置
- 通过 spring.cloud.nacos.config.shared-configs[n].data-id 支持多个共享 Data Id 的配置;
- 通过 spring.cloud.nacos.config.extension-configs[n].data-id 的方式支持多个扩展 Data Id 的配置;
- 通过内部相关规则(应用名、应用名+ Profile )自动生成相关的 Data Id 配置;
当三种方式共同使用时,总的来说 他们的一个优先级关系是:A < B < C。
1)以老版本来说:
- shared-dataids中越靠后,优先级越高;
- ext-config中n越大、或越靠后,优先级越高;
- shared-dataids < ext-config < 内部;
2)以新版本来说:
- shared-configs中n越大、或越靠后,优先级越高;
- extension-configs中n越大、或越靠后,优先级越高;
- shared-configs < extension-configs < 内部;
本地和远程配置优先级
SpringCloud中,nacos是借助SpringCloud的Config来加载属性源的,所以是否覆盖系统属性和配置文件属性的设置也是通过SpringCloud的配置进行触发。
默认情况下nacos属性源配置优先级最高,会覆盖系统属性源和配置属性源(本地文件)。
可以通过在远程配置中心(Nacos服务中)中做如下配置,设置本地配置覆盖远程配置:
spring:
cloud:
config:
# Nacos远程配置是否不覆盖其他属性源(文件、系统),默认为false,即覆盖其他源(文件、系统),当allow-override:为true时才会生效
override-none: true
# 是否允许Nacos远程配置被本地文件覆盖,默认为true
allow-override: true
# Nacos远程配置是否可以覆盖系统属性源(系统环境变量或系统属性),默认为true,即允许
override-system-properties: false
spring.cloud.nacos配置说明
注册中心
配置中心
# nacos 配置中心信息
spring:
cloud:
nacos:
server-addr: 39.103.194.102:8848 # nacos 服务端地址
username: nacos # nacos 用户名
password: nacos # nacos 用户密码
config:
file-extension: yaml # 配置文件类型 默认 properties 类型
# namespace: public # 命名空间 默认 public 如果配置了 public 循环打印clientWork日志, public 默认不配置
# group: DEFAULT_GROUP # 分组 默认使用的是 DEFAULT_GROUP 。如果需要自定义自己的 Group,可以通过以下配置来实现:
# enabled: true # 通过设置 spring.cloud.nacos.config.enabled = false 来完全关闭 Spring Cloud Nacos Config
# refresh-enabled: false # nacos 客户端无法感知
shared-configs: # 使用自定义配置文件时,data-id 必须加文件类型,否则报错
- data-id: com.mj.dataid-1.yaml
#group 默认分组 DEFAULT_GROUP
refresh: true
extension-configs:
- data-id: com.mj.dataid-2.yaml
#group 默认分组 DEFAULT_GROUP
refresh: true
# 配置文件的优先级
# profile 方式 > 默认配置文件 > extension-configs ( 扩展配置,下标越大 优先级越大)> shared-configs(共享配置)
Nacos使用细节
1、如果我们需要不停机改变我们的生产环境的某个值(例如文件保存地址)来控制业务逻辑。我们需要在对应的类上添加@RefreshScope 进行动态刷新。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!