Spring Colud Alibaba Nacos微服务组件的使用教程
什么是nacos
Dynamic Naming and Configuration Service(动态命名和配置服务)
nacos可以作为服务注册中心
nacos可以作为配置中心
nacos即支持AP也支持CP
下载安装Nacos
下载地址:https://github.com/alibaba/nacos/releases/download/2.5.0/nacos-server-2.5.0.zip
解压后,进入bin目录
通过"startup.cmd -m standalone"脚本启动,以单机模式启动
# 单机模式(开发环境)
startup.cmd -m standalone
# 集群模式(生产环境)
startup.cmd -m cluster
默认的运行端口为8848,默认的登陆账户是nacos,默认密码是nacos
访问http://localhost:8848/nacos验证nacos启动成功
nacos注册中心案例
在微服务项目父模块依赖管理中引入公共依赖,指定版本
<!--以pom依赖的形式导入spring-cloud-alibaba-dependencies依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2021.0.5.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
分别在各个微服务模块引入nacos的服务发现模块
<!--引入nacos的服务发现依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
分别在各个微服务模块中配置naocs
spring:
application:
name: member-consumer
cloud:
nacos:
discovery:
#配置nacos服务注册中心的地址
server-addr: localhost:8848
分别在各个微服务中使用注解"@EnableDiscoveryClient"启用服务发现功能
package anyi.space.memberConsumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @ProjectName: distributedSystemLearn
* @FileName: MemberConsumerApplication
* @Author: 杨逸
* @Data:2025/4/13 20:05
* @Description:
*/
@EnableDiscoveryClient
@SpringBootApplication(exclude= DataSourceAutoConfiguration.class)
public class MemberConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(MemberConsumerApplication.class,args);
}
}
启动各个微服务,在浏览器中访问http://localhost:8848/nacos查看nacos的管理面板,验证各个微服务是否成功注册到nacos注册中心
服务消费方利用nacos注册中心通过服务名称消费服务提供方
在服务消费方导入LoadBanlcer依赖
<!--新版的nacos负载均衡组件使用的是LoadBalancer,旧版使用的是Ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<version>3.1.5</version>
</dependency>
使用RestTemplate进行远程调用,默认的负载均衡算法是轮询
注入一个RestTemplate
package anyi.space.memberConsumer.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @ProjectName: distributedSystemLearn
* @FileName: RestTemplateConfig
* @Author: 杨逸
* @Data:2025/4/13 20:06
* @Description:
*/
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
远程调用使用服务名称
package anyi.space.memberConsumer.service.impl;
import anyi.sapce.common.entity.Member;
import anyi.sapce.common.entity.ResponseResult;
import anyi.space.memberConsumer.service.MemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
/**
* @ProjectName: distributedSystemLearn
* @FileName: MemberServiceIml
* @Author: 杨逸
* @Data:2025/4/13 20:10
* @Description:
*/
@RequiredArgsConstructor
@Service
public class MemberServiceIml implements MemberService {
private final RestTemplate restTemplate;
//基本的服务名
public static final String BASE_URL = "http://member-service-provider";
@Override
public ResponseResult getById(Long id) {
/**
* 使用服务名通过RestTemplate调用远程服务
*/
ResponseEntity<ResponseResult> resultResponseEntity = restTemplate.getForEntity(BASE_URL + "/member-provider/member?id="+id, ResponseResult.class);
return resultResponseEntity.getBody();
}
@Override
public boolean save(Member member) {
//直接传递参数,是使用json的格式提交数据
ResponseEntity<ResponseResult> responseResultResponseEntity = restTemplate.postForEntity(BASE_URL + "/member-provider/member", member, ResponseResult.class);
//HttpEntity<String> stringHttpEntity = new HttpEntity<>();
Object data = responseResultResponseEntity.getBody().getData();
boolean flag = (boolean) data;
return flag;
}
}
通过postman验证可以正确通过服务名称调用服务,且是负载均衡算法是轮询的
nacos负载均衡
新版的nacos使用的LoadBalancer进行负载均衡,旧版使用的是Ribbon
Nacos中AP和CP的切换
分布式系统中的三大原则,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性)
Nacos默认使用的是AP模式
AP:数据强一致性,服务不一定可用
CP:服务一定可用,数据会短暂不一致,但数据是最终一致
使用Nacos开放的RestAPI进行切换,注意使用PUT请求方式进行调用
- 切换为AP模式
curl -X PUT http://localhost:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=AP
- 切换为CP模式
curl -X PUT http://localhost:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP
nacos配置中心案例
- 在微服务模块中导入nacos配置中心的依赖
<!--nacos配置中心依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
-
在bootstarp.yaml配置文件中配置nacos配置中心的地址
- 在Spring Cloud 2020.0.2版本后,bootstarp.yaml配置配置文件被禁用了,需要引入依赖
<!--在新版的springcloud应用中使用bootstarp配置文件,需要引入这个依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> <version>3.1.5</version> </dependency>
- 通过"spring.cloud.nacos.config.server-addr"配置nacos配置中心服务的地址
- 通过"spring.cloud.nacos.config.file-extension"配置匹配nacos配置中心配置文件的后缀
- 通过"spring.cloud.nacos.config.prefix"配置匹配nacos配置中心配置文件的前缀
- 配置中心的DataId匹配格式为:
${spring.cloud.nacos.config.prefix}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
- nacos配置中心中通过namespace(名称空间),group(分组),dataId(配置id)三者唯一标识一个配置
server:
port: 5000
servlet:
context-path: /nacos-config-client
spring:
cloud:
nacos:
discovery:
#注册中心服务地址
server-addr: localhost:8848
#匹配nacos配置中心中DataId为: ${spring.cloud.nacos.config.prefix}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} 的配置文件
config:
#配置中心服务地址
server-addr: localhost:8848
#配置文件后缀
file-extension: yaml
#配置文件前缀,默认值为spring.application.name
prefix: ${spring.application.name}
#配置分组名称,默认为:DEFAULT_GROUP
group: DEFAULT_GROUP
#配置文件命名空间,默认为:public
namespace: public
application:
name: nacos-config-client
- 在application.yaml配置使用哪个环境的配置
- 通过"spring.profiles.active"参数配置使用哪个环境的配置文件
- test表示测试环境
- dev表示开发环境
- prod表示生产环境
- springboot中配置文件的加载是存在优先级顺序的,bootstrap.yml优先级高于application.yml
spring:
profiles:
#使用哪个环境的配置文件
#test:测试环境,dev:开发环境,prod:生产环境
active: test
- 在nacos配置中心创建配置,使用yaml格式,注意dataId要与客户端配置中的
${spring.cloud.nacos.config.prefix}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
保持一致
config:
info: 杨逸在学nacos的配置中心
name: 配置中心
- 创建一个测试Controller,验证成功从nacos配置中心中拉取配置信息
- 使用"@Value"注解从配置中获取信息
- 使用"@RefreshScope"注解配置自动刷新配置,当配置中心的配置发生变更时,运行的springboot程序能自动更新配置的值
package space.anyi.nacosConfigClient.controller;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @ProjectName: distributedSystemLearn
* @FileName: NacosConfigClientController
* @Author: 杨逸
* @Data:2025/9/14 18:02
* @Description: 测试nacos配置中心的controller
*/
@Data
@RestController()
@RequestMapping("/config")
//@RefreshScope表示自动刷新配置,配合配置中心实现配置的动态刷新
@RefreshScope
public class NacosConfigClientController {
@Value("${config.info}")
private String configInfo;
@Value("${config.name}")
private String configName;
@GetMapping("/info")
public String getConfigInfo(){
return configInfo;
}
@GetMapping("/name")
public String getConfigName(){
return configName;
}
}
-
使用postman接口测试验证,拉取nacos配置中心的配置成功
Nacos配置隔离方案
flowchart TD
subgraph Nacos配置管理系统
N1[Namespace: 公司A]
N2[Namespace: 公司B]
subgraph N1_Sub [公司A内部配置]
G1[Group: 前端组]
G2[Group: 后端组]
G3[Group: 移动端组]
subgraph G1_Sub [前端组配置]
D1[DataId: 开发环境]
D2[DataId: 测试环境]
D3[DataId: 生产环境]
end
subgraph G2_Sub [后端组配置]
D4[DataId: 开发环境]
D5[DataId: 测试环境]
D6[DataId: 生产环境]
end
subgraph G3_Sub [移动端组配置]
D7[DataId: 开发环境]
D8[DataId: 测试环境]
D9[DataId: 生产环境]
end
end
subgraph N2_Sub [公司B内部配置]
G4[Group: 前端组]
G5[Group: 后端组]
G6[Group: 大数据组]
subgraph G4_Sub [前端组配置]
D10[DataId: 开发环境]
D11[DataId: 测试环境]
D12[DataId: 生产环境]
end
subgraph G5_Sub [后端组配置]
D13[DataId: 开发环境]
D14[DataId: 测试环境]
D15[DataId: 生产环境]
end
subgraph G6_Sub [大数据组配置]
D16[DataId: 开发环境]
D17[DataId: 测试环境]
D18[DataId: 生产环境]
end
end
end
N1 --> N1_Sub
N2 --> N2_Sub
G1 --> G1_Sub
G2 --> G2_Sub
G3 --> G3_Sub
G4 --> G4_Sub
G5 --> G5_Sub
G6 --> G6_Sub
%% 样式设置
classDef namespace fill:#bbdefb,stroke:#1e88e5,stroke-width:2px;
classDef group fill:#e1bee7,stroke:#8e24aa,stroke-width:2px;
classDef dataid fill:#c8e6c9,stroke:#43a047,stroke-width:2px;
class N1,N2 namespace;
class G1,G2,G3,G4,G5,G6 group;
class D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,D11,D12,D13,D14,D15,D16,D17,D18 dataid;
naocs中有三种方式进行配置隔离,第一种是DataId,第二种是Group(分组),第三种是NameSpace(命名空间)
一般DataId的隔离场景是在同一个项目中,用于区分开发,测试,生产三种不同环境使用的配置
Group(分组隔离)的应用场景是在同一个企业中的不项目组中
NameSpace(命名空间)隔离的使用场景是在不同的企业与企业之间
基于DataId的配置隔离
-
在nacos创建一个新的dev配置
config: info: 学习基于DataId的配置隔离方案 name: 基于DataId的配置隔离
-
在nacos客户端配置
spring: profiles: #使用哪个环境的配置文件 #test:测试环境,dev:开发环境,prod:生产环境 active: dev
-
通过postman测试
基于Group(分组)的配置隔离
-
在nacos配置中心中创建一个新的测试配置
- 在Group中填入"GROUP_YANGYI",创建一个新的分组
config: info: 杨逸在学nacos的基于分组的配置隔离 name: 基于分组隔离的配置中心
-
在nacos客户端中配置分组信息
- 通过"spring.cloud.nacos.config.group"参数配置分组信息
server: port: 5000 servlet: context-path: /nacos-config-client spring: cloud: nacos: discovery: #注册中心服务地址 server-addr: localhost:8848 #匹配nacos配置中心中DataId为: ${spring.cloud.nacos.config.prefix}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} 的配置文件 config: #配置中心服务地址 server-addr: localhost:8848 #配置文件后缀 file-extension: yaml #配置文件前缀,默认值为spring.application.name prefix: ${spring.application.name} #配置分组名称,默认为:DEFAULT_GROUP group: GROUP_YANGYI #配置文件命名空间,默认为:public namespace: public application: name: nacos-config-client
-
通过postman测试
基于NameSpace(命名空间)的配置隔离
-
在nacos中创建一个新的命名空间"yangyi"
-
注意namespace的ID,在nacos配置namespace时需要使用到
-
切换到"yangyi"的namespace(命名空间)
-
命名空间"yangyi"中新建一个测试配置
-
在nacos客户端配置namespace(命名空间)
- 通过"spring.cloud.nacos.config.namespace"参数配置分组信息,注意配置namespace时,除了默认的public,其他的namespace配置使用的是namespace的ID
server: port: 5000 servlet: context-path: /nacos-config-client spring: cloud: nacos: discovery: #注册中心服务地址 server-addr: localhost:8848 #匹配nacos配置中心中DataId为: ${spring.cloud.nacos.config.prefix}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} 的配置文件 config: #配置中心服务地址 server-addr: localhost:8848 #配置文件后缀 file-extension: yaml #配置文件前缀,默认值为"spring.application.name"参数的值 prefix: ${spring.application.name} #配置分组名称,默认为:DEFAULT_GROUP group: DEFAULT_GROUP #配置文件命名空间,默认为:public,配置其他的namespace时,使用的namespace的ID namespace: 0901089c-92c1-40fa-bf3c-b98d434061bc application: name: nacos-config-client
-
通过postman测试