概述
Nacos 是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台(注册中心+ 配置中心 + 总线)。
Nacos 是 Naming 、Configuration、Service 这三个单词拼凑而来。
官网:https://github.com/alibaba/Nacos
https://nacos.io/zh-cn/
安装下载
下载地址: https://github.com/alibaba/nacos/releases/tag/2.2.1
注意:2.2.1 以后需要 将 Nacos/conf/application.properties 文件添加默认 key,指定规则:自定义密钥时,推荐将配置项设置为**Base64编码 **的字符串,且原始密钥长度不得低于32字符。
使用单机模式启动
bin/startup.sh -m standalone
看到如下界面表示启动成功。
通过下边的网址登录管理界面:http://192.168.3.104:8848/nacos/index.html
默认账号密码均为 :nacos
服务注册
官网:https://spring.io/
服务提供者
新增 mvn 依赖
<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>
<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
配置信息
spring:
application:
# 微服务名称
name: nacos-payment-provider
cloud:
nacos:
# 服务注册地址
discovery:
server-addr: localhost:8848 #配置Nacos地址
management:
endpoints:
web:
exposure:
include: '*'
服务启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
// 发现服务
@EnableDiscoveryClient
public class PaymentMain9001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain9001.class, args);
}
}
服务消费者
Nacos 支持负载均衡。Nacos 自带 ribbon,ribbon 是做负载均衡的 jar 包。
新增 mvn 依赖
<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
配置信息
server:
port: 83
spring:
application:
name: nacos-order-consumer
cloud:
nacos:
discovery:
server-addr: 192.168.3.104:8848
#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
nacos-user-service: http://nacos-payment-provider
服务启动类
@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerMain83 {
public static void main(String[] args) {
SpringApplication.run(ConsumerMain83.class, args);
}
}
配置类
@Configuration
public class ApplicationContextBean {
@Bean
// 负载均衡(必须)
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
Controller
@RestController
public class ConsumerController {
@Value("${service-url.nacos-user-service}")
private String serverUrl;
@Resource
private RestTemplate restTemplate;
@GetMapping(value = "/consumer/nacos/{id}")
public String get(@PathVariable("id") int id) {
return restTemplate.getForObject(serverUrl + "/payment/nacos/" + id, String.class);
}
}
注册中心对比
Nacos | Eureka | Consul | CoreDNS | Zookeeper | |
---|---|---|---|---|---|
一致性协议 | CP + AP | AP | CP | / | CP |
健康检查 | TCP/HTTP/MySQL/Client Beat | Client Beat | TCP/HTTP/GRPC/Cmd | / | Client Beat |
负载均衡 | 权重/DSL/metadata/CMDB | Ribbon | Fabio | RR | / |
雪崩保护 | 支持 | 支持 | 不支持 | 不支持 | 不支持 |
自动注销实例 | 支持 | 支持 | 不支持 | 不支持 | 支持 |
访问协议 | HTTP/DNS/UDP | HTTP | HTTP/DNS | DNS | TCP |
监听支持 | 支持 | 支持 | 支持 | 不支持 | 支持 |
多数据中心 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
夸注册中心 | 支持 | 不支持 | 支持 | 不支持 | 不支持 |
SpringCloud 集成 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
Dubbo 集成 | 支持 | 不支持 | 不支持 | 不支持 | 支持 |
K8s 集成 | 支持 | 不支持 | 支持 | 支持 | 不支持 |
Nacos 支持 AP 和 CP 模式的切换。
- C - Consistent,一致性:
all nodes see the same data at the same time
,即所有节点在同一时间的数据完全一致。 - A - Availability,可用性:
Reads and writes always succeed
,即服务在正常响应时间内一直可用。 - P - Partition tolerance,分区容忍性:
the system continues to operate despite arbitrary message loss or failure of part of the system
。即分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性或可用性的服务。
如果不需要存储服务级别的信息且服务实例是通过 nacos-client 注册,并能够保持心跳上报,那么就可以选择 AP 模式。当前主流的服务如:Spring cloud 和 Dubbo 服务,都适用于 AP 模式,AP 模式为了服务的可能性而减弱了一致性,因此 AP 模式下值支持注册临时实例。
如果需要在服务级别编辑或者存储配置信息,那么 PC 是必须,K8S 服务和 DNS 服务则适用于 PC 模式。
CP 模式下则支持注册持久化实例,此时则是使用以 Raft 协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会报错。
curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
配置中心
项目搭建
新增 mvn 依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
Nacos 同 Springcloud-config 一样,在项目初始化时,先从配置中心进行配置拉去,再去启动项目。
SpringBoot 中配置文件的加载优先级:bootstrap 优先级高于 application
bootstrap.yml
# nacos配置
server:
port: 3377
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: 192.168.3.104:8848 #Nacos服务注册中心地址
config:
server-addr: 192.168.3.104:8848 #Nacos作为配置中心地址
file-extension: yaml #指定yaml格式的配置
application.yml
spring:
profiles:
active: dev # 表示开发环境
服务启动类
@EnableDiscoveryClient
@SpringBootApplication
public class NacosConfigClientMain3377 {
public static void main(String[] args) {
SpringApplication.run(NacosConfigClientMain3377.class, args);
}
}
业务类
@RestController
@RefreshScope // 支持 Nacos 的动态刷新
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/config/info")
public String getConfigInfo() {
return configInfo;
}
}
数据配置
dataId
的完整格式如下
${prefix}-${spring.profiles.active}.${file-extension}
- prefix:默认为
spring.application.name
的值,也可以通过配置项spring.cloud.nacos.config.prefix
来配置。 - spring.profiles.active:即为当前环境对应的 profile。
- file-extension:为配置内容的数据格式,可以通过配置项
spring.cloud.nacos.config.file-extension
来配置。目前只支持properties
和yaml
类型。
例子:根据下边的 yaml 文件的内容,对应的 dataId = nacos-config-client-dev.yaml
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: 192.168.3.104:8848 #Nacos服务注册中心地址
config:
server-addr: 192.168.3.104:8848 #Nacos作为配置中心地址
file-extension: yaml #指定yaml格式的配置
spring:
profiles:
active: dev # 表示开发环境
新增一条测试数据
动态更新
在 nacos 中修改配置数据,线上立即收到最新的数据。
分类配置
问题
实际开发过程中,通常一个系统有多个环境:
- dev 开发环境
- rc 准生产环境
- prod 生产环境
如何保证不同的环境读取不同的配置数据呢?
通过 Namespace、Group、DataID 实现配置数据的隔离。
类似 Java 里面的 package 名。
namespace 用于区分部署环境,Group 和 DataID 逻辑上区分不同的目标对象。
默认情况:NameSpace = public,Group = DEFAULT_GROUP、默认 Cluster 是 DEFAULTGroup 可以把不同的微服务划分到同一个分组里。
方案一:DataID
Namespace、Group 使用默认值,不同环境使用不同的 DataID 来区分不同的环境。
不同开发环境加载不同的 yaml 文件
spring:
profiles:
active: rc # 表示开发环境
方案二:Group
Namespace 使用默认值,DataID 相同,不同环境使用不同的 Group 来区分不同的环境。
需要再 spring.cloud.nacos.config
下配置 group
方案三:Namespace
新增不同的 Namespace,将命名空间 ID 配置到项目中 yaml 中。
需要再 spring.cloud.nacos.config
下配置 namespace
Nacos 集群
默认 Nacos 使用嵌入式数据库(derby)实现数据存储。如果启动多个默认配置下的 Nacos 节点,数据存储是存在一致性的问题。
为了解决这个问题,Nacos 采用了集中式存储的方式来支持集群化部署,支持 MySQL 的存储。
Nacos 支持三种部署模式
- 单机模式:用于测试和单机试用。
- 集群模式:用于生产环境,确保高可用。
- 多集群模式:用于多数据中心场景。
配置 MySQL
创建数据库
create database nacos_config;
use nacos_config;
创建表:nacos/conf/mysql-schema.sql
修改 Nacos 配置 nacos/conf/application.properties
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 中添加的配置数据就保存在我们自己的 MySQL 数据库中了。
配置 Nacos 集群
配置集群 IP :nacos/conf/cluster.conf
192.168.3.104:3333
192.168.3.104:4444
192.168.3.104:5555
拷贝出三份 nacos 文件:
分别修改启动的端口: conf/application.properties
最后逐一启动
bin/startup.sh
配置 Nginx
修改 /usr/local/etc/nginx/nginx.conf
文件
启动 Nginx
./nginx -c /usr/local/etc/nginx/nginx.conf
修改服务yaml 中配置的 nacos 地址为 nginx 的地址
通过 nginx 地址访问 nacos
小结
上述 nacos 集群的架构图