Nacos服务发现与配置中心:微服务注册中心实战

**作者:洛水石** | **更新日期:2026-05-11** | **标签:Nacos | Spring Cloud | 微服务 | 服务治理**

前言

上周二早上9点,线上告警炸了:服务A调用服务B失败,500+错误。查了半天发现是服务B重启后IP变了,服务A还在用旧的IP调用。

这不是个案。在微服务架构中,**服务实例是动态的**,IP会变、端口会变、数量会动态伸缩。传统的配置文件方式根本无法应对这种变化。

Nacos就是来解决这个问题的------**服务注册与发现、配置管理、服务健康监测**,让你告别硬编码,拥抱动态服务治理。

一、Nacos核心概念

1.1 服务注册与发现原理

▲ Nacos服务注册发现架构

**核心流程**

  1. 服务提供者启动时向Nacos注册自己的信息
  2. 服务消费者从Nacos获取服务提供者的实例列表
  3. Nacos感知到服务变化时主动通知消费者

1.2 命名空间与隔离

|-------------------|-----------|---------------|
| 隔离级别 | 说明 | 使用场景 |
| **Namespace** | 顶级隔离,不同环境 | dev/test/prod |
| **Group** | 服务分组 | 业务线/团队划分 |
| **DataID** | 具体配置 | 配置文件 |

二、快速部署

2.1 Docker Compose部署

docker-compose.yml

version: '3.8'
services:
nacos:
image: nacos/nacos-server:v2.2.3
container_name: nacos
environment:
MODE: standalone
SPRING_DATASOURCE_PLATFORM: embedded
ports:

  • "8848:8848"
  • "9848:9848"
    volumes:
  • ./data:/home/nacos/data
  • ./logs:/home/nacos/logs
    restart: unless-stopped

启动

docker-compose up -d

访问控制台

http://localhost:8848/nacos

默认账号密码: nacos / nacos

2.2 Kubernetes部署

nacos.yaml

apiVersion: v1
kind: ConfigMap
metadata:
name: nacos-standalone-config
data:
MODE: "standalone"

apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nacos
spec:
serviceName: nacos
replicas: 1
selector:
matchLabels:
app: nacos
template:
metadata:
labels:
app: nacos
spec:
containers:

  • name: nacos
    image: nacos/nacos-server:v2.2.3
    ports:
  • containerPort: 8848
    name: client
  • containerPort: 9848
    name: grpc
    env:
  • name: MODE
    valueFrom:
    configMapKeyRef:
    name: nacos-standalone-config
    key: MODE
    resources:
    requests:
    memory: 1Gi
    cpu: 500m
    limits:
    memory: 2Gi
    cpu: 1000m

三、Spring Boot集成

3.1 依赖配置

<!-- pom.xml -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2022.0.0.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2022.0.0.0</version>
</dependency>

3.2 application.yml

bootstrap.yml (注意是bootstrap不是application)

spring:
application:
name: order-service
cloud:
nacos:
server-addr: 192.168.1.100:8848
username: nacos
password: nacos
discovery:
namespace: dev
group: DEFAULT_GROUP
metadata:
version: v1
config:
namespace: dev
group: DEFAULT_GROUP
file-extension: yaml
refresh-enabled: true
shared-configs:

  • data-id: common.yaml
    group: GLOBAL
    refresh: true

3.3 服务注册

@SpringBootApplication
@EnableDiscoveryClient // 启用服务发现
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}

// 服务启动后自动注册到Nacos
@RestController
public class HealthController {
@GetMapping("/health")
public String health() {
return "OK";
}
}

3.4 服务调用

@Service
public class OrderService {

@Autowired
private RestTemplate restTemplate;

// 方式1:服务名直接调用(Ribbon负载均衡)
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}

public Order createOrder(Long productId, Integer quantity) {
// 通过服务名调用,不需要知道IP和端口
Product product = restTemplate.getForObject(
"http://product-service/api/products/" + productId,
Product.class
);
// ... 创建订单
return order;
}
}

