SpringCloud 整合 Nacos 轻松构建分布式服务注册中心!
一、背景介绍
Spring Cloud Alibaba 是阿里巴巴推出的一套微服务开发的一站式解决方案,同时也是 Spring Cloud 的一个子项目,它整合了阿里巴巴开源的一些分布式系统中间件,比如 Nacos、Dubbo、Sentinel 等,特别是在处理高并发和大规模分布式系统方面具有优势,可以用来帮助开发者快速构建微服务项目架构。
在之前的文章中,我们简单介绍了一下 Spring Cloud Alibaba 的技术体系,相信大家对它已经有了初步的认识。
今天通过这篇文章,我们一起来了解一下 Spring Cloud Alibaba 技术体系中最核心的组件之一 Nacos。
二、Nacos 简介
Nacos 是一款开源的动态服务发现、配置管理和服务管理平台。简单点说,Nacos 可以帮助我们发现、配置和管理各个微服务,其作用相当于 Eureka 和 Config Server 的结合体,在微服务架构中起着至关重要的作用。
2.1、服务注册中心的交互流程介绍
当用于服务注册中心时,微服务之间的交互流程可以用如下图来概括。

从上图可以看出,其作用与 Eureka 基本一样,主要用于服务的注册和发现。
服务启动时,Service A 和 Service B 分别将自己的实例信息注册到 Nacos 上。当 Service A 需要调用 Service B 时,会先从 Nacos 上获取目标实例信息,最后再向 Service B 发起远程调用。
2.2、配置中心的交互流程介绍
当用于服务配置中心时,微服务之间的交互流程可以用如下图来概括。

当有大量业务微服务需要更新配置文件时,手动维护配置文件会变得非常困难。Nacos 可以作为统一的服务配置中心,连接各个业务微服务,实现对各个微服务的配置文件进行集中式管理,同时也可以在运行时动态更新配置信息,而无需重新启动微服务。
关于 Nacos 更多的功能特性介绍 ,可以参考官网文档。
下面我们一起来看看,如何利用 Nacos 搭建一套高可用的服务注册中心。
三、方案实践
3.1、安装 Nacos
与 Eureka 不同,Nacos 需要单独安装部署,下载地址:
https://nacos.io/download/nacos-server
下载完成之后,解压。根据不同平台,执行不同命令,启动单机版 Nacos 服务示例如下:
- Linux/Unix/Mac:
sh startup.sh -m standalone
- Windows:
cmd startup.cmd -m standalone
其中startup.sh
脚本位于 Nacos 解压后的bin
目录下。
服务启动之后,访问:http://127.0.0.1:8848/nacos/
,就可以进入 Nacos 的首页,示例如下。

默认用户名密码为:nacos
,登陆之后就会进入服务管理页面,界面如下。

下面我们创建两个应用程序(服务提供方和服务消费方),一起来验证 Nacos 的服务注册和发现功能。
3.2、创建服务提供方
首先,创建一个 Maven 工程,命名为nacos-provider
,并在pom.xml
中引入相关的依赖内容,示例如下:
<!-- 定义组件版本号 -->
<properties>
<spring-boot.version>2.2.5.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR3</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependencies>
<!-- SpringBoot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Nacos 服务发现 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 服务发现:OpenFeign服务调用 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 负载均衡器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- 引入 springBoot 版本号 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 引入 spring cloud 版本号 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 引入 spring cloud alibaba 适配的版本号 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
接着,创建一个服务启动类并添加@EnableDiscoveryClient
注解,开启 Spring Cloud 的服务注册与发现功能。
@EnableDiscoveryClient
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
然后,创建一个 web 接口,以便等会服务消费者发起 RPC 远程调用测试。
@RestController
public class HelloController {
@GetMapping("/findByName")
public String findByName(@RequestParam(value = "name") String name) {
System.out.println("收到客户端发起的rpc请求,请求参数:" + name);
return "hello,我是服务提供方,收到请求参数:" + name;
}
}
最后,还需要在application.properties
配置文件中,添加服务注册中心地址,示例如下:
spring.application.name=nacos-provider
server.port=9010
# 设置Nacos的服务地址,多个地址可使用【,】分隔
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
启动服务之后,再次访问http://127.0.0.1:8848/nacos
的服务列表,可以看到nacos-provider
成功注册到服务中心,界面如下。

3.3、创建服务消费方
同理,创建一个 Maven 工程,命名为nacos-consumer
。由于服务提供方和服务消费方,都属于 Nacos 客户端服务,其pom.xml
所需要的依赖内容和服务启动配置完全一致,在此就不重复粘贴了。
接着,创建一个服务启动类并添加@EnableDiscoveryClient
和@EnableFeignClients
注解,以便等会通过openFegin
发起远程调用。
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
然后,创建一个 web 接口,同时向nacos-provider
发起远程调用,示例如下:
@RestController
public class HelloController {
@Autowired
private RpcService rpcService;
/**
* 发起远程调用测试
* @return
*/
@GetMapping("/rpc")
public String rpc(@RequestParam(value = "name") String name) {
String result = rpcService.findByName(name);
return "通过 openfeign 发起远程调用,收到返回的信息:" + result;
}
}
/**
* 配置要调用的服务实例名称
*/
@FeignClient(name = "nacos-provider")
public interface RpcService {
/**
* 要调用的目标服务接口地址
* @return
*/
@RequestMapping(value = "/findByName")
String findByName(@RequestParam(value = "name") String name);
}
与上文类似,在application.properties
配置文件中添加服务注册中心地址,示例如下:
spring.application.name=nacos-consumer
server.port=9011
# 设置Nacos的服务地址,多个地址可使用【,】分隔
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
将服务启动,再次访问http://127.0.0.1:8848/nacos
的服务列表,可以看到nacos-consumer
也成功注册到服务中心,界面如下。

