Nacos
主要是用来做服务注册
0. 为什么需要服务注册中心
随着行业的发展,原来的单体架构演变为现在推崇的微服务架构,但是随之而来也带来一些问题,比如:服务之间的调用,如果业务表简单,下图就可以满足:

这时A需要记录B的 IP和端口号,才能调用成功,但是如果B服务做成集群,如下图

这时就要修改A服务,写上B2的IP和端口号,这样做是及其不合理的,所以需要服务注册中心

1. 介绍
官方解释:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
全称:Dynamic Naming and Configuration Service,其实就是一个注册和配置中心
注意:这是一个独立的应用
1. 下载
官方地址:https://nacos.io/zh-cn/

github地址:https://github.com/alibaba/Nacos

下载地址:https://github.com/alibaba/nacos/releases/tag/2.0.4


2. 文档
3. 安装
1. mac
下载压缩包后,解压:

启动
#进入bin目录
@B-R33MG8WN-0319 ~ % cd soft/nacos/bin
#执行启动命令
@B-R33MG8WN-0319 bin % sh startup.sh -m standalone
之后可以看到一下输出:

打开对应的日志文件:


这就算启动成功了
关闭nacos:
2. Centos7
- 上传压缩包到 /home/soft 目录(注意:先安装JDK)

- 执行:tar -zxvf nacos-server-2.0.4.tar.gz,解压

- 修改启动参数
默认情况下nacos占内存较大,进入 bin 目录 修改 startup.sh 启动文件,比如:

修改后:

- 在 bin 目录下执行:./startup.sh -m standalone


也可以执行: ps -ef | grep nacos, 查看 nacos 进程

- 关闭 nacos,在 bin 目录下执行:./shutdown.sh

3. windows
解压到指定目录中

打开命令行,切换到nacos安装目录的bin文件夹先,然后执行:startup.cmd -m standalone

关闭:Ctrl + c
4. 使用
浏览器中输入:IP地址:8848/nacos

账户:nacos,密码:nacos

上图看到服务列表是空的,因为目前并没有服务往上面注册
2. 服务注册
1. 创建一个普通的maven项目


1. pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.11</version>
</parent>
<dependencyManagement>
<dependencies>
<!--声明 springcloud 依赖版本-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--声明 springcloud alibaba 依赖版本-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2021.0.4.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2. Provider
新建一个model,起名:provider-service

1. pom.xml
<dependencies>
<!-- nacos 相关依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- spring boot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2. application.properties
# 端口
server.port=8100
# 应用名称
spring.application.name=nacos-provider-service
# nacos地址
spring.cloud.nacos.discovery.server-addr=192.168.56.103:8848
3. 启动类
@SpringBootApplication
// spring提供的注解,用于服务发现(让注册中心可以发现自己),其实也可以注掉,目前版本不需要这个这个注解也能注册到nacos上
@EnableDiscoveryClient
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
4. 结果
启动项目后,访问nacos

3. Consumer
跟Provider类似,不再重复
完成后查看Nacos

3. 通信
实现 consumer 和 provider 的通信
在provider中新建立一个ProviderController

代码:
@RestController
public class ProviderController {
@Value("${server.port}")
private int port;
@GetMapping("/getport")
public int getport(){
return port;
}
}
在consumer中新建立一个ConsumerController
@RestController
public class ConsumerController {
//使用discoveryClient 获取服务
// 注意:是这个包 org.springframework.cloud.client.discovery
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/getport")
public String test(){
//根据服务名获取服务实例列表
List<ServiceInstance> instances = discoveryClient.getInstances("nacos-provider-service");
// 获取第一个服务信息
ServiceInstance instanceInfo = instances.get(0);
//获取ip
String ip = instanceInfo.getHost();
//获取port
int port = instanceInfo.getPort();
String url ="http://"+ip+":"+port+"/getport";
//使用 RestTemplate 来进行远程调用
RestTemplate restTemplate = new RestTemplate();
return restTemplate.getForObject(url, String.class);
}
}
重启 provider 和 consumer,然后访问 consumer 的getport接口:http://localhost:8200/getport


4. 负载均衡
1. Provider集群
再Provider的application.properties文件中,把server.port这个配置干掉
然后:


点击左上角的复制按钮:

分别启动8100和8101,然后再nacos上查看:

点击上图中的 详情

