什么是 Nacos?官方直通车
Nacos集成
一、Nacos 服务搭建
1.1 环境准备
- 腾讯云 Linux centos 7.5 64位
- 本地windows 64 bit JDK 1.8;
- 本地 Maven 3.6.3;
1.2 下载安装
- 下载源码并打包源码包(PS,也可以直接下载源码包)
git clone https://github.com/alibaba/nacos.git
cd nacos/
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
ls -al distribution/target/
- 上传源码包并解压缩到云服务器
tar -xvf nacos-server-$version.tar.gz
1.3 运行 nacos server
Nacos支持三种运行模式:
- 单机模式:用于测试和单机试用
- 集群模式:用于生产环境,确保高可用
- 多集群模式:用于多数据中心场景
单机模式
cd nacos/bin
[root@VM-0-5-centos bin]# ll
total 32
-rw-r--r-- 1 root root 720 Sep 20 20:35 derby.log
drwxr-xr-x 2 root root 4096 Sep 22 19:04 logs
-rwxr-xr-x 1 root root 978 Sep 20 15:16 shutdown.cmd
-rwxr-xr-x 1 root root 979 Sep 20 15:16 shutdown.sh
-rwxr-xr-x 1 root root 3535 Sep 20 15:16 startup.cmd
-rwxr-xr-x 1 root root 5028 Sep 20 20:07 startup.sh
drwxr-xr-x 3 root root 4096 Sep 20 20:08 work
启动命令(standalone代表着单机模式运行,非集群模式):
sh startup.sh -m standalone
ps:
1. 首次启动可能存在sh权限问题,需要对sh进行赋权
chmod +x startup.sh
2. 首次启动可能报.sh line 2 :$'\r': command not found
原因是 windows 下的换行符是 \r\n,而 linux 下的换行符是 \n
解决方案:
# 安装 dos2unix
yum install dos2unix -y
# 执行命令
dos2unix startup.sh
# 关闭页面,后台运行
./startBatch.sh &
单机模式支持mysql
nacos 0.7 以后支持mysql数据源:
- 安装mysql 5.6.5+
- 创建nacos database, 初始化nacos-mysql.sql
- 修改conf/application.properties文件,增加支持mysql数据源配置(目前只支持mysql),添加mysql数据源的url、用户名和密码。
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=root
db.password=root
再以单机模式启动nacos,nacos所有写嵌入式数据库的数据都写到了mysql。
访问nacos控制台
遇到的坑,在首次启动后台服务器报错:jmenv.tbsite.net
aused by: com.alibaba.nacos.api.exception.NacosException: java.net.UnknownHostException: jmenv.tbsite.net
at com.alibaba.nacos.core.cluster.lookup.AddressServerMemberLookup.run(AddressServerMemberLookup.java:110)
at com.alibaba.nacos.core.cluster.lookup.AddressServerMemberLookup.start(AddressServerMemberLookup.java:66)
at com.alibaba.nacos.core.cluster.ServerMemberManager.initAndStartLookup(ServerMemberManager.java:156)
at com.alibaba.nacos.core.cluster.ServerMemberManager.init(ServerMemberManager.java:144)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:363)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:307)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136)
... 111 common frames omitted
解决办法是,conf中只给了一个cluster.conf.example文件,需要copy成一个cluster.conf即可。
集群模式
多集群模式
二、Spring Cloud nacos注册中心和配置中心集成
- 通过 Nacos Server 和 spring-cloud-starter-alibaba-nacos-discovery 实现服务的注册与发现。
- 通过 Nacos Server 和 spring-cloud-starter-alibaba-nacos-config 实现配置的动态管理。
Spring Cloud可以实现零代码切换到Nacos注册中心,只需要引入nacos依赖并增加配置nacos注册中心。
版本说明:
2.2.9.RELEASE
Hoxton.SR8
2.2.3.RELEASE
截止2020.09.22 spring-cloud-alibaba 仅支持Spring Boot 2.2.x
2.1 Nacos 快速集成
- 引入Nacos client 依赖
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
- 通过Spring Cloud 原生注解开启注册服务以及自动刷新配置功能
package com.qt.mall;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@RefreshScope
@SpringBootApplication
public class NacosServiceApplication {
public static void main(String[] args) {
SpringApplication.run(NacosServiceApplication.class, args);
}
}
- 在配置中增加nacos地址、注册应用名称、配置中心配置
bootstrap.yml
# mvn 命令启动添加--spring.profiles.active=test
spring:
application:
name: nacos-service
profiles:
active: dev
bootstrap-dev.yml
spring:
main:
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
server-addr: 120.53.121.130
namespace: 180d5ec1-9253-4c55-a018-e27e609b83f3
#ip: 192.168.128.41
config:
server-addr: 120.53.121.130
file-extension: yml
group: nacos-service
namespace: 180d5ec1-9253-4c55-a018-e27e609b83f3
-
登录nacos控制台,增加配置
-
启动服务,验证注册服务和配置中心结果
2.2 配置说明
nacos除了核心注册中心、配置中心连接配置外,可以实现代码零配置解决方案。
nacos动态配置服务可以让系统以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。
- spring.application.name:注册服务名称,也是构成 Nacos 配置管理 dataId字段的一部分。
# 在 Nacos Spring Cloud 中,dataId 的完整格式如下:
${prefix}-${spring.profiles.active}.${file-extension}
prefix
默认为spring.application.name
的值,也可以通过配置项spring.cloud.nacos.config.prefix
来配置。spring.profiles.active
即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 注意:当spring.profiles.active
为空时,对应的连接符-
也将不存在,dataId 的拼接格式变成${prefix}.${file-extension}
file-exetension
为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension
来配置。目前只支持properties
和yaml
类型。
2.3 Nacos数据隔离模式
Nacos提供四层的数据隔离模式:
- Company:用户账号对应的可能是一个企业或者独立的个体,这个数据一般情况下不会透传到服务注册中心。
- Namespace: 一个用户账号可以新建多个命名空间,每个命名空间对应一个客户端实例,这个命名空间对应的注册中心物理集群是可以根据规则进行路由的,这样可以让注册中心内部的升级和迁移对用户是无感知的,同时可以根据用户的级别,为用户提供不同服务级别的物理集群。Namespace常用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
- Group:Nacos 中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串(如 Buy 或 Trade )对配置集进行分组,从而区分 Data ID 相同的配置集。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如 database_url 配置和 MQ_topic 配置。
- Service:服务是指一个或一组软件功能(例如特定信息的检索或一组操作的执行),其目的是不同的客户端可以为不同的目的重用(例如通过跨进程的网络调用)。Nacos 支持主流的服务生态,如 Kubernetes Service、gRPC|Dubbo RPC Service 或者 Spring Cloud RESTful Service.
三、高级应用
3.1 基于Namespace命名空间的资源隔离
根据Nacos不同的Namespace下,可以存在相同的 Group 或 Data ID 的配置的数据隔离特性,我们可以很好的实现同一Nacos Server集群统一管理项目不同环境的资源(注册服务实例、配置等)
-
定义各个环境命名空间
-
多环境配置支持
基于spring.profile.active,增加应用的多环境配置支持,不同环境配置对应的Nacos命名空间,根据应用启动的环境变量参数自动识别对应的Nacos配置
# dev配置
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.128.20
namespace: 1c53b59e-9f3d-44a4-b2d7-5faaea25b3c6 # dev 环境的命名空间
ip: 192.168.128.20
config:
server-addr: 192.168.128.20
file-extension: yml
group: ds-user-center-server
namespace: 1c53b59e-9f3d-44a4-b2d7-5faaea25b3c6 # dev 环境的命名空间
shared-configs:
- data-id: mqclient-config-share.yml
group: MQCLIENT_GROUP
refresh: true
extension-configs:
- data-id: global-public-share.yml
group: share
refresh: true
- data-id: resource-service-public-share.yml
group: share
refresh: true
test、qa、prod配置类似。
3.2 Nacos自定义配置
Nacos除了支持file-extension模式的data-id.yml或data-id.properties的配置外, 自0.2.1版本以后还支持自定义的data-id的配置。目前主要支持shared-configs模式和extension-configs模式,配置示例:
shared-configs:
- data-id: mqclient-config-share.yml
group: MQCLIENT_GROUP
refresh: true
extension-configs:
- data-id: global-public-share.yml
group: share
refresh: true
- data-id: resource-service-public-share.yml
group: share
refresh: true
3.2.1 配置优先级
综上,Spring Cloud Alibaba Nacos Config 提供了三种配置能力从 Nacos 拉取相关的配置。
A: 通过 spring.cloud.nacos.config.shared-configs[n].data-id 支持多个共享 Data Id 的配置
B: 通过 spring.cloud.nacos.config.extension-configs[n].data-id 的方式支持多个扩展 Data Id 的配置
C: 通过内部相关规则(应用名、应用名+ Profile )自动生成相关的 Data Id 配置
当三种方式共同使用时,他们的一个优先级关系是:A < B < C
Nacos-config
3.3 Nacos配置灰度发布
Nacos 1.1.0版本以后,支持灰度配置。Nacos配置的灰度发布是基于Nacos配置中心Beta发布功能进行实现,默认不勾选该功能。
灰度配置流程如下:
- 预备同一应用两个节点:
192.168.132.49
192.168.128.20
- 在Nacos配置中心执行Beta发布,指定只发布到49节点机器,将配置suffixurl 和 shortSuffixurl
suffixurl: http://%s.myyshop-dev01.com
shortSuffixurl: all.myyshop-dev01.com
查看日志,可以验证到49机器配置发布生效:
而20机器,无任何反应,说明配置未发布到20:
进一步通过接口验证灰度发布是否生效,可以看到49发布的配置已经生效,而20机器接口仍是灰度发布前配置内容。
灰度验证通过后,关闭灰度,将配置正式发布,再次验证20机器接口,可以发现配置也生效
3.4 基于Nacos元数据实现Spring Cloud 微服务灰度发布实践
应用迭代过程中会不断有新版本API发布,在新版本正式发布前,可以使用灰度流量控制先进行小规模验证,将升级带来的影响限定在指定的用户范围内可以最大程度上保障线上业务的稳定运行,通过收集使用体验的数据,对应用新版本的功能、性能、稳定性等指标进行评判,然后再全量升级。
这里主要参考了Nepxion 灰度框架。
3.4.1 调用链分析
外部调用
web请求 ==> Gateway ==> 服务
GateWay 转发请求时,会根据Ribbon(目前采用轮询策略)从服务实例选择对应服务进行转发
内部调用
请求 ==> Feign调用==> 服务
目前内部服务间调用没有经过网关,而是直接根据Ribbon(目前采用轮询策略)从服务实例选择对应服务进行接口调用。
3.4.2 预备知识
Nacos元数据
Nacos数据(如配置和服务)描述信息,如服务版本、权重、容灾策略、负载均衡策略、鉴权配置、各种自定义标签 (label),从作用范围来看,分为服务级别的元信息、集群的元信息及实例的元信息。
设置Nacos元数据
# Nacos config for qt
spring.cloud.nacos.discovery.metadata.group=qt-service-group #定义所属组,也可以通过服务名前缀来自动产生服务组名
spring.cloud.nacos.discovery.metadata.version=1.0 #定义版本号 也可以通过Git插件方式自动产生版本号
spring.cloud.nacos.discovery.metadata.region=dev 定义区域
spring.cloud.nacos.discovery.metadata.env=env1 定义环境
spring.cloud.nacos.discovery.metadata.zone=zone1 #定义所属可用区
3.4.3 实现方案
实现思路
- 根据应用注册的实例元数据来实现灰度,比如选择version来标记灰度版本:
spring.cloud.nacos.discovery.metadata.version=1.1
- 基于网关为灰度触点,自定义Gate Way Filter, 实现从Spring Cloud Gateway发起的调用都走版本为x.x的服务或者Spring Cloud Gateway发起的调用按照配置的的灰度策略,如A:1.1 ==> 网关 B:1.2 ==> 网关==>C:1.3。
- 基于Ribbon权重负责均衡,实现从Spring Cloud Gateway发起的调用1.0版本流量调用为90%,1.1流量调用为10%
元数据动态指定
外部系统(例如:运维发布平台)在远程启动微服务的时候,可以通过参数传递来动态改变元数据或者增加运维特色的参数,最后注册到远程配置中心。有如下两种方式
- 通过Program arguments来传递,它的用法是前面加“--”,支持Nacos的增量覆盖。例如:
mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=1100 --spring.cloud.nacos.discovery.metadata.version=1.0"
- 通过VM arguments来传递,它的用法是前面加“-D”。推荐使用该方式。例如:-Dmetadata.version=1.0
- 两种方式尽量避免同时用
实现流程
实现场景
通过外部参数动态指定A、B、C服务灰度版本为2.0。
基于Header传递的灰度路由模式,通过http工具,传递Http Header,比如version=2.0,网关根据header动态路由到灰度服务,而不带header的依旧请求到初始版本。
前后端灰度,当前端(例如:APP)和后端微服务同时存在多个版本时,可以采用“前端灰度&网关灰度路由组合式策略”,前端调用网关时,传入前端app版本号,网关根据路由策略,路由要相关的灰度服务。
- APP v1.0 -> 网关 -> A服务 v1.0 -> B服务 v1.0
- APP v1.1 -> 网关 -> A服务 v1.1 -> B服务 v1.1
- 基于Nacos配置中心的全局订阅的灰度策略,基于header的灰度策略,在全链路下,实现可能比较复杂,Nacos全局订阅实现方式提供了简单的方式规避了header传递。
3.4.4 主要的功能点
- Nacos服务实例元数据相关,支持从外部参数动态获取元数据。
- 自定义网关Filter,实现请求header侦测,灰度路由解析、灰度动态路由等功能
- 自定义Ribbon负载均衡策略,实现灰度流量控制策略