Nacos
# Nacos
**官网:**https://nacos.io/zh-cn/
# 1. 简介
Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
# 2. 安装
- 64 bit OS,支持 Linux/Unix/Mac/Windows,推荐选用 Linux/Unix/Mac。
- 64 bit JDK 1.8+;下载 (opens new window) & 配置 (opens new window)。
- Maven 3.2.x+;下载 (opens new window) & 配置 (opens new window)。
# 2.1 Windows上安装
下载https://github.com/alibaba/nacos/releases
解压
进入bin目录执行
startup.cmd -m standalone
1访问http://IP:8848/nacos/
默认账号:nacos/nacos
# 2.2 Linux上安装
下面有讲到
# 3. 服务注册
创建SpringBoot父工程
SpringCloud2022
父工程添加相关依赖
对应依赖版本关系可以参考官网:https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
<?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> <groupId>top.damoncai</groupId> <artifactId>SpringCloud2022</artifactId> <version>1.0-SNAPSHOT</version> <properties> <java.version>1.8</java.version> <spring-cloud-alibaba-version>2.2.5.RELEASE</spring-cloud-alibaba-version> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.13.RELEASE</version> <relativePath/> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba-version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50创建子工程
nacos-9001
子工程添加依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies>
1
2
3
4
5
6
7
8
9
10YML
server: port: 9001 spring: application: name: nacos-provider cloud: nacos: discovery: server-addr: 127.0.0.1:8848 management: endpoint: web: exposure: include:'*'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15启动类
@SpringBootApplication @EnableDiscoveryClient//加此注解 public class Nacos9001App { public static void main(String[] args) { SpringApplication.run(Nacos9001App.class, args); } }
1
2
3
4
5
6
7
8业务类
@RestController @RequestMapping("demo") public class DemoControl { @Value("${server.port}") private String serverPort; @GetMapping(value = "/test") public String getServerPort(){ return "Hello Nacos Discovery"+serverPort; } }
1
2
3
4
5
6
7
8
9
10
11
12启动服务
查看nacos
按照上面搭建一个9002工程
# 4. nacos 负载均衡
按照上面创建nacos-9003做为消费端
# 4.1 远程调用与Ribbon
它是一个基于HTTP和TCP客户端负载均衡器。它虽然只是一个工具类库,它却是每一个微服务的基础设施。因为实际上,对于服务间调用、API网关请求转发都需要经过Ribbon负载均衡来实现。总体来说,Ribbon的主要作用是:从注册服务器端拿到对应服务列表后以负载均衡的方式访问对应服务。
# 4.1.1 具体使用
现在如果我们需要远程访问那么可以使用RestTemplate,其中getForObject是最常用方法,同时还要在服务消费者中配置RestTemplate:
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
restTemplate.getForObject(arg1,arg2,arg3...);
2
3
4
5
6
7
第一个参数url表示被调用的目标Rest接口位置
第二个参数是返回值类型
- JavaBean类型或者JavaBean数组类型,如果控制器返回的是List集合,需要使用数组类型接收。
第三个参数是可变参数
- 是传递给url的动态参数,使用参数时候需要在url上需要使用{1}、{2}、{3}进行参数占位,这样传递的参数就会自动替换占位符。
测试代码
消费者服务中编写
@GetMapping(value = "/test")
public String getServerPort(){
String res = restTemplate.getForObject("http://nacos-provider/demo/test", String.class);
return res;
}
2
3
4
5
启动消费者
多次调用服务
返现返回信息是相互交替
# 5. nacos和其他注册中心对比
服务注册与发现框架 | CAP模型 | 控制台管理 | 社区活跃度 |
---|---|---|---|
Eureka | AP | 支持 | 低(2.x版本闭源) |
Zookeeper | CP | 不支持 | 中 |
Consul | CP | 支持 | 高 |
Nacos | AP/CP | 支持 | 高 |
# 5.1 CAP模型
计算机专家 埃里克·布鲁尔(Eric Brewer)于 2000 年在 ACM 分布式计算机原理专题讨论会(简称:PODC)中提出的分布式系统设计要考虑的三个核心要素:
- 一致性(Consistency):同一时刻的同一请求的实例返回的结果相同,所有的数据要求具有强一致性(Strong Consistency)
- 可用性(Availability):所有实例的读写请求在一定时间内可以得到正确的响应
- 分区容错性(Partition tolerance):在网络异常(光缆断裂、设备故障、宕机)的情况下,系统仍能提供正常的服务
以上三个特点就是CAP原则(又称CAP定理),但是三个特性不可能同时满足,所以分布式系统设计要考虑的是在满足P(分区容错性)的前提下选择C(一致性)还是A(可用性),即:CP或AP
# 5.2 CP原则:一致性 + 分区容错性原则
CP 原则属于强一致性原则,要求所有节点可以查询的数据随时都要保持一直(同步中的数据不可查询),即:若干个节点形成一个逻辑的共享区域,某一个节点更新的数据都会立即同步到其他数据节点之中,当数据同步完成后才能返回成功的结果,但是在实际的运行过程中网络故障在所难免,如果此时若干个服务节点之间无法通讯时就会出现错误,从而牺牲了以可用性原则(A),例如关系型数据库中的事务。
# 5.3 AP原则:可用性原则 + 分区容错性原则
AP原则属于弱一致性原则,在集群中只要有存活的节点那么所发送来的所有请求都可以得到正确的响应,在进行数据同步处理操作中即便某些节点没有成功的实现数据同步也返回成功,这样就牺牲一致性原则(C 原则)。
使用场景:对于数据的同步一定会发出指令,但是最终的节点是否真的实现了同步,并不保证,可是却可以及时的得到数据更新成功的响应,可以应用在网络环境不是很好的场景中。
# 5.4 Nacos支持CP和AP
Nacos无缝支持一些主流的开源生态,同时再阿里进行Nacos设计的时候重复的考虑到了市场化的运作(市面上大多都是以单一的实现形式为主,例如:Zookeeper使用的是 CP、而 Eureka采用的是AP),在Nacos中提供了两种模式的动态切换。
# 5.5 Nacos 何时选择切换模式
一般来说,如果不需要储存服务界别的信息且服务实例通过nacos-client注册,并能够保持心跳上报,那么就可以选择AP模式。如Spring Cloud 和 Dubbo,都适用于AP模式,AP模式为了服务的可用性减弱了一致性,因此AP模式下只支持注册临时实例。
如果需要在服务级别编辑或者储存配置信息,那么CP是必须的,K8S服务和DNS服务则是用于CP模式。CP模式下则支持注册持久化实例,此时则是以Raft协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。
切换命令(默认是AP):
curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
1
注意:临时和持久化的区别主要在健康检查失败后的表现,持久化实例健康检查失败后会被标记成不健康,而临时实例会直接从列表中被删除。
# 6. 配置中心
Nacos不仅仅可以作为注册中心来使用,同时它支持作为配置中心
创建 nacos-config-3377工程
在上面的依赖上额外添加配置依赖
<dependency> <groupId> com.alibaba.cloud </groupId> <artifactId> spring-cloud-starter-alibaba-nacos-config </artifactId> </dependency>
1
2
3
4YML配置
创建bootstrap.yml
# nacos配置 server: port: 3377 spring: application: name: nacos-config-client cloud: nacos: discovery: server-addr: localhost:8848 #Nacos服务注册中心地址 config: server-addr: localhost:8848 #Nacos作为配置中心地址 file-extension: yaml #指定yaml格式的配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14application.yml
spring: profiles: active: dev # 表示开发环境
1
2
3
主启动
@SpringBootApplication @EnableDiscoveryClient public class Nacosconfig3377 { public static void main(String[] args) { SpringApplication.run(Nacosconfig3377.class, args); } }
1
2
3
4
5
6
7
8业务类
这里的@RefreshScope实现配置自动更新,意思为如果想要使配置文件中的配置修改后不用重启项目即生效,可以使用@RefreshScope配置来实现
@RestController @RefreshScope //支持Nacos的动态刷新功能 public class DemoController { @Value("${config.info}") private String configInfo; @GetMapping("/config/info") public String getConfigInfo(){ return configInfo; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
6.1 Nacos配置规则
在 Nacos Spring Cloud 中,dataId
的完整格式如下(详情可以参考官网 https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html):
${prefix}-${spring.profiles.active}.${file-extension}
prefix
默认为spring.application.name
的值,也可以通过配置项spring.cloud.nacos.config.prefix
来配置spring.profiles.active
即为当前环境对应的 profile,注意:当spring.profiles.active
为空时,对应的连接符-
也将不存在,dataId 的拼接格式变成${prefix}.${file-extension}
(不能删除)file-exetension
为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension
来配置。目前只支持properties
和yaml
类型。通过 Spring Cloud 原生注解
@RefreshScope
实现配置自动更新:所以根据官方给出的规则我们最终需要在Nacos配置中心添加的配置文件的名字规则和名字为:
# ${spring.application.name}-${spring.profiles.active}.${file-extension} # nacos-config-client-dev.yaml # 微服务名称-当前环境-文件格式
1
2
3
nacos上创建配置文件
启动服务调用接口
将nacos中配置文件版本改为2,在访问
# 7. Namespcae、分组和DataID关系
# 7.1 名词解释
命名空间(Namespace)
用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
配置分组(Group)
Nacos 中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串(如 Buy 或 Trade )对配置集进行分组,从而区分 Data ID 相同的配置集。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如 database_url 配置和 MQ_topic 配置。
配置集 ID(Data ID)
Nacos 中的某个配置集的 ID。配置集 ID 是组织划分配置的维度之一。Data ID 通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。Data ID 通常采用类 Java 包(如 com.taobao.tc.refund.log.level)的命名规则保证全局唯一性。此命名规则非强制。
配置集:一组相关或者不相关的配置项的集合称为配置集。在系统中,一个配置文件通常就是一个配置集,包含了系统各个方面的配置。例如,一个配置集可能包含了数据源、线程池、日志级别等配置项。
# 7.2 三者关系
默认情况
Namespace=public,Group=DEFAULT_GROUP,默认Cluster是DEFAULT
具体情况
Nacos默认的命名空间是public,我们就可以利用Namespace来实现隔离,比如我们现在有三个环境:开发、测试、生产环境,我们就可以创建三个Namespace,不同的Namespace之间是隔离的。
Group本身就是分组的意思,它可以把不同的微服务划分到同一个分组里面去。
剩下的就是具体微服务,一个Service可以包含多个Cluster,Nacos默认Cluster是DEFAULT,Cluster是对指定微服务的一个虚拟划分。比如说,将一个Service部署在北京和和杭州的机房中,北京机房的Service就可以起名为(BJ),杭州机房中的Service就可以起名为(HZ),这样就可以尽量让同一个机房的微服务互相调用,提升性能。
# 8. nacos数据derby切换为mysql
Nacos默认自带嵌入式数据库derby,所以我们每次创建一个Nacos实例就会有一个derby,当有多个Nacos节点的时候,就会出现一致性问题,所以Nacos支持了外部数据库统一数据管理MySql。
在MySQL中创建对应的数据库
nacos_config
导入sql文件
修改conf/application.properties文件,增加支持mysql数据源配置(目前只支持mysql),添加mysql数据源的url、用户名和密码。
spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&serverTimezone=UTC db.user=root db.password=root
1
2
3
4
5
6测试
- nacos中添加配置文件
- 在数据库中查看相关表数据
# 9. 集群配置
# 9.1 Nacos支持三种部署模式
- 单机模式 - 用于测试和单机试用
- 集群模式 - 用于生产环境,确保高可用
- 多集群模式 - 用于多数据中心场景
# 9.2 集群部署说明
参考网站:https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html
架构图:部署生产使用的集群模式
具体拆分
# 9.3 linux上nacos集群部署
官网压缩包下载
解压
将数据持久化切换为MySQL,上面有讲到
注意application.properties中的端口,会设置三个节点需要不能重复
修改
cluster.conf
,这里存放着集群各个节点的ip和端口192.168.220.201:8848 192.168.220.201:8868 192.168.220.201:8888
1
2
3将nacos复制三分,需要注意的是端口需要和上面集群配置的端口一样
启动
sh startup.sh //启动命令
1
# 9.4 Nginx实现负载均衡
安装nginx
下载依赖http://nginx.org/en/download.html
解压
编译安装
./configure --with-stream make & make install
1
2修改nginx.cnf
worker_processes 1; events { worker_connections 1024; } stream { upstream nacos { server 192.168.100.101:8848; server 192.168.100.101:8868; server 192.168.100.101:8888; } server { listen 81; proxy_pass nacos; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19运行
./nginx
1
方位
# 9.5 测试服务注册
将之前微服务注册地址改为http://192.168.100.101:81
server:
port: 9001
spring:
application:
name: nacos-provider
cloud:
nacos:
discovery:
server-addr: http://192.168.100.101:81
management:
endpoint:
web:
exposure:
include:'*'
2
3
4
5
6
7
8
9
10
11
12
13
14
15