2. LoadBalancer
- 修改 consumer 中的pom.xml,增加:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
- 创建一个配置类Config:
![image.png]()
注意:上图中的@LoadBalanced注解不可少
@Configuration
public class Config {
@Bean
@LoadBalanced // 支持负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
- 修改ConsumerController,增加
@Autowired
private RestTemplate restTemplate;
@GetMapping("/balance2")
public int balance2(){
String url ="http://nacos-provider-service/getport";
return restTemplate.getForObject(url, int.class);
}
- 重启后,浏览器访问:http://localhost:8200/balance2
![image.png]()
![image.png]()
3. 负载均衡策略
1. RoundRobinLoadBalancer
RoundRobinLoadBalancer:轮训策略,默认使用的就是这种
查看 LoadBalancerClientConfiguration 类,可以看到:

2. RandomLoadBalancer
RandomLoadBalancer:随机策略
修改 Config :
@Configuration
//需要使用LoadBalancerClients注解
@LoadBalancerClients(defaultConfiguration = {Config.class})
public class Config {
@Bean
@LoadBalanced // 支持负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
//使用随机策略
@Bean
public ReactorLoadBalancer<ServiceInstance> reactorLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(
loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
}
}
3. NacosLoadBalancer
NacosLoadBalancer:根据权重进行随机,权重越大选中的概率越大
nacos中可以设置权重,比如:

修改 Config:
@Configuration
@LoadBalancerClients(defaultConfiguration = {Config.class})
public class Config {
@Bean
@LoadBalanced // 支持负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
@Bean
public ReactorLoadBalancer<ServiceInstance> reactorLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
//使用 NacosLoadBalancer :根据权重随机
return new NacosLoadBalancer(
loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name,nacosDiscoveryProperties);
}
}
重启 Consumer 后,访问结果:

5. 集成Feign
feign本质是对 restTemplate 的封装,使服务之间的调用更简单
修改 Consumer
1. pom.xml
<!-- openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2. 启动类
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients//开启Feign
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
3. 业务代码
新增 ProviderService
@FeignClient(value = "nacos-provider-service")
public interface ProviderService {
// 配置请求路径
@GetMapping("/getport")
int getPort();
}
修改 ConsumerController,增加
@Autowired
private ProviderService providerService;
@GetMapping("/getport2")
public int getport2(){
return providerService.getPort();
}
4. 结果
浏览器访问:http://localhost:8200/getport2

6. Config中心
nacos 除了用于服务注册,还可以作为配置中心
1. bootstrap方式
1. pom.xml
修改 consumer-service 中的 pom.xml,增加
<!-- nacos 配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
2. properties
新增 bootstrap.properties
#配置中心地址
spring.cloud.nacos.config.server-addr=localhost:8848
3. Nacos
在nacos中,增加一个配置



4. Controller
@RestController
public class ConfigController {
@Value("${hero.name}")
private String heroName;
@GetMapping("/hero")
public String hero(){
return heroName;
}
}
5. 结果
重启 consumer 后访问:

2. spring.config.import
新版本的 springBoot 废除 bootstrap,推荐:spring.config.import
- pom.xml注释掉 bootstrap 的依赖

- 删除 bootstrap.properties
- application.properteis中,增加:
spring.cloud.nacos.config.server-addr=192.168.110.102:8848
#格式:nacos:dataId
spring.config.import=nacos:${spring.application.name}
- 结果:

3. 动态刷新
使用RefreshScope注解,在Nacos中修改配置后,代码中能自动获取最新的值

重启 Consumer 后,浏览器访问:http://localhost:8200/hero

在 nacos 上修改 consumer 的配置

浏览器访问:http://localhost:8200/hero

4. 加载指定文件
1. Group
通过 Group 选择不同的配置
1. Nacos
增加两个Data ID相同,但是Group不同的配置


2. properties
修改 application.properties , 增加:
#配置group
spring.cloud.nacos.config.group=DEV_GROUP
spring.config.import=nacos:nacos-consumer-service-info
3. 结果
spring.cloud.nacos.config.group=DEV_GROUP

spring.cloud.nacos.config.group=PRD_GROUP

2. Namespace
1. Nacos
新建两个命名空间

可以在配置列表中看到

dev中新增一个配置

prd中新增一个配置

这两个配置,Data ID 和 Group都一样,但是命名空间不同。
2. properties
修改 application.properties , 增加:
#命名空间,配置命名空间ID
spring.cloud.nacos.config.namespace=a227b467-dec4-4620-99f1-3defebf6adbf
3. 结果
spring.cloud.nacos.config.namespace=a227b467-dec4-4620-99f1-3defebf6adbf

spring.cloud.nacos.config.namespace=prd

5. 使用Mysql
nacos默认使用嵌入式数据库(derby)实现数据的存储,不方便观察数据存储的情况。
但它同时支持mysql,地址:https://nacos.io/zh-cn/docs/deployment.html

1. nacos-mysql.sql
-
先新建一个数据库:nacos
![image.png]()
-
在nacos安装目录中找到:nacos/conf/nacos-mysql.sql,在你的mysql客户端执行
![image.png]()
执行完,在左侧就可以看到创建的表
2. properties
在nacos安装目录中找到:nacos/conf/application.properties,在文件最下方加入:
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://localhost:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&serverTimezone=UTC
db.user=用户名
db.password=密码

注意:如果你的mysql是没有密码的,需要设置一个密码,否则nacos启动报错,
比如:

3. 结果
重启nacos,会发现之前的配置都没有了,就证明切换成的mysql

新增一个配置

在mysql中可以查看到









浙公网安备 33010602011771号