Nacos 学习文档

内容由ChatGPT-3.5 生成

简介

Nacos 是阿里巴巴开源的一款动态服务发现、配置管理和服务管理平台。它提供了注册中心、配置中心和可视化界面三大功能。在微服务架构中,Nacos 可以作为服务发现和配置中心的核心组件,帮助开发者解决微服务架构下的配置管理和服务发现问题。

本文档将介绍 Nacos 的安装、使用以及相关概念,并提供一些实际应用场景的示例。

安装

通过 Docker 安装

Nacos 提供了 Docker 镜像的方式进行安装,相比传统的安装方式更加方便快捷。首先需要安装 Docker,可以参考 Docker 官方文档 进行安装。

然后执行如下命令拉取 Nacos 镜像并启动容器:

docker run --name nacos -e MODE=standalone -p 8848:8848 -d nacos/nacos-server

其中,MODE=standalone 表示以单机模式运行,-p 8848:8848 表示将宿主机的 8848 端口映射到容器的 8848 端口,nacos/nacos-server 表示拉取最新版本的 Nacos 镜像。运行完成后,可以通过浏览器访问 http://localhost:8848/nacos 访问 Nacos 的控制台。

通过源码安装

Nacos 也提供了源码安装的方式,首先需要安装 JDK 和 Maven。可以从官网下载并安装 JDKMaven

然后执行如下命令进行编译和启动:

git clone https://github.com/alibaba/nacos.git
cd nacos/
mvn -Prelease-nacos clean install -U
cd distribution/target/nacos-server-<version>/bin
sh startup.sh -m standalone

其中,<version> 需要替换为具体的版本号,例如 1.4.1。运行完成后,同样可以通过浏览器访问 http://localhost:8848/nacos 访问 Nacos 的控制台。

原理

CAP 理论

CAP 理论是分布式系统设计中的重要理论,它指出在一个分布式系统中,Consistency(一致性)、Availability(可用性)和Partition tolerance(分区容错性)这三个特性无法同时满足。在 CAP 理论中,Nacos 选择了保证 AP(一致性和可用性)。

  • 一致性(Consistency):在分布式系统中的所有节点,数据的一致性应该得到保证。这意味着当一个节点的数据发生变化时,其他节点应该能够立即感知到这个变化。
  • 可用性(Availability):分布式系统在面对节点故障或网络分区的情况下,仍然能够保持对外提供服务的能力。
  • 分区容错性(Partition tolerance):分布式系统能够在网络分区的情况下继续工作,并保持数据的一致性和可用性。

Nacos 实现原理

Nacos 使用了一些核心技术来实现其功能,包括:

  • 服务注册与发现:Nacos 使用基于 Raft 算法的一致性协议实现服务注册与发现功能。每个节点通过选举产生一个 Leader 节点,Leader 负责处理客户端的请求,将服务实例信息存储在自身的内存中,并将变更同步给其他节点。
  • 配置管理:Nacos 使用基于 Raft 算法的一致性协议实现配置管理功能。通过选举产生 Leader 节点,Leader 负责处理客户端的配置请求,并将配置信息存储在内存中,然后将变更同步给其他节点。
  • 服务调用:Nacos 通过集成 Ribbon 和 Feign 实现了服务调用的负载均衡和动态路由功能。它使用心跳机制来检测服务实例的健康状态,并根据负载均衡策略选择合适的实例进行调用。

选举原理

在 Nacos 中,选举过程是通过 Raft 算法实现的。Raft 是一种共识算法,用于在分布式系统中选择一个 Leader 节点来处理客户端请求。选举的过程如下:

  1. 初始状态下,所有节点都处于 Follower 状态,没有 Leader 节点。
  2. 当节点接收到客户端请求时,如果它是 Follower 状态,它将转变为 Candidate 状态,并开始选举过程。
  3. Candidate 节点向其他节点发送选举请求(RequestVote)。
  4. 其他节点收到选举请求后,会比较候选节点的日志信息和任期号,如果发现候选节点的日志更新且任期号较大,它们将投票给候选节点。
  5. 如果候选节点收到大多数节点的选票(超过半数),它将成为新的 Leader 节点。
  6. 新选举出的 Leader 节点会定期向其他节点发送心跳消息来保持其领导地位。

选举过程中使用了随机化的超时机制,以防止多个节点同时发起选举。Raft 算法保证了在正常情况下只有一个 Leader 节点,并且能够快速选举新的 Leader 节点来替代失败的节点。

使用

注册中心

在微服务架构中,服务实例需要向注册中心注册自己的信息,包括 IP 地址、端口号、所属应用名称等。Nacos 提供了非常简单的 API,可以方便地实现服务注册和发现。

服务注册

服务注册需要调用 Nacos 的 API,在服务启动时将自身的信息注册到 Nacos 中。以下是 Java 代码示例:

public class Application {
public static void main(String[] args) throws NacosException {
// 创建 NamingService 实例,指定注册中心地址
Properties properties = new Properties();
properties.setProperty("serverAddr", "localhost:8848");
NamingService namingService = new NacosNamingService(properties);

// 注册服务
namingService.registerInstance("app", "127.0.0.1", 8080);
}
}

以上代码将 app 服务注册到 Nacos 中,IP 地址为 127.0.0.1,端口号为 8080。在实际应用中,可以根据自己的需求传递更多参数。

服务发现