3.5 使用Feign调用

// 定义Feign客户端
@FeignClient(name = "product-service", path = "/api/products")
public interface ProductClient {

@GetMapping("/{id}")
Product getProduct(@PathVariable("id") Long id);

@GetMapping("/{id}/stock")
Integer getStock(@PathVariable("id") Long id);
}

// 使用
@Service
public class OrderService {

@Autowired
private ProductClient productClient;

public Order createOrder(Long productId) {
Product product = productClient.getProduct(productId);
// ... 创建订单
return order;
}
}

四、配置中心

4.1 在Nacos创建配置

▲ 配置中心工作流程

Data ID: order-service.yaml

Group: DEFAULT_GROUP

Namespace: dev

spring:
datasource:
url: jdbc:mysql://mysql:3306/orders?useSSL=false
username: root
password: ${DB_PASSWORD:default123}
driver-class-name: com.mysql.cj.jdbc.Driver

server:
port: ${SERVER_PORT:8080}

order:
timeout: 5000
max-retry: 3
payment-url: http://payment-service/api/pay

4.2 动态获取配置

@RestController
@RefreshScope // 启用动态刷新
public class OrderConfig {

@Value("${order.timeout:3000}")
private Integer timeout;

@Value("${order.max-retry:3}")
private Integer maxRetry;

@GetMapping("/config")
public Map<String, Object> getConfig() {
Map<String, Object> config = new HashMap<>();
config.put("timeout", timeout);
config.put("maxRetry", maxRetry);
return config;
}
}

4.3 配置监听

@Component
@Slf4j
public class NacosConfigListener {

@NacosConfigListener(dataId = "order-service.yaml", groupId = "DEFAULT_GROUP")
public void onConfigChange(String config) {
log.info("配置变更: {}", config);
// 处理配置变更
// 例如:重新初始化连接池、刷新缓存等
}
}

4.4 共享配置

共享配置 - 多个服务共用

Data ID: common.yaml

Group: GLOBAL

日志配置

logging:
level:
root: INFO
com.example: DEBUG
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"

Swagger配置

swagger:
enabled: true
title: API文档
version: 1.0

五、服务治理

5.1 负载均衡权重

// 服务实例级别设置权重
@Configuration
public class RibbonConfig {

@Bean
public IRule ribbonRule() {
// 权重负载均衡 - 根据权重分配流量
return new WeightedResponseTimeRule();
}
}

5.2 熔断降级

@FeignClient(name = "product-service", fallback = ProductClientFallback.class)
public interface ProductClient {

@GetMapping("/{id}")
Product getProduct(@PathVariable("id") Long id);
}

// 降级实现
@Component
@Slf4j
public class ProductClientFallback implements ProductClient {

@Override
public Product getProduct(Long id) {
log.warn("Product服务调用失败,返回降级数据");
Product fallbackProduct = new Product();
fallbackProduct.setId(id);
fallbackProduct.setName("降级商品");
fallbackProduct.setPrice(BigDecimal.ZERO);
return fallbackProduct;
}
}

5.3 命名空间隔离

bootstrap.yml

spring:
cloud:
nacos:
discovery:
namespace: {NACOS_NAMESPACE} # 指定命名空间 group: {SERVICE_GROUP} # 指定分组

// Java中获取某命名空间的服务
@Autowired
private NamingService namingService;

public List<Instance> getInstances(String serviceName) {
try {
return namingService.selectInstances(serviceName, true);
} catch (NacosException e) {
log.error("获取服务实例失败", e);
return Collections.emptyList();
}
}

六、生产最佳实践

6.1 高可用部署

▲ Nacos高可用集群架构

nacos-cluster.yaml

version: '3.8'
services:
nacos1:
image: nacos/nacos-server:v2.2.3
container_name: nacos1
environment:
MODE: cluster
NACOS_SERVERS: nacos1:8848 nacos2:8848 nacos3:8848
MYSQL_HOST: mysql
MYSQL_DB_NAME: nacos
MYSQL_USER: nacos
MYSQL_PASSWORD: nacos123
ports:

  • "8848:8848"
    depends_on:
  • mysql

