目录
1. Nacos简介
1.1 什么是Nacos
Nacos(Dynamic Naming and Configuration Service)是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
Nacos的含义:
- Naming:命名服务,提供分布式系统中所有对象(Object)、实体(Entity)的"名字"到关联的元数据之间的映射管理服务
- Configuration:配置服务,在分布式系统中,服务配置的编辑、存储、分发、变更管理、历史版本管理、变更审计等所有与配置相关的活动
- Service:服务管理,提供对服务的注册、发现、健康检查、路由、负载均衡等服务管理能力
1.2 Nacos的核心功能
服务发现和服务健康监测
- 支持基于DNS和基于RPC的服务发现
- 提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求
- 提供统一的健康检查仪表盘,帮助您根据健康状态管理服务的可用性及流量
动态配置服务
- 动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置
- 动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷
动态DNS服务
- 动态DNS服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单DNS解析服务
服务及其元数据管理
- Nacos能让您从微服务平台建设的视角管理数据中心的所有服务及元数据
1.3 Nacos的优势
- 易于使用:提供简单易用的特性集,帮助您快速实现动态服务发现、服务配置管理、服务及流量管理
- 更适应云原生:由于其轻量级特性,更适应云原生场景
- 生产可用:经过阿里巴巴双11等大型活动考验,具备生产级的稳定性和可用性
- 丰富的应用场景:支持几乎所有主流类型的"服务"的发现、配置和管理
2. Nacos架构原理
2.1 整体架构
Nacos采用分层架构设计,主要包括以下几个层次:
┌─────────────────────────────────────────┐
│ Console (控制台) │
├─────────────────────────────────────────┤
│ Open API │
├─────────────────────────────────────────┤
│ Config Service │
│ Naming Service │
├─────────────────────────────────────────┤
│ Consistency Protocol │
├─────────────────────────────────────────┤
│ Core │
├─────────────────────────────────────────┤
│ Plugin (插件) │
└─────────────────────────────────────────┘
2.2 核心组件
Provider APP(服务提供者)
- 服务的被调用方,向Nacos注册自己提供的服务,向Nacos汇报自己的健康状态
Consumer APP(服务消费者)
- 服务的调用方,向Nacos订阅自己所需要的服务,从Nacos查询提供特定服务的Provider的信息
Name Server(注册中心)
- 服务注册中心,接受Provider的注册,接受Consumer的订阅,实现服务发现
Nacos Server
- Nacos服务端,由Java编写,为Provider和Consumer提供服务注册、服务订阅等服务,同时包含配置中心功能
2.3 数据存储
内嵌数据库模式
- 单机模式下,Nacos默认使用内嵌数据库Derby
- 适用于开发测试环境
外置数据库模式
- 生产环境推荐使用MySQL作为数据存储
- 支持集群部署,数据持久化更可靠
3. Nacos安装与部署
3.1 单机部署
下载安装包
# 下载Nacos
wget https://github.com/alibaba/nacos/releases/download/2.3.2/nacos-server-2.3.2.tar.gz
# 解压
tar -xzf nacos-server-2.3.2.tar.gz
cd nacos
启动服务器
# Linux/Mac系统
sh startup.sh -m standalone
# Windows系统
startup.cmd -m standalone
访问控制台
- 地址:http://localhost:8848/nacos
- 默认用户名/密码:nacos/nacos
3.2 集群部署
配置集群配置文件
# 复制集群配置文件
cp conf/cluster.conf.example conf/cluster.conf
# 编辑集群配置文件
vim conf/cluster.conf
cluster.conf内容示例:
192.168.1.100:8848
192.168.1.101:8848
192.168.1.102:8848
配置数据库
# 编辑数据库配置
vim conf/application.properties
添加MySQL配置:
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://localhost:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=nacos
db.password.0=nacos
启动集群
# 在每台机器上启动
sh startup.sh
3.3 Docker部署
单机模式
docker run -d \
--name nacos-standalone \
-e MODE=standalone \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
nacos/nacos-server:v2.3.2
Docker Compose集群部署
version: '3.8'
services:
nacos1:
image: nacos/nacos-server:v2.3.2
container_name: nacos1
environment:
- PREFER_HOST_MODE=hostname
- MODE=cluster
- NACOS_APPLICATION_PORT=8848
- NACOS_SERVERS=nacos1:8848 nacos2:8848 nacos3:8848
- MYSQL_SERVICE_HOST=mysql
- MYSQL_SERVICE_DB_NAME=nacos
- MYSQL_SERVICE_USER=nacos
- MYSQL_SERVICE_PASSWORD=nacos
ports:
- "8848:8848"
- "9848:9848"
depends_on:
- mysql
nacos2:
image: nacos/nacos-server:v2.3.2
container_name: nacos2
environment:
- PREFER_HOST_MODE=hostname
- MODE=cluster
- NACOS_APPLICATION_PORT=8848
- NACOS_SERVERS=nacos1:8848 nacos2:8848 nacos3:8848
- MYSQL_SERVICE_HOST=mysql
- MYSQL_SERVICE_DB_NAME=nacos
- MYSQL_SERVICE_USER=nacos
- MYSQL_SERVICE_PASSWORD=nacos
ports:
- "8849:8848"
- "9849:9848"
depends_on:
- mysql
mysql:
image: mysql:8.0
container_name: mysql
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=nacos
- MYSQL_USER=nacos
- MYSQL_PASSWORD=nacos
ports:
- "3306:3306"
volumes:
- ./mysql:/var/lib/mysql
4. Nacos服务发现
4.1 服务注册
自动注册
在SpringCloud中,服务启动时会自动向Nacos注册,注册信息包括:
- 服务名称
- IP地址
- 端口号
- 健康状态
- 元数据信息
手动注册
@RestController
public class ServiceController {
@Autowired
private NacosRegistration nacosRegistration;
@Autowired
private NacosServiceRegistry nacosServiceRegistry;
@PostMapping("/register")
public String register() {
nacosServiceRegistry.register(nacosRegistration);
return "服务注册成功";
}
@PostMapping("/deregister")
public String deregister() {
nacosServiceRegistry.deregister(nacosRegistration);
return "服务注销成功";
}
}
4.2 服务发现
使用RestTemplate调用
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
@Service
public class UserService {
@Autowired
private RestTemplate restTemplate;
public String getUserInfo(Long userId) {
return restTemplate.getForObject(
"http://user-service/user/" + userId,
String.class
);
}
}
使用OpenFeign调用
@FeignClient(name = "user-service")
public interface UserServiceFeign {
@GetMapping("/user/{id}")
String getUserInfo(@PathVariable("id") Long id);
}
@Service
public class OrderService {
@Autowired
private UserServiceFeign userServiceFeign;
public String createOrder(Long userId) {
String userInfo = userServiceFeign.getUserInfo(userId);
// 创建订单逻辑
return "订单创建成功";
}
}
4.3 健康检查
默认健康检查
Nacos默认通过TCP端口检查服务健康状态,每5秒检查一次。
自定义健康检查
@Component
public class CustomHealthIndicator implements HealthIndicator {
@Override
public Health health() {
// 自定义健康检查逻辑
boolean isHealthy = checkBusinessHealth();
if (isHealthy) {
return Health.up()
.withDetail("status", "服务运行正常")
.build();
} else {
return Health.down()
.withDetail("status", "服务异常")
.build();
}
}
private boolean checkBusinessHealth() {
// 检查数据库连接、缓存等
return true;
}
}
4.4 负载均衡
Ribbon负载均衡策略
@Configuration
public class RibbonConfig {
@Bean
public IRule ribbonRule() {
// 随机策略
return new RandomRule();
// 轮询策略
// return new RoundRobinRule();
// 权重策略
// return new WeightedResponseTimeRule();
}
}
自定义负载均衡
@Configuration
public class LoadBalancerConfig {
@Bean
public ReactorLoadBalancer<ServiceInstance> customLoadBalancer(
Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new CustomLoadBalancer(
loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),
name
);
}
}
5. Nacos配置管理
5.1 配置发布
通过控制台发布配置
- 登录Nacos控制台
- 进入"配置管理"→"配置列表"
- 点击"+"号添加配置
- 填写Data ID、Group、配置内容
- 点击"发布"
通过API发布配置
@RestController
public class ConfigController {
@Autowired
private ConfigService configService;
@PostMapping("/config/publish")
public String publishConfig(@RequestParam String dataId,
@RequestParam String group,
@RequestParam String content) throws NacosException {
boolean result = configService.publishConfig(dataId, group, content);
return result ? "配置发布成功" : "配置发布失败";
}
}
5.2 配置获取
在SpringBoot中获取配置
# bootstrap.properties
spring.application.name=order-service
spring.cloud.nacos.config.server-addr=localhost:8848
spring.cloud.nacos.config.file-extension=yaml
spring.cloud.nacos.config.group=DEFAULT_GROUP
spring.cloud.nacos.config.namespace=dev
使用@Value注解
@RestController
public class ConfigTestController {
@Value("${mysql.host:localhost}")
private String mysqlHost;
@Value("${mysql.port:3306}")
private String mysqlPort;
@GetMapping("/config/mysql")
public String getMysqlConfig() {
return "MySQL配置: " + mysqlHost + ":" + mysqlPort;
}
}
使用@ConfigurationProperties
@Component
@ConfigurationProperties(prefix = "mysql")
@Data
public class MysqlProperties {
private String host;
private Integer port;
private String username;
private String password;
private String database;
}
5.3 配置热更新
使用@RefreshScope
@RefreshScope
@RestController
public class ConfigController {
@Value("${app.name:default}")
private String appName;
@GetMapping("/config/app-name")
public String getAppName() {
return "应用名称: " + appName;
}
}
配置变更监听
@Component
public class ConfigListener {
@Autowired
private ConfigService configService;
@PostConstruct
public void init() throws NacosException {
String dataId = "order-service.yaml";
String group = "DEFAULT_GROUP";
configService.addListener(dataId, group, new Listener() {
@Override
public Executor getExecutor() {
return null;
}
@Override
public void