记录一下Nacos注册中心的一些心得体会。老实说,刚开始接触这个东西时,我是懵逼的😂。但是经过一番折腾后,发现其实没那么复杂,写下这篇博客,记录并方便复习。

为什么需要注册中心?

先说说为什么我们需要注册中心吧。

还记得我第一次做分布式项目时的场景:

项目里有订单服务、用户服务、支付服务等多个服务,它们部署在不同的服务器上。问题来了 - 服务间如何互相调用?

最开始,我是这样做的:

// 写死IP和端口
String url = "http://192.168.1.100:8080/user/getUserById?id=1";

看起来没问题对吧?但实际上问题大了:

  1. 服务器IP变了怎么办?重新改代码,重新部署…
  2. 一个服务部署了多台机器做负载均衡?不知道该访问哪一台…
  3. 某台服务器挂了?继续访问会报错…

这时候就需要一个"管家",帮我们记录并管理所有服务的地址信息,这个"管家"就是注册中心。

Nacos是个啥?

Nacos是阿里开源的一个注册中心+配置中心的组合工具,名字来源于"Naming and Configuration Service"。

说人话,就是它就像一个大型企业的前台接待+通讯录:

  • 前台接待:新来的服务要先在前台登记自己的信息(服务注册)
  • 通讯录:谁想找某个服务,就翻翻通讯录,找到它的联系方式(服务发现)

相比Eureka、Zookeeper等其他注册中心,Nacos的优势在于:

  • 同时支持AP和CP模式(不清楚的可以去补习一下CAP理论)
  • 自带简洁实用的控制台界面(这是真香)
  • 整合了配置中心功能

实际操作Nacos

下面实际操作一下。

1. 安装Nacos

首先,我们需要下载并安装Nacos。

我是在Windows下学习的,所以直接去Nacos的GitHub下载了最新稳定版的zip包。解压后,进入bin目录,双击startup.cmd就启动了(Mac/Linux用户使用startup.sh)。

默认情况下,Nacos以单机模式启动,访问http://localhost:8848/nacos,用户名密码默认都是nacos

2. Spring Cloud整合Nacos(生产者)

接下来,我们创建两个服务:一个生产者(provider)和一个消费者(consumer)。

先来看看生产者端怎么整合Nacos:

1)添加依赖

<!-- SpringCloud Alibaba Nacos -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2021.1</version>
</dependency>

2)配置application.yml

server:
  port: 8081

spring:
  application:
    name: service-provider  # 服务名称,重要!
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.*.*:8848  # Nacos地址

3)启动类添加注解

@SpringBootApplication
@EnableDiscoveryClient  // 开启服务注册发现功能
public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }
}

4)提供一个简单的测试接口

@RestController
public class HelloController {

    @Value("${server.port}")
    private String port;

    @GetMapping("/hello")
    public String hello() {
        return "Hello from Provider, port: " + port;
    }
}

启动应用后,打开Nacos控制台,就能看到我们的服务已经注册上去了!

3. Spring Cloud整合Nacos(消费者)

消费者的配置与生产者类似,只是端口和服务名不同:

server:
  port: 8082

spring:
  application:
    name: service-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

然后我们使用OpenFeign来调用生产者服务,首先添加OpenFeign依赖:

<!-- SpringCloud OpenFeign -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

在启动类上添加@EnableFeignClients注解:

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients  // 开启Feign功能
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}

接下来,创建一个Feign接口来声明要调用的服务:

@FeignClient(name = "service-provider")  // 指定服务名
public interface ProviderClient {

    @GetMapping("/hello")  // 与提供者接口路径保持一致
    String hello();
}

最后,在控制器中使用这个接口调用服务:

@RestController
public class ConsumerController {

    @Autowired
    private ProviderClient providerClient;

    @GetMapping("/consumer/hello")
    public String hello() {
        // 直接调用接口方法
        return providerClient.hello();
    }
}

启动消费者应用,访问http://localhost:8082/consumer/hello,就能看到调用成功的结果了!

Nacos的一些高级特性

1. 服务健康检查

Nacos会定期检查已注册服务的健康状态。默认情况下,如果一个服务在15秒内没有发送心跳,Nacos会将其标记为不健康;如果30秒内没有心跳,则会将其从服务列表中临时摘除。

这个机制保证了总是能访问到健康的服务实例。

2. 权重配置与负载均衡

Nacos支持为每个服务实例设置权重,范围是0到1。权重越大,被调用的几率越高。

在控制台上可以很方便地调整权重

这个功能在灰度发布时非常有用!比如,新版本刚上线时,可以先给它设置较低的权重,观察一段时间没问题后再逐步提高权重。

3. 命名空间和分组

在实际项目中,我们通常会有多个环境:开发、测试、预发、生产…

Nacos提供了命名空间(Namespace)和分组(Group)来解决环境隔离问题:

  • 命名空间:可以用来隔离不同环境,如dev、test、prod
  • 分组:可以用来隔离同一环境下的不同应用或团队

配置起来也很简单:

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: dev  # 指定命名空间
        group: GROUP-A  # 指定分组

4. 临时实例和持久化实例

Nacos中的服务实例分为两类:

  • 临时实例(默认):依赖心跳维持,实例下线后会从注册中心删除
  • 持久化实例:即使实例下线,也不会从注册中心删除,需要手动删除

配置持久化实例:

spring:
  cloud:
    nacos:
      discovery:
        ephemeral: false  # 设置为持久化实例

临时实例适合无状态服务,持久化实例适合有状态服务(如数据库)。

踩坑记录

  1. 依赖版本冲突:Spring Cloud和Spring Cloud Alibaba的版本需要匹配,否则可能会报错。建议参考官方版本说明
  2. 服务调用失败:使用OpenFeign时,确保@EnableFeignClients注解没有遗漏,且FeignClient接口的name属性与提供者的服务名完全一致。
  3. 服务名区分大小写:在服务调用时,Nacos中的服务名是区分大小写的,需要保持一致。
  4. Nacos占用内存过大:默认配置下Nacos比较吃内存,可以修改startup脚本中的JVM参数,将内存调小一点。

总结与思考

nacos确实极大方便了配置,真的很有用。

Nacos还有很多我没有使用的功能,比如更复杂的配置中心功能、集群部署等。这些内容我打算在后面的学习中继续深入研究。