Spring Cloud Alibaba Nacos
代码地址:https://github.com/wicksonZhang/Spring-Cloud-Alibaba
1. 基础概念1.1. Nacos 解决了什么问题Nacos 主要解决了微服务中服务注册与发现和服务配置问题,在 Spring Cloud
中如果需要实现服务注册与发现和配置需要使用到 Eureka
、Spring Cloud Config
和 Spring Cloud Bus
。但现在只需要使用一个 Nacos
就可以解决问题。
1.2. Nacos 是什么
官网地址:https://nacos.io/
Github地址:https://github.com/alibaba/nacos
Nacos:Dynamic Naming and Configuration Service
的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它由阿里巴巴开源团队维护,旨在为现代微服务架构提供一套集成的解决方案。
1.3. 注册中心对比以下是 Nacos
相对于 Eureka
的一些优点:
动态配置管理: Nacos
不仅提供了服务注册与发现的功能,还集成了动态配置管理。
健康检查更灵活: Nacos
提供了更灵活的健康检查机制,支持不同的健康检查方式和策略。
更强大的集群管理: Nacos
在集群管理方面更为强大,支持多数据中心、多命名空间的配置管理和服务发现。
特性 / 注册中心
Nacos
Eureka
Zookeeper
Consul
服务发现
✔ 支持
✔ 支持
✔ 支持
✔ 支持
配置管理
✔ 支持
✖ 不支持(需结合Spring Cloud Config)
✖ 不支持(可结合其他配置中心)
✖ 不支持(可结合其他配置中心)
多数据中心支持
✔ 支持
✔ 支持
✖ 不支持
✔ 支持
动态 DNS 服务
✔ 支持
✖ 不支持
✖ 不支持
✖ 不支持
健康检查
✔ 支持
✖ 不支持(需结合Spring Cloud Health)
✔ 支持
✔ 支持
事件监听机制
✔ 支持
✔ 支持
✔ 支持
✔ 支持
支持协议
HTTP、DNS、gRPC等
HTTP
客户端/服务器模型,可扩展协议
HTTP,支持DNS
一致性协议
CP + AP
AP(强调可用性和分区容忍性)
CP 协议(强一致性)
CP + AP协议
生态系统整合
Spring Cloud Alibaba 生态系统
Spring Cloud 生态系统
社区广泛使用,适用于多种场景
Spring Cloud 生态系统
开发维护
阿里巴巴维护,活跃的社区
Netflix 维护,社区逐渐减少
Apache 维护,社区广泛使用
HashiCorp 维护,社区活跃
2. Nacos 安装启动
下载地址:https://github.com/alibaba/nacos
下载版本:nacos-server-2.0.1.zip
启动命令如下,如果看到了对应图标且不报错说明启动成功
默认启动是集群模式:startup.cmd
如果需要指定为单机模式:startup.cmd -m standalone
1 2 D:\software\nacos\bin>startup.cmd -m standalone "nacos is starting with standalone"
3. Nacos 单机操作
代码地址如下:
3.1. 实现需求1 2 1. 当用户访问消费者服务接口时,消费者服务会利用相应的路由将请求分派给特定的服务提供者。 2. 服务提供者则会根据配置中心的设定,检索相关内容,并将消息传递回消费者服务。
3.2. 实现结果
3.3. 实现步骤1 2 3 1. 创建 提供者1 服务,并将其注册到Nacos中。 2. 创建 提供者2 服务,并将其注册到Nacos中。 3. 创建 消费者 服务,并将其注册到Nacos中,通过 Nacos 的负载均衡将消费者的请求转发到服务提供者。
3.4. 服务提供者1实现步骤
1 2 3 4 5 Step-1: 创建 服务提供者1 02-spring-cloud-alibaba-nacos-producer1-2100 Step-2: 导入 pom.xml 依赖 Step-3: 创建 bootstrap.yml、application.yml Step-4: 创建启动类 SpringCloudAlibabaProducer1Application Step-5: 创建控制类 Producer1Controller
Step-2: 导入 pom.xml 依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <dependencies > <dependency > <groupId > cn.wickson.cloud.alibaba</groupId > <artifactId > 01-spring-cloud-alibaba-common</artifactId > <version > 1.0-SNAPSHOT</version > </dependency > <dependency > <groupId > com.alibaba.cloud</groupId > <artifactId > spring-cloud-starter-alibaba-nacos-discovery</artifactId > </dependency > <dependency > <groupId > com.alibaba.cloud</groupId > <artifactId > spring-cloud-starter-alibaba-nacos-config</artifactId > </dependency > </dependencies >
Step-3: 创建 bootstrap.yml、application.yml
bootstrap.yml
: 主要用于应用程序的引导阶段,会优先被加载。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 server: port: 2100 spring: application: name: spring-cloud-alibaba-nacos-producer cloud: nacos: discovery: server-addr: localhost:8848 config: server-addr: localhost:8848 file-extension: yaml management: endpoints: web: exposure: include: "*"
application.yml
:主要用于应用程序的主配置文件,如数据库连接、服务端口。
1 2 3 spring: profiles: active: dev
Step-4: 创建启动类 SpringCloudAlibabaProducer1Application
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @EnableDiscoveryClient @SpringBootApplication public class SpringCloudAlibabaProducer1Application { public static void main (String[] args) { SpringApplication.run(SpringCloudAlibabaProducer1Application.class, args); } }
Step-5: 创建控制类 Producer1Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Slf4j @Validated @RestController @RefreshScope @RequestMapping("/producer") public class Producer1Controller { @Value("${server.port}") private Integer serverPort; @Value("${config.info}") private String configInfo; @GetMapping(value = "/nacos") public String getProducerConfig () { return "The producer1 server.port: " + serverPort + " registered to nacos.The producer1 config:" + configInfo; } }
3.5. 服务提供者2实现步骤
1 2 3 4 5 Step-1: 创建 服务提供者1 02-spring-cloud-alibaba-nacos-producer2-2200 Step-2: 导入 pom.xml 依赖 Step-3: 创建 bootstrap.yml、application.yml Step-4: 创建启动类 SpringCloudAlibabaProducer2Application Step-5: 创建控制类 Producer2Controller
操作与服务提供者保持一致
3.6. 服务消费者实现步骤
1 2 3 4 5 6 Step-1: 创建 服务消费者 02-spring-cloud-alibaba-nacos-consumer-2300 Step-2: 导入 pom.xml 依赖 Step-3: 创建 application.yml Step-4: 创建启动类 SpringCloudAlibabaConsumerApplication Step-5: 创建控制类 ConsumerController Step-6: 创建 RestTemplate 配置类
Step-2: 导入 pom.xml 依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <dependencies > <dependency > <groupId > cn.wickson.cloud.alibaba</groupId > <artifactId > 01-spring-cloud-alibaba-common</artifactId > <version > 1.0-SNAPSHOT</version > </dependency > <dependency > <groupId > com.alibaba.cloud</groupId > <artifactId > spring-cloud-starter-alibaba-nacos-discovery</artifactId > </dependency > </dependencies >
Step-3: 创建 application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 server: port: 2300 spring: application: name: spring-cloud-alibaba-nacos-consumer cloud: nacos: discovery: server-addr: localhost:8848 service-url: nacos-user-service: http://spring-cloud-alibaba-nacos-producer
Step-4: 创建启动类 SpringCloudAlibabaConsumerApplication
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @EnableDiscoveryClient @SpringBootApplication(scanBasePackages = "cn.wickson.cloud.alibaba") public class SpringCloudAlibabaConsumerApplication { public static void main (String[] args) { SpringApplication.run(SpringCloudAlibabaConsumerApplication.class, args); } }
Step-5: 创建控制类 ConsumerController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @Slf4j @Validated @RestController @RequestMapping("/consumer") public class ConsumerController { @Resource private RestTemplate restTemplate; @Value("${service-url.nacos-user-service}") private String serverUrl; @GetMapping("/getProducer") public String getProducer () { return restTemplate.getForObject(serverUrl + "/producer/nacos" , String.class); } }
Step-6: 创建 RestTemplate 配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Configuration public class RestTemplateConfig { @Bean @LoadBalanced public RestTemplate restTemplate () { return new RestTemplate (); } }
3.7. 服务注册中心当 服务提供者1、服务提供者2、服务消费者 启动时,查看 服务管理 —> 服务列表
3.8. 服务配置中心由于我们需要通过在服务提供者中读取 config.info
的配置文件信息
1 Data ID = $ {spring.application.name}-$ {spring.profiles.active}.$ {spring.cloud.nacos.config.file-extension}
我们需要在 配置管理 —> 配置列表 —> + 中创建并配置如下内容
4. Nacos 配置说明在实际开发场景中,我们需要针对不同的开发环境采用不同的系统环境配置,如下是Nacos的领域模型。
Namespace
命名空间、Group
分组、Service/Data Id
这些都是为了进⾏归类管理,把服务和配置⽂件进⾏归类。
名词
描述
Namespace
用于隔离配置和服务的独立区域。例如开发环境、测试环境、生产环境。
Group
对同一个服务的不同实例进行逻辑上的分组。例如,我们有两个项目都需要使用我们的 Nacos。我们可以在同一个 NameSpace 中通过 Group 将他们隔开。
Service
一个具体的应用或服务实例,可通过服务注册进行管理。例如,对应具体的应用,如订单服务。
DataId
用于唯一标识一个配置项,与服务名、分组和命名空间一起使用。例如,订单服务对应的配置文件名称。
4.1. NameSpaceNameSpace:
命名空间,针对不同的环境进行隔离。在 Nacos
中 NameSpace
的默认空间是 public
。
在配置文件中指定命名空间的配置如下,我们指定 dev
的命名空间:
1 2 spring.cloud.nacos.config.namespace=571e7679-ab13-4608-abf4-e1a3618398e5
我们需要在 命名空间 —> 新建命名空间 中创建并配置,其中我创建 dev
命名空间为例子。
4.2. GroupGroup:一个 NameSpace
下有多个 Group ,其中 Group 默认为 DEFAULT_GROUP
,可以将不同的微服务划分到不同的组。也可以将不同的项目以不同的组进行区分。
在配置文件中指定组名的配置如下,我们指定 NACOS_DEV_GROUP
组。
1 2 spring.cloud.nacos.config.group=NACOS_DEV_GROUP
我们需要在 配置管理 —> 配置列表 中创建,在 dev
命名空间下,其中我创建 NACOS_DEV_GROUP
组例子。
4.3. Data IDData ID:对应一个服务的配置与服务名、分组和命名空间一起使用。
1 2 spring-cloud-alibaba-nacos-producer-dev.yaml
我们需要在 配置管理 —> 配置列表 中创建,与创建 Group 时一起创建,具体的配置规则如下
4.4. 测试结果我们以上诉 Naocs
单机操作 案例,重新修改上述 服务提供者1 、服务提供者2 的 yml 配置文件
1 2 3 spring: profiles: active: dev
1 2 3 4 5 6 7 8 9 10 11 12 spring: application: name: spring-cloud-alibaba-nacos-producer cloud: nacos: discovery: server-addr: localhost:8848 config: server-addr: localhost:8848 file-extension: yaml namespace: 571e7679 -ab13-4608-abf4-e1a3618398e5 group: NACOS_DEV_GROUP
5. Nacos 集群操作集群模式:主要的作用还是为了保高可用,即使其中的一台 Nacos
宕机也不会影响项目的正常使用。
5.1. 实现需求1 2 1. 搭建三台 Nacos 集群,实现相互通讯。 2. 并采用两种方式进行测试:ip直连模式、Nginx代理转发
5.2. 实现结果
ip直连模式: 在配置文件中直接配置三个 Nacos
的 ip
地址.
5.3. 实现步骤
1 2 3 4 5 6 1. 创建 MySQL 服务:192.168.10.16 2. 创建 Nacos1 服务:192.168.10.17, 配置 Nacos 集群服务 3. 创建 Nacos2 服务:192.168.10.18, 配置 Nacos 集群服务 4. 创建 Nacos3 服务:192.168.10.19, 配置 Nacos 集群服务 6. 实现 ip 直连模式 7. 实现 Nginx 代理转发模式
5.4. 创建 MySQL 服务
由于我们单机版中使用的是 Nacos 自带的数据库,但是在集群版中这是不行的,所以让三台服务连接外部数据库
数据文件 nacos-mysql.sql 将数据库导入到 自己创建的数据库 nacos_config
中,具体操作如下。
5.5. 创建 Nacos 服务
下载地址:https://github.com/alibaba/nacos
下载版本:nacos-server-2.0.1.tar.gz
注意:我们三台配置都是一样的,我只以其中 192.168.10.17 为例子
5.5.1. 修改 cluster.conf
文件1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 [root@localhost conf] /home/nacos/conf [root@localhost conf] [root@localhost conf] 总用量 88 -rw-r--r--. 1 502 games 1224 4月 19 2021 1.4.0-ipv6_support-update.sql -rw-r--r--. 1 502 games 8489 4月 29 2021 application.properties -rw-r--r--. 1 502 games 6515 4月 19 2021 application.properties.example -rw-r--r--. 1 root root 670 1月 24 17:47 cluster.conf -rw-r--r--. 1 502 games 670 3月 18 2021 cluster.conf.example -rw-r--r--. 1 502 games 31156 4月 29 2021 nacos-logback.xml -rw-r--r--. 1 502 games 10660 4月 19 2021 nacos-mysql.sql -rw-r--r--. 1 502 games 8795 4月 19 2021 schema.sql [root@localhost conf] 192.168.10.17:8848 192.168.10.18:8848 192.168.10.19:8848 [root@localhost conf]
5.5.2. 修改 application.yml
文件1 2 3 4 5 6 7 8 9 10 [root@localhost conf] /home/nacos/conf [root@localhost conf] spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://192.168.10.16:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true &useUnicode=true &useSSL=false &serverTimezone=UTC db.user.0=root db.password.0=P@ssw0rd
5.5.3. 启动 Nacos1 2 3 4 5 6 7 8 9 10 11 12 13 14 [root@localhost nacos] [root@localhost bin] 总用量 20 -rwxr-xr-x. 1 502 games 954 5月 14 2020 shutdown.cmd -rwxr-xr-x. 1 502 games 951 3月 18 2021 shutdown.sh -rwxr-xr-x. 1 502 games 3340 4月 19 2021 startup.cmd -rwxr-xr-x. 1 502 games 4923 4月 19 2021 startup.sh [root@localhost bin] [root@localhost bin] /home/java/jdk1.8.0_171/bin/java -server -Xms2g -Xmx2g -Xmn1g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/nacos/logs/java_heapdump.hprof -XX:-UseLargePages -Dnacos.member.list= -Djava.ext.dirs=/home/java/jdk1.8.0_171/jre/lib/ext:/home/java/jdk1.8.0_171/lib/ext -Xloggc:/home/nacos/logs/nacos_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -Dloader.path=/home/nacos/plugins/health,/home/nacos/plugins/cmdb -Dnacos.home=/home/nacos -jar /home/nacos/target/nacos-server.jar --spring.config.additional-location=file:/home/nacos/conf/ --logging.config=/home/nacos/conf/nacos-logback.xml --server.max-http-header-size=524288 nacos is starting with cluster nacos is starting,you can check the /home/nacos/logs/start.out [root@localhost bin] tcp6 0 0 :::8848 :::* LISTEN 1377/java
5.5.4. 开放端口
1 2 3 4 5 [root@localhost bin] success [root@localhost bin] success [root@localhost bin]
1 2 3 4 5 [root@localhost bin]# firewall-cmd --zone=public --add-port=9849/tcp --permanent success [root@localhost bin]# firewall-cmd --reload success [root@localhost bin]#
5.6. ip 直连模式ip直连: 上诉我们已将搭建好了三台 Nacos
服务器信息,我们只需要在 yml
配置文件中修改 Nacos
服务注册地址即可,具体如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 server: port: 2200 spring: application: name: spring-cloud-alibaba-nacos-producer cloud: nacos: discovery: server-addr: 192.168 .10 .17 :8848,192.168.10.18:8848,192.168.10.19:8848 config: server-addr: 192.168 .10 .17 :8848,192.168.10.18:8848,192.168.10.19:8848 file-extension: yaml namespace: fc1c8c25-c514-4430-9197-3148654af6ab group: NACOS_DEV_GROUP
5.7. Nginx 代理转发Nginx代理转发: 本质上就是通过配置了一个 负载均衡 分别路由到不同的 Nacos 中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 upstream nacos_server { server 192.168.10.17:8848 ; server 192.168.10.18:8848 ; server 192.168.10.19:8848 ; } server{ listen 8001 ; server_name nacos_server; location / { proxy_set_header Host $http_host ; proxy_set_header X-Real-IP $remote_addr ; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ; proxy_pass http://nacos_server; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 server: port: 2200 spring: application: name: spring-cloud-alibaba-nacos-producer cloud: nacos: discovery: server-addr: 192.168 .10 .20 :8001 config: server-addr: 192.168 .10 .20 :8001 file-extension: yaml namespace: fc1c8c25-c514-4430-9197-3148654af6ab group: NACOS_DEV_GROUP