nacos2:
image: nacos/nacos-server:v2.2.3
container_name: nacos2
environment:
MODE: cluster
NACOS_SERVERS: nacos1:8848 nacos2:8848 nacos3:8848
MYSQL_HOST: mysql
MYSQL_DB_NAME: nacos
MYSQL_USER: nacos
MYSQL_PASSWORD: nacos123
ports:

  • "8849:8848"

nacos3:
image: nacos/nacos-server:v2.2.3
container_name: nacos3
environment:
MODE: cluster
NACOS_SERVERS: nacos1:8848 nacos2:8848 nacos3:8848
MYSQL_HOST: mysql
MYSQL_DB_NAME: nacos
MYSQL_USER: nacos
MYSQL_PASSWORD: nacos123
ports:

  • "8850:8848"

mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: nacos
volumes:

  • mysql_data:/var/lib/mysql

volumes:
mysql_data:

6.2 配置加密

// 配置属性加密
@Configuration
public class NacosConfig {

@NacosConfigurationProperties(prefix = "spring.datasource")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
}

// 使用加密配置
spring:
datasource:
password: '{cipher}xxx加密后的密码xxx'

七、常见问题

Q1: 服务注册后发现实例不存在?

检查网络连通性

curl http://192.168.1.100:8848/nacos/v1/ns/instance/list?serviceName=order-service

检查服务实例元数据

curl http://192.168.1.100:8848/nacos/v1/ns/instance/metadata?serviceName=order-service

Q2: 配置更新后没有生效?

// 检查是否添加了 @RefreshScope
@RestController
@RefreshScope // 必须添加!
public class ConfigController {
@Value("${custom.config}")
private String config;
}

Q3: 服务下线后仍被调用?

// 确保正确下线
@PreDestroy
public void deregister() {
try {
nacosServiceManager.getNamingService().deregisterInstance(
serviceName, ip, port
);
} catch (NacosException e) {
log.error("服务注销失败", e);
}
}

总结

Nacos核心能力一览:

|--------------|------------|------------|
| 能力 | 说明 | 收益 |
| **服务注册** | 自动注册、心跳检测 | 免去手动维护服务列表 |
| **服务发现** | 动态获取、实时通知 | 告别硬编码IP |
| **配置管理** | 集中管理、动态刷新 | 配置变更无需重启 |
| **命名空间** | 环境隔离、逻辑分区 | 支持多环境部署 |
| **高可用** | 集群模式、数据持久化 | 生产环境必备 |

**下一步建议**

  1. 集成Sentinel实现流量控制
  2. 接入SkyWalking实现链路追踪
  3. 配置Prometheus监控

*微服务架构,Nacos让服务治理变得简单。*

相关推荐
喜欢流萤吖~1 小时前
微服务可观测性:让系统不再黑盒
微服务·架构
下次再写1 小时前
深入浅出微服务架构:从理论到Spring Boot实战
java·微服务·springboot·springcloud·架构设计·后端开发·分布式系统
Kiyra1 小时前
限流不是加个计数器就行:用 Lua 脚本实现多维度原子限流
开发语言·人工智能·网络协议·职场和发展·架构·lua·ai-native
SamDeepThinking2 小时前
千万级用户购物车系统的架构设计
java·后端·架构
前端不太难2 小时前
鸿蒙 App 的 Task + State 双核心架构
架构·状态模式·harmonyos
十年编程老舅2 小时前
深度长文|Linux 图形与显示架构
linux·运维·后端·架构·内核·linux内核·通信机制
heimeiyingwang2 小时前
【架构实战】服务注册与发现Nacos:微服务时代的“电话总机“
网络·架构
薛定猫AI2 小时前
【深度解析】Gemma Chat:基于 MLX 的 Mac 离线 Coding Agent 架构与实战
macos·架构
星梦清河2 小时前
微服务-Elasticsearch01
elasticsearch·微服务·架构