Nacos介绍
Nacos (Dynamic Naming and Configuration Service)是阿里巴巴开源的一个针对微服务架构中服务发现、配置管理和服务管理平台。
Nacos就是注册中心 + 配置中心的组合(Nacos = Eureka + Config + Bus)。官网:https://nacos.io 。下载地址:https://github.com/alibaba/Nacos。
Nacos功能特性有以下几点:
- 服务发现与健康检查
- 动态配置管理
- 动态DNS服务
- 服务和元数据管理(管理平台的⻆度,nacos也有一个ui⻚面,可以看到注册的服务及其实例信息(元数据信息)等),动态的服务权重调整、动态服务优雅下线,都可以去做
Nacos Server单例服务部署
下载解压安装包,执行命令启动(我们使用最近比较稳定的版本 nacos-server-1.4.2.tar.gz)
linux/mac:sh startup.sh -m standalone
windows:cmd startup.cmd
访问Nacos管理界面:http://127.0.0.1:8848/nacos/#/login(默认端口8848, 账号和密码 nacos/nacos)。
Nacos Server集群
Nacos Server集群我们要安装3个及以上的实例。首先,我们复制解压后的nacos文件夹,分别命名为nacos-01、nacos-02、nacos-03。
我们使用同一台机器模拟,将上述三个文件夹中application.properties中的 server.port分别改为 8848、8849、8850,同时给当前实例节点绑定ip,因为服务器可能绑定多个ip:
nacos.inetutils.ip-address=127.0.0.1
接下来,我们复制一份conf/cluster.conf.example文件,命名为cluster.conf。在配置文件中设置集群中每一个节点的信息:
# 集群节点配置
127.0.0.1:8848
127.0.0.1:8849
127.0.0.1:8850
最后,我们使用脚本启动每一个实例即可。需要注意的是:默认每一个Nacos Server需要至少2G的内存,生产环境下适当调整该参数。
sh startup.sh -m cluster
Nacos Server数据持久化
Nacos 默认使用嵌入式数据库进行数据存储,它支持改为外部Mysql存储:
- 新建数据库 nacos_config,数据库初始化脚本文件。文件位置在 ${nacoshome}/conf/nacos-mysql.sql
- 修改${nacoshome}/conf/application.properties,增加Mysql数据源配置如下
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
db.user=root
db.password=123456
Nacos 数据模型
Namespace命名空间、Group分组、集群这些都是为了进行归类管理,把服务和配置文件进行归类,归类之后就可以实现一定的效果,比如隔离。
举例来说,对于服务来说,不同命名空间中的服务不能够互相访问调用。
- Namespace:命名空间,对不同的环境进行隔离,比如隔离开发环境、测试环境和生产环境
- Group:分组,将若干个服务或者若干个配置集归为一组,通常习惯一个系统归为一个组
- Service:某一个服务,比如简历微服务
- DataId:配置集或者可以认为是一个配置文件
Namespace + Group + Service 如同 Maven 中的GAV坐标,GAV坐标是为了锁定 Jar,而这里是为了锁定服务。
Namespace + Group + DataId 如同 Maven 中的GAV坐标,GAV坐标是为了锁定 Jar,二这里是为了锁定配置文件。
最佳实践
Nacos抽象出了Namespace、Group、Service、DataId等概念,具体代表什么取决 于怎么用(非常灵活),推荐用法如下:
概念 | 描述 |
Namespace | 代表不同的环境,如开发dev、测试test、生产环境prod |
Group | 代表某项目 |
Service | 某个项目中具体xxx服务 |
DataId | 某个项目中具体的xxx配置文件 |
服务注册到Nacos注册中心上
我们以网关服务为例,我们在spring-cloud-demo模块中添加SCA的依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--spring boot 父启动器依赖-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<groupId>com.rubin</groupId>
<artifactId>spring-cloud-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>scn</module>
<module>sca</module>
<module>gateway</module>
<module>stream</module>
<module>config-server</module>
<module>zipkin-server</module>
<module>authorization-server</module>
</modules>
<packaging>pom</packaging>
<dependencies>
<!--日志依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--lombok⼯具-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
<!-- Actuator可以帮助你监控和管理Spring Boot应⽤-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--SCA -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--SCA -->
</dependencies>
</dependencyManagement>
<build>
<plugins>
<!--编译插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
<!--打包插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
网关服务pom添加以下依赖(注释eureka客户端依赖):
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
修改配置文件如下:
server:
port: 9200
spring:
application:
name: gateway
rabbitmq:
host: rabbitmq-host
port: 5672
username: root
password: 123456
zipkin:
# zipkin-server的请求地址
base-url: http://zipkin-host:9500
sender:
# web 客户端将踪迹日志数据通过网络请求的方式传送到服务端,另外还有配置
# kafka/rabbit 客户端将踪迹日志数据传递到mq进行中转
type: web
sleuth:
sampler:
# 采样率 1 代表100%全部采集 ,默认0.1 代表10% 的请求踪迹数据会被采集
# 生产环境下,请求量非常大,没有必要所有请求的踪迹数据都采集分析,对于网络包括server端压力都是比较大的,可以配置采样率采集一定比例的请求的踪迹数据进行分析即可
probability: 1
cloud:
nacos:
discovery:
# 配置nacos server地址
server-addr: nacos-host:8848
# 不配置默认注册到public命名空间
namespace: 651d1e6f-4bf4-46b9-b5b0-1885a215dc12
gateway:
routes:
- id: service-resume-router
uri: lb://scn-service-resume
predicates:
- Path=/api-resume/**
filters:
- StripPrefix=1
- id: service-auto-deliver-router
uri: lb://scn-service-auto-deliver
predicates:
- Path=/api-auto-deliver/**
# 详情参考:https://docs.spring.io/spring-cloud-gateway/docs/2.2.10.BUILD-SNAPSHOT/reference/html/#configuring-route-predicate-factories-and-gateway-filter-factories
# 时间点后匹配
# - After=2017-01-20T17:42:47.789-07:00[America/Denver]
# 时间点前匹配
# - Before=2017-01-20T17:42:47.789-07:00[America/Denver]
# 时间区间匹配
# - Between=2017-01-20T17:42:47.789-07:00[America/Denver],2017-01-21T17:42:47.789-07:00[America/Denver]
# 指定Cookie正则匹配指定值
# - Cookie=chocolate, ch.p
# 指定Header正则匹配指定值
# - Header=X-Request-Id, \d+
# 请求Host匹配指定值
# - Host=**.somehost.org,**.anotherhost.org
# 请求Method匹配指定请求⽅式
# - Method=GET,POST
# 请求路径正则匹配
# - Path=/red/{segment},/blue/{segment}
# 请求包含某参数
# - Query=green
# 请求包含某参数并且参数值匹配正则表达式
# - Query=red, gree.
# 远程地址匹配
# - RemoteAddr=192.168.1.1/24
filters:
- StripPrefix=1 # 可以去掉api-auto-deliver之后转发 数字代表去掉几层
- RequestTime=true
# springboot中暴露健康检查等断点接⼝
management:
endpoints:
web:
exposure:
include: "*"
# 暴露健康接口的细节
endpoint:
health:
show-details: always
#分布式链路追踪
logging:
level:
org.springframework.web.servlet.DispatcherServlet: DEBUG
org.springframework.cloud.sleuth: DEBUG
重启服务,我们就会在控制台看到我们的服务已经注册到注册中心了。
在这里,我们重点讲解一下服务的一个重要的配置项:保护阈值。保护阈值可以设置为0-1之间的浮点数,它其实是一个比例值(当前服务健康实例 数/当前服务总实例数)。
一般流程下,Nacos是服务注册中心,服务消费者要从Nacos获取某一个服务的可用实例信息。对于服务实例有健康/不健康状态之分,Nacos在返回给消费者实例信息的时候,会返回健康实例。这个时候在一些高并发、大流量场景下会存在一定的问题:如果服务A有100个实例,98个实例都不健康了,只有2个实例是健康的,如果Nacos只返回这两个健康实例的信息的话,那么后续消费者的请求将全部被分配到这两个实例。一旦流量洪峰到来,2个健康的实例也扛不住了,整个服务A 就扛不住,上游的微服务也会导致崩溃,从而产生雪崩效应。
而保护阈值的意义在于:当服务A健康实例数/总实例数 < 保护阈值 的时候,说明健康实例真的不多了,这个时候保护阈值会被触发(状态true)。Nacos将会把该服务所有的实例信息(健康的 + 不健康的)全部提供给消费者,消费者可能访问到不健康的实例,请求失败,但这样也比造成雪崩要好,牺牲了一些请求,但保证了整个系统的一个可用。
Nacos配置中心
之前我们的配置中心使用的技术是:SpringCloud Config + Bus。这种方式还是有一定的不方便的:1、配置文件需要单独的地方存储(Git、SVN)2、刷新配置文件还要继承MQ中间件,增加了项目的部署成本。
我们使用Nacos作为配置中心就简单很多了,
Github不需要了(配置信息直接配置在Nacos server中),Bus也不需要了(依然可以完成动态刷新)。
我们再来改造一下我们的网关服务,在其pom中添加配置中心的依赖(注释掉原来的配置中心和Bus):
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
将bootstrap.yml的配置文件改成以下内容:
spring:
profiles:
active: nacos
新建bootstrap-nacos.yml,内容如下:
spring:
cloud:
nacos:
discovery:
# 配置nacos server地址
server-addr: nacos-host:8848
namespace: 651d1e6f-4bf4-46b9-b5b0-1885a215dc12
config:
server-addr: nacos-host:8848
namespace: 651d1e6f-4bf4-46b9-b5b0-1885a215dc12
prefix: gateway
group: DEFAULT_GROUP
file-extension: yaml
ext-config[0]:
data-id: zipkin-client.yaml
group: DEFAULT_GROUP
refresh: true
ext-config[1]:
data-id: actuator.yaml
group: DEFAULT_GROUP
refresh: true
ext-config[2]:
data-id: logging.yaml
group: DEFAULT_GROUP
refresh: true
我们在Nacos Server上新建了一个叫做rubin的命名空间,服务的注册于配置都在此命名空间上。那么,微服务中如何锁定 Nacos Server 中的配置文件(dataId)呢?微服务是通过 Namespace + Group + dataId 来锁定配置文件,Namespace不指定就默认public,Group不指定就默认 DEFAULT_GROUP。
dataId 的完整格式如下:
${prefix}-${spring.profile.active}.${file-extension}
prefix
默认为spring.application.name
的值,也可以通过配置项spring.cloud.nacos.config.prefix
来配置spring.profile.active
即为当前环境对应的profile
。注意:当spring.profile.active
为空时,对应的连接符 - 也将不存在,dataId
的拼接格式变成${prefix}.${file-extension}
file-exetension
为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension
来配置。目前只支持properties
和yaml
类型
所以,我们在rubin的命名空间下创建以下几个配置文件:
gateway-nacos.yaml:
server:
port: 9200
spring:
application:
name: gateway
cloud:
gateway:
routes:
- id: sca-service-resume-router
uri: lb://sca-service-resume
predicates:
- Path=/sca-api-resume/**
filters:
- StripPrefix=1
- id: sca-service-auto-deliver-router
uri: lb://sca-service-auto-deliver
predicates:
- Path=/sca-api-auto-deliver/**
filters:
- StripPrefix=1
- id: scn-service-resume-router
uri: lb://scn-service-resume
predicates:
- Path=/scn-api-resume/**
filters:
- StripPrefix=1
- id: scn-service-auto-deliver-router
uri: lb://scn-service-auto-deliver
predicates:
- Path=/scn-api-auto-deliver/**
# 详情参考:https://docs.spring.io/spring-cloud-gateway/docs/2.2.10.BUILD-SNAPSHOT/reference/html/#configuring-route-predicate-factories-and-gateway-filter-factories
# 时间点后匹配
# - After=2017-01-20T17:42:47.789-07:00[America/Denver]
# 时间点前匹配
# - Before=2017-01-20T17:42:47.789-07:00[America/Denver]
# 时间区间匹配
# - Between=2017-01-20T17:42:47.789-07:00[America/Denver],2017-01-21T17:42:47.789-07:00[America/Denver]
# 指定Cookie正则匹配指定值
# - Cookie=chocolate, ch.p
# 指定Header正则匹配指定值
# - Header=X-Request-Id, \d+
# 请求Host匹配指定值
# - Host=**.somehost.org,**.anotherhost.org
# 请求Method匹配指定请求⽅式
# - Method=GET,POST
# 请求路径正则匹配
# - Path=/red/{segment},/blue/{segment}
# 请求包含某参数
# - Query=green
# 请求包含某参数并且参数值匹配正则表达式
# - Query=red, gree.
# 远程地址匹配
# - RemoteAddr=192.168.1.1/24
filters:
- StripPrefix=1 # 可以去掉api-auto-deliver之后转发 数字代表去掉几层
- RequestTime=true
zipkin-client.yaml:
spring:
zipkin:
# zipkin-server的请求地址
base-url: http://zipkin-host:9500
sender:
# web 客户端将踪迹日志数据通过网络请求的方式传送到服务端,另外还有配置
# kafka/rabbit 客户端将踪迹日志数据传递到mq进行中转
type: web
sleuth:
sampler:
# 采样率 1 代表100%全部采集 ,默认0.1 代表10% 的请求踪迹数据会被采集
# 生产环境下,请求量非常大,没有必要所有请求的踪迹数据都采集分析,对于网络包括server端压力都是比较大的,可以配置采样率采集一定比例的请求的踪迹数据进行分析即可
probability: 0.1
actuator.yaml:
# springboot中暴露健康检查等断点接口
management:
endpoints:
web:
exposure:
include: "*"
# 暴露健康接口的细节
endpoint:
health:
show-details: always
logging.yaml:
#分布式链路追踪
logging:
level:
org.springframework.web.servlet.DispatcherServlet: DEBUG
org.springframework.cloud.sleuth: DEBUG
优先级:根据规则生成的dataId > 扩展的dataId(对于扩展的dataId,[n] n越大优 先级越高)。
至此,我们的Nacos相关内容就讲完了。欢迎小伙伴们积极留言交流~~~
文章评论