服务注册与配置Nacos
- nacos 介绍
- nacos 特性
- nacos 的安装
- nacos 注册中心
- 注册中心案例
- 注册中心原理
- nacos服务分级存储模型
- nacos 配置中心
- nacos 配置数据模型
- nacos 配置管理
- 配置文件优先级
- nacos 配置持久化
- nacos 集群部署
nacos 介绍
nacos 英文全称 Dynamic Naming and Configuration Service,Na为naming/nameServer即注册中心。co为configuration 即注册中心,service是指该注册/配置中心都是以服务为核心。
Nacos 是阿里巴巴推出来的一个开源项目。Nacos 提供了一组简单易用的特性集,帮助快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 支持几乎所有主流类型的服务的发现、配置和服务管理平台,提供注册中心、配置中心和动态DNS服务三大功能。能够无缝对接Springcloud、Spring、Dubbo等流行框架。
nacos 特性
服务发现和服务健康监测
支持 DNS 与 RPC 服务发现,也提供原生 SDK、OpenAPI 等多种服务注册方式和 DNS、HTTP 与 API 等多种服务发现方式。
Nacos 提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求。Nacos 支持传输层 (PING 或 TCP)和应用层 (如 HTTP、MySQL、用户自定义)的健康检查。 对于复杂的云环境和网络拓扑环境中(如 VPC、边缘网络等)服务的健康检查,Nacos 提供了 agent 上报模式和服务端主动检测2种健康检查模式。Nacos 还提供了统一的健康检查仪表盘,帮助您根据健康状态管理服务的可用性及流量。
动态配置服务
动态配置服务允许您在所有环境中以集中和动态的方式管理所有服务的配置。 Nacos 消除了在更新配置时重新部署应用程序,这使配置的更改更加高效和灵活。
Nacos 还提供了一个简洁易用的 UI 帮助您管理所有的服务和应用的配置。Nacos 还提供包括配置版本跟踪、金丝雀发布、一键回滚配置以及客户端配置更新状态跟踪在内的一系列开箱即用的配置管理特性,帮助您更安全地在生产环境中管理配置变更和降低配置变更带来的风险。
动态 DNS 服务
Nacos 支持动态 DNS 服务权重路由,能够让我们很容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单 DNS 解析服务。
服务及其元数据管理
Nacos 能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略。
nacos 的安装
下载地址:https://github.com/alibaba/nacos/releases/download/1.4.1/nacos-server-1.4.1.zip
解压软件:请解压到路径中不包含中文以及空格的目录,Java运行环境为JDK1.8+。
解压完成后,使用命令启动startup.cmd -m standalone
启动完成,进行访问:http://localhost:8848/nacos/,登录账号:nacos,登录密码:nacos
nacos 注册中心
nacos 注册中心分为 server 与 client,server 采用 Java 编写,为 client 提供注册发现服务与配置服务。而client可以用多语言实现,client与微服务嵌套在一起,nacos提供 sdk和 openApi,如果没有sdk也可以根据 openApi手动写服务注册与发现和配置拉取的逻辑。
注册中心结构图
注册中心案例
服务提供者,将自身注册到注册中心。
pom文件中引入 nacos 依赖。此依赖的作用是服务发现
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
修改配置文件
server:
port: 8001
spring:
application:
name: service-goods
cloud:
nacos:
discovery:
server-addr: http://localhost:8848 # nacos server 的地址
在主启动类上添加 @EnableDiscoveryClient 注解,启动项目,就可以将当前服务注册到nacos中。
服务名:每个服务在服务注册中心的标识。
服务实例:网络中提供服务的实例,具有IP和端口,一个实例即为运行在服务器上的一个进程。
服务消费者
在pom 文件中引入服务发现依赖。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
修改配置文件
server:
port: 8002
spring:
application:
name: service-order
cloud:
nacos:
discovery:
server-addr: http://localhost:8848 # nacos server 的地址
需要在启动类上添加 @EnableDiscoveryClient 注解。
远程调用,通过服务名去进行远程调用。
@RestController
public class OrderController {
@Value("${server.port}")
private Integer port;
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/order/findByOid")
public String findByOid(@RequestParam("oid") String oid) {
String goods = restTemplate.getForObject("http://service-goods/goods/findByGid?gid=1", String.class);
return goods;
}
}
远程调用执行流程:
- 服务提供方将自己注册到服务注册中心
- 服务消费方从注册中心获取服务地址
- 通过获取的服务进行远程调用
注册中心原理
nacos 将服务实例划分为临时实例和永久实例。默认情况下服务为临时实例。
当服务为临时实例,采用心跳检测的方式,来对服务实例进行健康检查,心跳带上了服务名,服务ip,服务端口等信息。当服务宕机,nacos 则会直接将服务实例从服务列表中剔除。
当服务为永久实例,nacos采用主动问询的方式,来对服务实例进行健康检查。当服务宕机,nacos 不会将服务实例从服务列表中剔除,而仅做标记。
服务消费者获取服务列表的方式有两种,一种为定时拉取,一种为nacos主动推送,当nacos检测到服务提供者宕机,会主动向服务消费者进行推送。
通过配置文件设置临时实例和永久实例
spring:
cloud:
nacos:
discovery:
ephemeral: false # 设置为永久实例,默认为临时实例
nacos服务分级存储模型
命名空间 namespace
不同的命名空间逻辑上是隔离的,不特殊设置的情况下,服务不会跨命名空间请求,不同命名空间中的服务实例互不可见,命名空间主要的作用是区分服务使用的范围,比如开发、测试、生产、灰度可以分别设置四个命名空间来互相隔离。nacos中默认的命名空间为 public。
集群
多个服务实例组成一个集群,在进行远程调用的时候,优先访问集群内的服务实例。nacos中默认的集群为 DEFAULT。
实例
服务注册到注册中心的具体实例。一个服务可以注册多个服务实例,在访问的时候根据负载均衡算法,选择其中一个进行调用。
总结:
命名空间的作用是不同环境之间进行隔离,集群是对服务实例的进一步划分,集群中由多个不同的服务实例组成。
在nacos中创建新的命名空间,记录命名空间的 id,在配置文件中进行服务注册时指定命名空间和集群。
spring:
application:
name: service
cloud:
nacos:
discovery:
server‐addr: http://localhost:8848 # nacos server 的地址
namespace: a1f8e863‐3117‐48c4‐9dd3‐e9ddc2af90a8 #命名空间 id
cluster‐name: DEFAULT #默认集群,可不填
设置 nacos 负载均衡规则,优先调用集群内的服务实例。
userservice: # 服务名
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
nacos 配置中心
配置:应用程序在启动和运行的时候往往需要读取一些配置信息,配置基本上伴随着应用程序的整个生命周期,如数据库连接参数、启动参数等。
配置的特点:
- 配置是独立于程序的只读变量
- 配置贯穿于应用的整个生命周期,应用在启动时通过读取配置来初始化,在运行时根据配置调整行为。
- 配置可以有多种加载方式,常见的有程序内部硬编码,配置文件,环境变量,启动参数,基于数据库等。
- 配置需要治理,同一份程序在不同的环境(开发,测试,生产)、不同的集群(如不同的数据中心)经常需要有不同的配置,所以需要有完善的环境、集群配置管理。
在微服务架构中为了统一管理各个微服务的配置信息专门设置配置中心,配置中心就是一种统一管理各种应用配置的基础服务组件。配置中心将配置从各应用中剥离出来,对配置进行统一管理,应用自身不需要自己去管理配置。
配置中心的服务流程:
- 用户在配置中心更新配置信息。
- 服务A和服务B及时得到配置更新通知,从配置中心获取配置。
nacos 配置数据模型
对于 nacos 配置管理,通过 namespace、group、Data ID 能够定位到一个配置集。
命名空间 (namespace):
命名空间可用于进行不同环境的配置隔离。例如可以隔离开发环境、测试环境和生产环境,因为它们的配置可能各不相同,或者是隔离不同的用户,不同的开发人员使用同一个nacos管理各自的配置,可通过 namespace 隔离。不同的命名空间下,可以存在相同名称的配置分组(Group) 或 配置集。
group:
nacos中的一组配置集合,是组织配置的维度之一,通过一个有意义的字符串(如 Buy 或 Trade)对一组配置集合进行分组,从而区分Data ID相同的配置集合,当在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP。
Data Id:
nacos 中的某个配置集合的 ID,配置集合ID是组织划分配置的维度之一,Data ID 通常用于组织划分系统的配置集合,一个系统或者应用可以包含多个配置集合,每个配置集都可以被一个有意义的名称标识。
通常把 namespace看作环境的区分,不同的namespace 代表不同环境,如开发、测试、生产环境。
通常把group看作项目的区分,不同的group 代表某项目,如XX医疗项目、XX电商项目。
通常把 data Id 看作不同的工程的区分,每个项目下往往有若干个工程,每个配置集(DataId) 就是一个工程的主配置文件。
nacos 配置管理
发布配置,在nacos中新建配置。
获取配置。从配置中心获取配置
获取nacos中的步骤:
bootstrap.yml 优先级最高,项目启动后,优先读取。
在项目启动后,读取 bootstrap.yml 中的配置信息,在 bootstrap.yml 中配置nacos 的配置地址信息,读取nacos配置信息,然后再读取本地配置文件,最后创建spring容器,创建bean。
在项目中添加依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐starter‐alibaba‐nacos‐config</artifactId>
</dependency>
在resource目录添加 bootstrap.yml 文件。在文件中配置nacos信息。
需要指定nacos的地址,配置文件的信息,包括data Id,group,namespace,用来确定一个唯一的配置文件。
data Id 必须指定,group 如不指定默认 DEFAULT_GROUP,namespace,如不指定默认public。
data Id 的组成格式
${prefix}-${spring.profile.active}.${file-extension}
prefix 默认为所属工程配置 spring.application.name 的值,也可以用spring.cloud.nacos.config.prefix来配置。
spring.profile.active 即为当前环境对应的profile,当spring.profile.active为空的时候,对应的连接符-也不存在,
data Id的拼接格式变成prefix.{file-extension}
file-extension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。
下面的data Id 为 :userservice-dev.yaml
spring:
application:
name: userservice
profiles:
active: dev #激活开发环境配置
cloud:
nacos:
discovery:
server-addr: http://localhost:8848
config:
server-addr: http://localhost:8848
# prefix 指定配置文件的前缀
file-extension: yaml #指定配置文件的拓展名
group: DEFAULT_GROUP #指定配置文件所在组
namespace: public #指定配置文件所在命名空间
测试获取配置中心的配置信息:
@RestController
@RequestMapping("/user")
@RefreshScope
public class UserController {
// 注入nacos.中的配置属性
@Value("${pattern.dateformat}")
private String dateformat;
// 编写controller,通过日期格式化器来格式化现在时间并返回
@GetMapping("now")
public String now(){
return LocalDate.now().format(DateTimeFormatter.ofPattern(dateformat, Locale.CHINA));
}
}
在@Value注入的变量所在类上添加注解@RefreshScope,当nacos 配置中心的配置发生更改,无需重启微服务,即可完成配置的热更新。
也可以使用 @ConfigurationProperties 注解加载配置文件,实现配置的热更新。
@Component
@Data
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
private String dateformat;
}
配置文件优先级
微服务在启动的时候,会从配置中心读取多个配置文件的配置信息。
一种是读取带环境的配置文件 prefix-spring.profile.active.file-extension
一种是读取不带环境的配置文件 prefix.file-extension
prefix.file-extension 的配置文件,用作配置多环境共享的配置信息。
如下:
在 userservice 的dev环境中,会同时加载以上两个配置文件。
如果一个配置信息在 本地 和 配置中心中都进行了配置。则配置信息的优先级如下:
nacos 配置持久化
使用 mysql 数据库做配置的持久化。
在mysql 中 初始化数据库:CREATE DATABASE nacos_config; USE nacos_config;
导入配置文件。配置文件在 nacos 的 conf 目录下。
导入后,在数据库中生成如下表。
修改nacos 配置文件,在配置文件中进行mysql 的配置。
#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=123456
重启 nacos ,新建配置文件。
然后打开数据库,查询 config_info 表的信息,就会发现新建的配置已经存储在数据库中。
nacos 集群部署
整体架构图
集群中有3个nacos节点,使用 nginx做反向代理和负载均衡 。同时使用 mysql 做配置的持久化。
步骤1:
配置mysql数据库,详见 nacos 配置持久化中的部分。
步骤2:
将cluster.conf.example 拷贝一份为 cluster.conf,在cluster.conf进行配置。
配置集群中 nacos节点的ip地址,这里使用本机启动三个不同的nacos节点。
#it is ip
127.0.0.1:8845
127.0.0.1:8846
127.0.0.1:8847
步骤3:
复制三份 nacos 目录,命名为 nacos1,nacos2,nacos3。
分别修改配置文件中nacos的端口。
### Default web server port:
server.port=8845
### Default web server port:
server.port=8846
### Default web server port:
server.port=8847
分别启动 3 个nacos节点。点击 bin 目录下的 startup.cmd。
步骤4:
配置 nginx,在nginx 的配置文件 nginx.conf 中做如下配置
upstream nacos-cluster {
server 127.0.0.1:8845;
server 127.0.0.1:8846;
server 127.0.0.1:8847;
}
server {
listen 80;
server_name localhost;
location /nacos {
proxy_pass http: //nacos-cluster;
}
}
然后启动 nginx ,访问 localhost/nacos,通过 nginx 反向代理,自动会在nacos集群中做负载均衡,访问其中一个nacos 节点。
步骤5:
修改项目配置文件,将nacos的地址 指定为 nginx 反向代理的地址 localhost:80。
spring:
application:
name : userservice
profiles:
active: dev #坏境
cloud :
nacos:
server-addr: localhost:80 # nacos地址
config:
file-extension: yaml #文件后缀名