Spring Cloud-Nacos
Spring Cloud-Nacos
认识Nacos
Nacos
是阿里巴巴的产品,现在是 SpringCloud
中的一个组件。相比 Eureka
功能更加丰富,在国内受欢迎程度较高。
Nacos /nɑ:kəʊs/
是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
服务(Service)是 Nacos 世界的一等公民。Nacos 支持几乎所有猪流类型的“服务”的发现、配置、管理:
Nacos 的关键特性包括:
服务发现和服务健康监测
Nacos 支持基于 DNS 和基于 RPC 的服务发现。服务提供者使用 原生SDK、OpenAPI、或一个独立的Agent TODO注册 Service 后,服务消费者可以使用DNS TODO 或HTTP&API查找和发现服务。
Nacos 提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求。Nacos 支持传输层 (PING 或 TCP)和应用层 (如 HTTP、MySQL、用户自定义)的健康检查。 对于复杂的云环境和网络拓扑环境中(如 VPC、边缘网络等)服务的健康检查,Nacos 提供了 agent 上报模式和服务端主动检测2种健康检查模式。Nacos 还提供了统一的健康检查仪表盘,帮助您根据健康状态管理服务的可用性及流量。
动态配置服务
动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。
动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。
配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。
Nacos 提供了一个简洁易用的UI (控制台样例 Demo) 帮助您管理所有的服务和应用的配置。Nacos 还提供包括配置版本跟踪、金丝雀发布、一键回滚配置以及客户端配置更新状态跟踪在内的一系列开箱即用的配置管理特性,帮助您更安全地在生产环境中管理配置变更和降低配置变更带来的风险。
动态 DNS 服务
动态 DNS 服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单DNS解析服务。动态DNS服务还能让您更容易地实现以 DNS 协议为基础的服务发现,以帮助您消除耦合到厂商私有服务发现 API 上的风险。
Nacos 提供了一些简单的 DNS APIs TODO 帮助您管理服务的关联域名和可用的 IP:PORT 列表.
服务及其元数据管理
Nacos 能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务的 SLA 以及最首要的 metrics 统计数据。
Nacos官方文档:home (nacos.io)
Nacos 地图
一图看懂 Nacos
Nacos生态
如 Nacos 全景图所示,Nacos 无缝支持一些主流的开源生态,例如
使用 Nacos 简化服务发现、配置管理、服务治理及管理的解决方案,让微服务的发现、管理、共享、组合更加容易。
Nacos安装-单机
前置环境
有一个能够运行 docker 和 mysql,可以参考Docker中运行一个mysql
选择拉取镜像
这里选择了**2.1.0
**版本
docker pull nacos/nacos-server:v2.1.0 |
创建nacos数据库
将nacos持久化到mysql数据库中
新建nacos数据库
从Nacos数据库配置下载建表语句。也可以将下列语句粘贴执行
/* |
运行容器
获取容器内的配置文件
先直接部署一个容器
是为了拿到
application.properties
等配置文件
docker run -d \ |
参数说明
- MODE=standalone 单节点模式(开发阶段单机模式即可)
- SPRING_DATASOURCE_PLATFORM=mysql 使用mysql数据库连接方式
- MYSQL_SERVICE_HOST=192.168.120.1 指定数据库地址
- MYSQL_SERVICE_PORT 数据库端口
- MYSQL_SERVICE_USER 数据库用户名
- MYSQL_SERVICE_PASSWORD 数据库密码
- MYSQL_SERVICE_DB_NAME 数据库名称
- -p 8848:8848 端口映射
- –name nacos 容器命名
- –restart=always 任意时候重启容器,开机就能自动启动容器(需设置docker为开机自启)
Ncaos Docker支持的参数有:
Common property configuration
属性名称 | 描述 | 选项 |
---|---|---|
MODE | 系统启动方式: 集群/单机 | cluster/standalone默认 cluster |
NACOS_SERVERS | 集群地址 | p1:port1空格ip2:port2 空格ip3:port3 |
PREFER_HOST_MODE | 支持IP还是域名模式 | hostname/ip 默认 ip |
NACOS_SERVER_PORT | Nacos 运行端口 | 默认 8848 |
NACOS_SERVER_IP | 多网卡模式下可以指定IP | |
SPRING_DATASOURCE_PLATFORM | 单机模式下支持MYSQL数据库 | mysql / 空 默认:空 |
MYSQL_SERVICE_HOST | 数据库 连接地址 | |
MYSQL_SERVICE_PORT | 数据库端口 | 默认 : 3306 |
MYSQL_SERVICE_DB_NAME | 数据库库名 | |
MYSQL_SERVICE_USER | 数据库用户名 | |
MYSQL_SERVICE_PASSWORD | 数据库用户密码 | |
MYSQL_SERVICE_DB_PARAM | 数据库连接参数 | default : characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false |
MYSQL_DATABASE_NUM | 数据库编号 | 默认 :1 |
JVM_XMS | -Xms | 默认 :1g |
JVM_XMX | -Xmx | 默认 :1g |
JVM_XMN | -Xmn | 默认 :512m |
JVM_MS | -XX:MetaspaceSize | 默认 :128m |
JVM_MMS | -XX:MaxMetaspaceSize | 默认 :320m |
NACOS_DEBUG | 是否开启远程DEBUG | y/n 默认 :n |
TOMCAT_ACCESSLOG_ENABLED | server.tomcat.accesslog.enabled | 默认 :false |
NACOS_AUTH_SYSTEM_TYPE | 权限系统类型选择,目前只支持nacos类型 | 默认 :nacos |
NACOS_AUTH_ENABLE | 是否开启权限系统 | 默认 :false |
NACOS_AUTH_TOKEN_EXPIRE_SECONDS | token 失效时间 | 默认 :18000 |
NACOS_AUTH_TOKEN | token | 默认 :SecretKey012345678901234567890123456789012345678901234567890123456789 |
NACOS_AUTH_CACHE_ENABLE | 权限缓存开关 ,开启后权限缓存的更新默认有15秒的延迟 | 默认 : false |
MEMBER_LIST | 通过环境变量的方式设置集群地址 | 例子:192.168.16.101:8847?raft_port=8807,192.168.16.101?raft_port=8808,192.168.16.101:8849?raft_port=8809 |
EMBEDDED_STORAGE | 是否开启集群嵌入式存储模式 | embedded 默认 : none |
NACOS_AUTH_CACHE_ENABLE | nacos.core.auth.caching.enabled | default : false |
NACOS_AUTH_USER_AGENT_AUTH_WHITE_ENABLE | nacos.core.auth.enable.userAgentAuthWhite | default : false |
NACOS_AUTH_IDENTITY_KEY | nacos.core.auth.server.identity.key | default : serverIdentity |
NACOS_AUTH_IDENTITY_VALUE | nacos.core.auth.server.identity.value | default : security |
NACOS_SECURITY_IGNORE_URLS | nacos.security.ignore.urls | default : /,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/p |
宿主机配置文件映射
拷贝配置文件
docker cp nacos:/home/nacos/conf/application.properties /home/docker/nacos/config/ |
拷贝logback日志配置文件
docker cp nacos:/home/nacos/conf/nacos-logback.xml /home/docker/nacos/config/ |
修改application.properties的配置
# spring |
采用添加默认值的方式,这样不会影响指定命令行的参数
运行容器
运行之前先删除之前启动的容器
docker stop nacos |
重新运行容器
docker run -d \ |
访问:**ip:8848/nacos
** 进入 Nacos
图形化控制台
输入账户密码 默认账户密码都为 nacos
进入如下界面表示登录成功。
服务注册/服务发现
入门案例
将服务注册到Nacos上,完成服务调用。
由于 Spring Cloud Commons 定义了Spring Cloud 的一组抽象类和接口,所以Spring Cloud 各类组件的行为都是一致的,例如Spring Cloud 规定了 服务发现接口和 服务注册的接口,Spring Cloud 中的服务治理组件都是实现了这两个接口并衍生的,所以相同类别的组件切换只需要更换依赖和修改配置即可。其他操作与原来一致(例如服务的注册,服务的发现,服务的调用等)
例如这里我们使用 nacos 代替 eureka 作为注册中心,只需要修改依赖和添加nacos的服务器地址即可,其他行为与原eureka相同,不需要做其他的改变。
Spring Cloud 2021.0.1 新版本使用 Spring Cloud Loadbalancer 做负载均衡,没有默认集成 Ribbon 了,在进行服务消费者开发的项目中需要引入 Loadbalancer 依赖,这一点需要注意一下。从2021版本开始 Nacos已经不再支持Ribbon了。所以推荐使用Spring Cloud LoadBalaner
父工程
在父工程中添加 spring-cloud-alibaba-dependencies
得管理依赖
<dependency> |
完整pom.xml依赖
|
消费者
将Cloud-eureka-consumer-order80
工程复制到该父工程的子模块下,改名为Cloud-nacos-consumer-order80
新增pom.xml依赖,并且把原来的eureka的依赖删除或者注释掉。
<!-- nacos客户端依赖 --> |
完整pom.xml
依赖
|
删除掉原来与eureka
有关的所有配置,application.yml
和代码中的部分
application.yml
新增nacos配置
cloud: |
生产者
将Cloud-eureka-provider-payment8001
和 Cloud-eureka-provider-payment8002
工程复制到该父工程的子模块下,改名为Cloud-nacos-provider-payment8001
和 Cloud-nacos-provider-payment8002
新增pom.xml依赖,并且把原来的eureka的依赖删除或者注释掉。
<!-- nacos客户端依赖 --> |
完整pom.xml
依赖
|
删除掉原来与eureka
有关的所有配置,application.yml
和代码中的部分
application.yml
新增nacos配置
cloud: |
测试
启动生产者集群和消费者。
启动完成后可以在Nacos的控制界面中看到,这跟eureka也是一致的。
点击详情可以看到服务实例节点的ip、端口等信息。
调用get: http://localhost:80/consumer/payment/get/1547503738317369346
调用成功。
Nacos服务分级存储模型
一个服务可以包含多个服务集群,集群又可以包含多个服务实例。这就是Nacos的分级存储模型。
服务跨集群调用问题
服务调用尽可能选择本地集群的服务,,跨集群调用延迟较高
本地集群不可访问时,再去访问其他集群。
没有设置集群是,会显示DEFAULT
我们可以通过修改application.yml
文件来修改配置集群名称
cloud: |
修改后
总结:
- Nacos服务分级存储模型
- 一级是服务,例如userservice
- 二级是集群,例如杭州或上海
- 三级是实例,例如杭州机房的某台部署了userservice的服务器
- 如何设置实例的集群属性
- 修改
application.yml
文件,添加集群名称即可。
- 修改
NacosRule 负载均衡
Nacos + Ribbon特有的策略
Spring Cloud Nacos 2021 版本开始已经禁止使用Ribbon做负载均衡了,而使用LoadBalancer有没有许多支持的策略,所以这里我们选择老版本的Spring Cloud Nacos 做演示。
<dependency> |
消费者添加如上依赖后,修改application.yml
配置
cloud-payment-service: |
为 cloud-payment-service
服务配置Nacos的集群负载均衡策略。
修改后消费者就会优先调用同一个集群内的服务提供者。如果同一集群内的服务提供者宕机或者发生网络波动断开了与注册中心的连接,消费者就会向其他集群内的提供者发起调用,并且会在控制台提醒发生了跨集群调用。
总结:
- NacosRule负载均衡策略
- 优先选择同集群服务实例列表
- 本地集群找不到提供者,才去其他集群寻找,并且会报警
- 确定了可用实例列表后,再采用随机负载均衡挑选实例。
根据权重负载均衡
实际部署中会出现这样的场景:
- 服务器设备性能由差异,部分实例所在机器性能比较好,另一些较差,我没希望性能好的机器承担更多的用户请求。
Nacos提供了权重配置来控制访问频率,权重越大则访问频率越高。
在Nacos控制台可以设置实例的权重值,首先选中实例后面的编辑按钮
将权重设置为0.1,测试可以发现8001被访问到的频率大大降低
用途
除了希望将性能更好的机器承担更多的用户请求外,还有一点;当我们想要将某一服务实例做维护时,可以将该服务实例的权重调为0,慢慢的请求将不会再发送到该实例上,我们就可以将其下线进行维护,等维护完毕,想要上线时,将其的权重调小一点,放部分请求测试服务是否可用后,再将其的权重调为正常值。在此期间用户时完全没有感知的。
总结
- 实例的权重控制
- Nacos控制台可用设置实例的权重值,0~1之间
- 统计群内的多个实例,权重越高被访问的频率越高
- 权重为0则完全不会被访问
环境隔离 - NameSpace
Nacos中服务存储和数据存储的最外层都是一个名为 namespace 的东西,用来做最外层隔离。
用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
Nacos 数据模型 Key 由三元组唯一确认。
- 作为注册中心时,Namespace + Group + Service
- 作为配置中心时,Namespace + Group + DataId
在Nacos控制台可用创建 namespace,用来隔离环境
然后填写一个新的命名空间信息:
保存后会在控制台看到这个命名空间的id:
而我们创建的服务注册到 Nacos 上默认都是在 public 这个命名空间下,想要修改就需要在application.yml
中添加如下配置。
cloud: |
配置好后 在dev的命名空间下就可以看到我们配置的服务。
此时访问消费者调用提供者的接口,因为namespace不同,会导致找不到userservice,控制台会报错:
总结
- Nacos环境隔离
- 每个namespace都有唯一id
- 服务设置namespace时要写id而不是名称
- 不同namespace下的服务互相不可见
配置分组-Group
Nacos 中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串(如 Buy 或 Trade )对配置集进行分组,从而区分 Data ID 相同的配置集。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如 database_url 配置和 MQ_topic 配置。
Nacos 与 Eureka 对比
nacos注册中心细节分析
消费者并不是每一次都向注册中心拉取一次服务列表,而是有一个缓存,nacos客户端会对服务列表做一个服务列表缓存,默认每隔30秒刷新一次。这一点与Eureka一致;但是当发现有服务变更,Nacos会主动推送变更消息到消费者。
Nacos对于临时实例采用心跳检测(即服务每个一段时间向 Nacos 发起一次心跳),如果超过一段时间后 Nacos 接收不到服务的心跳了,就会把这个临时实例剔除;
但是对于非临时实例 服务实例不再需要向 Nacos 发送心跳,而是Nacos主动询问节点是否存活。并且服务挂掉了也不会将其直接剔除,而是标记为不健康的实例。
cloud: |
总结:
- Nacos 与 Eureka 的共同点
- 都支持服务注册和服务拉取
- 都支持服务提供者心跳方式做健康检测
- Nacos 与 Eureka 的区别
- Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
- 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
- Nacos 支持服务列表变更的消息推送模式,服务列表更新更及时。
- Nacos 集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式。
配置管理
前面我们学过 Spring Cloud Config。这里我们学习 Nacos 的配置管理,这也是非常流行的方式。
- 配置更改热更新
Spring Cloud Alibaba Nacos 即有服务注册/发现的功能,又有配置管理的功能。
添加配置
在Nacos控制台上添加配置
在弹出表单中填写配置信息:
获取配置
配置获取的步骤如下:
- 引入Nacos的配置管理客户端依赖
<dependency> |
在resource目录添加一个bootstrap.yml文件,这个文件是引导文件,优先级高于application.yml,用来在引导配置管理中心的的信息,来获取配置:
spring:
application:
name: cloud-order-service #服务名称
profiles:
active: dev #开发环境,这里是dev
cloud:
nacos:
server-addr: 36.137.128.27:8848
username: nacos
password: nacos
config:
file-extension: yaml #文件名后缀
enabled: true
group: DEFAULT_GROUP
management:
endpoints:
web:
exposure:
include:
- '*'配置后可以将Application.yml中的nacos相关配置给删除,但还是按需配置。
业务类
private String dateFormat;
public String now(){
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateFormat));
}启动后 访问对于接口
2022-08-14 11:56:48
总结:
将配置交给Nacos管理的步骤
- 在Nacos中添加配置文件。
- 在微服务中引入nacos的config依赖。
- 在微服务中添加bootstrap.yml,配置nacos地址、当前环境、服务名称、文件后缀名。这些决定了程序启动时去nacos读取那个文件。
配置自动刷新
Nacos中的配置文件变更后,微服务无需重启就可以感知。与Spring Cloud Config 不同的是Nacos配置文件发送变动后会主动推送给订阅者。不过需要通过下面两种配置实现:
方式一:
在 @Value 注入的变量所在类上添加注解 @RefreshScope
|
方式二:
使用@ConfigurationProperties注解
|
|
总结:
Nacos配置更改后,微服务可以实现热更新,方式:
- 通过@Value注解注入,结合@RefreshScope来刷新
- 通过@ConfigurationProperties注入,自动刷新
注意事项:
- 不是所有的配置都适合放到配置中心,维护起来比较麻烦
- 建议将一些关键参数,需要运行时调整的参数放到nacos配置中心,一般都是自定义配置
多环境配置共享
微服务启动时会从nacos读取多个配置文件:
- [spring.application.name]-[spring.profiles.active].yaml,例如:userservice-dev.yaml
- [spring.application.name].yaml,例如:userservice.yaml无论profile
如何变化,[spring.application.name].yaml这个文件一定会加载,因此多环境共享配置可以写入这个文件
新增配置文件cloud-order-service.yaml
测试
配置类
|
业务类
|
结果
{ |
发现确实访问到了未带有属性的配置文件。
多环境配置覆盖优先级
服务名-profile.yaml > 服务名称.yaml > 本地配置
总结:
微服务会从nacos读取的配置文件:
- [服务名]-[spring.profile.active].yaml,环境配置
- [服务名].yaml,默认配置,多环境共享
优先级:
- [服务名]-[环境].yaml >[服务名].yaml > 本地配置
多服务共享配置
不同微服务之间可以共享配置文件,通过下面的两种方式来指定:
首先创建一个用来共享的配置文件。即除了配置中心独有特质的配置文件外,还想配置中心拉取以创建的共享的配置文件
方式一:
spring: |
方式二:
spring: |
测试:
{ |
多种配置的覆盖优先级:
服务名-profile.yaml >服务名称.yaml > extension-config > shared-config > 本地配置
总结
微服务默认读取的配置文件:
- [服务名]-[spring.profile.active].yaml,默认配置
- [服务名].yaml,多环境共享
不同微服务共享的配置文件:
- 通过shared-configs指定
- 通过extension-configs指定
优先级:
- 环境配置 >服务名.yaml > extension-config > extension-configs > shared-configs > 本地配置
实践:
项目中的使用:每个微服务创建自己的命名空间,使用配置分组区分环境,dev、test、prod
同时加载多个配置集
- 微服务任何配置信息,任何配置文件都可以放在配置中心中
- 只需要在 bootstrap.yml 中说明加载配置中心那些配置文件即可
Nacos安装-集群
docker network create nacos-net
Open-API
Nacos open-API官网地址:https://nacos.io/zh-cn/docs/open-api.html
包含了查询服务实例、注销服务实例等功能。