最后,将服务提供方nacos-provider
和服务消费方nacos-consumer
保持启动状态,然后访问http://127.0.0.1:9011/rpc?name=nacos
,可以得到类似于如下内容。

可以清晰的看到,服务消费方成功的远程调用了服务提供方的接口,并收到返回结果。
四、集群配置
4.1、数据持久化
在上文的介绍中,对于 Nacos 的服务端我们没有做任何特殊配置,一切均以默认的单机模式运行。这种模式只适合学习和测试环境,对于需要高可用的生产环境来说,显然并不合适。
与 Eureka 相比,Nacos 有一个显著的特色就是支持数据库存储。默认情况下,会使用嵌入式数据库实现数据的存储,但是这种模式不方便观察数据存储情况,从 0.7 版本开始,增加了支持 mysql 数据源能力。
具体的操作步骤如下:
- 第一步:安装数据库,版本要求:5.6.5+
- 第二步:创建 mysql 数据库
nacos-config
,数据库初始化脚本文件为nacos-mysql.sql
,该脚本文件在 Nacos 包下的 conf 目录下(此处 nacos 采用的是1.4.8
,不同的版本可能脚本文件有所不同,具体以实际为准) - 第三步:修改
conf/application.properties
文件,添加 mysql 数据源相关配置(目前只支持 mysql)。
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://localhost:3306/nacos-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user.0=root
db.password.0=root
到这里,Nacos 数据持久化到 MySQL 的配置就完成了。再次以单机模式重启 nacos,nacos 所有写入嵌入式数据库的数据都会写到了 mysql 中。
4.2、集群搭建
在上文的基础上,下面我们再一起来看看 Nacos 的集群搭建步骤。
4.2.1、集群部署架构图
对于要求高可用的服务,通常会采用 3 个及以上的节点来部署,Nacos 也不例外,集群架构图可以用如下图来描述。

下面我们来介绍每一步的搭建细节。
4.2.2、配置集群文件
在 Nacos 的conf
目录下有一个cluster.conf.example
文件,将其复制一份,然后命名为cluster.conf
,后续我们所有部署的 Nacos 实例地址都需要配置在这里。
我们以上文介绍的 Nacos 程序包为例,分别在本地以不同端点启动3个 Nacos 服务,配置如下:
# ip:port
197.168.12.192:8841
197.168.12.192:8842
197.168.12.192:8843
4.2.3、启动服务实例
将上文的 nacos 文件夹复制三份,分别命名为:nacos1、nacos2、nacos3。

然后分别修改三个文件夹中的application.properties
。
- nacos1
server.port=8841
- nacos2
server.port=8842
- nacos3
server.port=8843
最后,分别在 nacos1、nacos2、nacos3 的bin
文件夹下,执行启动命令。
sh startup.sh
访问其中任何一个 nacos 服务管理平台,点击集群管理,可以看到相关的节点信息。

到此,nacos 的集群节点部署已完成。
如果需要关闭服务实例,在bin
文件夹下,执行关停命令即可。
sh shutdown.sh
此时,如果 Spring Cloud 应用想要访问 Nacos 集群,可以通过如下方式实现。
spring.cloud.nacos.discovery.server-addr=197.168.12.192:8841,197.168.12.192:8842,197.168.12.192:8843
4.2.4、配置代理
根据上文的架构图所示,Nacos 的集群部署完成之后,我们还需要一个统一的入口用来维护 Nacos 的访问,能用的组件有很多种,比如 DNS、Nginx 等,以此来实现 Nacos 的负载均衡访问。
这里我们以 Nginx 作为代理组件为例,具体的实现思路如下。
修改conf/nginx.conf
文件,配置如下:
upstream nacoscluster {
server 197.168.12.192:8841;
server 197.168.12.192:8842;
server 197.168.12.192:8843;
}
server {
listen 8888;
server_name localhost;
location /nacos {
proxy_pass http://nacoscluster;
}
}
最后,将 Spring Cloud 中的 nacos 地址指向 nginx 所在的IP和端口地址即可。
spring.cloud.nacos.discovery.server-addr=197.168.12.192:8888
五、小结
最后总结一下,Nacos 是 Spring Cloud Alibaba 体系中最重要的组件之一,主要用于服务的注册中心和配置中心。
本文主要围绕 Nacos 用于服务注册中心使用进行一次知识内容的总结,下篇文章将会继续介绍 Nacos 用于服务配置中心的使用方式。
六、参考
1、https://sca.aliyun.com/docs/2.2.x/user-guide/nacos/overview/
2、https://spring.didispace.com/spring-cloud/spring-cloud-alibaba-1.html
3、https://juejin.cn/post/6926437744671457294
作者:潘志的技术笔记
出处:https://pzblog.cn/
版权归作者所有,转载请注明出处