服务发现需要调用 Nacos 的 API,在需要使用服务时从 Nacos 中获取服务信息。以下是 Java 代码示例:

public class Application {
public static void main(String[] args) throws NacosException {
// 创建 NamingService 实例,指定注册中心地址
Properties properties = new Properties();
properties.setProperty("serverAddr", "localhost:8848");
NamingService namingService = new NacosNamingService(properties);

// 获取服务实例列表
List<Instance> instances = namingService.getAllInstances("app");

// 选择其中一个实例进行调用
Instance instance = instances.get(0);
String url = "http://" + instance.getIp() + ":" + instance.getPort() + "/api";

// 调用服务
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.get()
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
}
}

以上代码从 Nacos 中获取了 app 服务的所有实例列表,然后选择其中一个进行调用。在实际应用中,可以根据自己的需求选择相应的实例。

配置中心

在微服务架构中,各个服务之间的配置信息可能会发生变化,因此需要一个集中的配置中心来管理这些配置信息。Nacos 提供了非常方便的配置中心功能,可以实现动态配置更新和推送等功能。

添加配置

添加配置需要通过 Nacos 的控制台或 API 进行操作。以下是通过控制台添加配置的示例:

  1. 登录 Nacos 控制台,选择 配置管理 -> 配置列表
  2. 点击 + 新增配置
  3. 填写配置信息,包括 Data IDGroupContent。其中,Data IDGroup 用于唯一标识一个配置信息,Content 则是配置内容。
  4. 点击 发布 按钮即可完成添加配置。

获取配置

获取配置需要调用 Nacos 的 API。以下是 Java 代码示例:

public class Application {
public static void main(String[] args) throws NacosException {
// 创建 ConfigService 实例,指定配置中心地址
Properties properties = new Properties();
properties.setProperty("serverAddr", "localhost:8848");
ConfigService configService = NacosFactory.createConfigService(properties);

// 获取配置
String content = configService.getConfig("data-id", "group", 5000);
System.out.println(content);
}
}

以上代码从 Nacos 中获取了 data-id 配置信息,并指定了 group 分组和超时时间为 5000ms。在实际应用中,可以根据自己的需求传递更多参数。

监听配置变化

监听配置变化需要调用 Nacos 的 API,在配置发生变化时触发相应的回调函数。以下是 Java 代码示例:

public class Application {
public static void main(String[] args) throws NacosException, InterruptedException {
// 创建 ConfigService 实例,指定配置中心地址
Properties properties = new Properties();
properties.setProperty("serverAddr", "localhost:8848");
ConfigService configService = NacosFactory.createConfigService(properties);

// 监听配置变化
configService.addListener("data-id", "group", new Listener() {
@Override
public void receiveConfigInfo(String configInfo) {
System.out.println(configInfo);
}
@Override
public Executor getExecutor() {
return null;
}
});

// 等待配置变化通知
Thread.sleep(Long.MAX_VALUE);
}
}

以上代码监听了 data-id 配置信息的变化,并在变化发生时输出相应的内容。在实际应用中,可以根据自己的需求传递更多参数。

实际应用

Spring Cloud 集成

Nacos 与 Spring Cloud 微服务框架集成非常简单,只需要引入相应的依赖和配置即可。以下是 Maven 依赖和配置示例:

<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>

<!-- 引入 Nacos 依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>

<!-- 引入 Nacos 配置依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
<!-- 配置 Nacos 服务器地址 -->
spring.cloud.nacos.discovery.server-addr=localhost:8848
spring.cloud.nacos.config.server-addr=localhost:8848

以上配置引入了 Nacos 的服务注册与发现和配置中心功能,并指定了 Nacos 服务器的地址。

服务注册与发现

在 Spring Cloud 中,服务注册与发现是通过 @EnableDiscoveryClient 注解实现的。以下是示例代码:

@SpringBootApplication
@EnableDiscoveryClient
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

以上代码将当前应用标记为可被发现的服务,并启动 Spring Boot 应用。在应用启动后,Nacos 将自动扫描并注册当前应用的服务实例。

配置中心

在 Spring Cloud 中,配置中心需要通过 @RefreshScope 注解实现动态更新。以下是示例代码:

@RestController
@RefreshScope
public class ConfigController {

@Value("${config.key}")
private String configValue;

@GetMapping("/config")
public String getConfig() {
return configValue;
}
}

以上代码使用 @Value 注解获取配置信息,同时使用 @RefreshScope 注解实现动态更新。当配置信息发生变化时,Nacos 将自动通知应用并刷新 configValue 的值。

负载均衡

在 Spring Cloud 中,负载均衡是通过 @LoadBalanced 注解实现的。以下是示例代码:

@SpringBootApplication
@EnableDiscoveryClient
public class Application {

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

以上代码创建了一个使用 Ribbon 实现负载均衡的 RestTemplate 对象,并将其标记为可被 Spring 容器扫描和注入的 Bean。

服务调用

在 Spring Cloud 中,服务调用可以使用 RestTemplate 或 Feign 客户端实现。以下是示例代码:

@FeignClient("provider-service")
public interface HelloService {

@GetMapping("/hello")
String hello();
}

@RestController
public class ConsumerController {

@Autowired
private HelloService helloService;

@GetMapping("/hello")
public String hello() {
return helloService.hello();
}
}

以上代码使用 RestTemplate 调用名为 provider-service 的远程服务。在实际应用中,可以根据自己的需求选择相应的方式进行服务调用。