【笔记】Nacos学习笔记

前言

Nacos (official site: nacos.io) is an easy-to-use platform designed for dynamic service discovery and configuration and service management. It helps you to build cloud native applications and microservices platform easily.(Github

部署Nacos服务端

Nacos项目下载

1
2
3
wget https://github.com/alibaba/nacos/releases/download/1.4.4/nacos-server-1.4.4.tar.gz
tar -xzvf nacos-server-2.1.2.tar.gz -C .
cd nacos

启动Nacos服务

  • 默认占用8848端口
1
sh bin/startup.sh -m standalone

访问管理页面

用户名:nacos
密码:nacos

完成

父级依赖

  • 通过父级依赖统一控制子级依赖的版本
pom.xml
1
2
3
4
5
6
7
8
9
10
11
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

Nacos客户端使用

添加依赖

pom.xml
1
2
3
4
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

修改配置

  • 注册服务到注册中心,指定服务中心的地址

spring.application.name:指定服务名称
spring.cloud.nacos.server-addr:指定Nacos注册中心的地址

src/main/resources/application.yml
1
2
3
4
5
6
spring:
application:
name: 服务名称
cloud:
nacos:
server-addr: http://127.0.0.1:8848

通过服务名称访问服务

1
2
String url = "http://eureka-service-user/users/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);

Nacos作为注册中心的配置

负载均衡方式配置

轮询方式

  • 默认不添加额外的配置,将采用轮询的方式

集群方式

  • 将服务添加到集群

spring.cloud.nacos.discovery.cluster-name:指定集群名称。如果没有指定集群,那么为默认集群,也就是没有配置集群
服务名.ribbon.NFLoadBanlancerRuleClassName:为指定服务配置负载均衡方式

com.alibaba.cloud.nacos.ribbon.NacosRule:优先选择集群内的实例,在集群内随机选择实例

src/main/resources/application.yml
1
2
3
4
5
6
7
8
spring:
cloud:
nacos:
discovery:
cluster-name: 集群名
服务名:
ribbon:
NFLoadBanlancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
权重配置
  • 通过权重配置,改变在集群内选择的优先级

  • 权重的配置范围为[0,1],权重越高被访问的频率越高,如果为0表示完全不会被访问

  • 在管理页面,选择一个服务需要配置的权重,点击详情

  • 编辑->修改权重->确定

环境隔离

  • Group分组名称:通常用于业务功能相关的服务作为一组,默认不配置为DEFAULT_GROUP分组
  • Namespace命名空间:通常用于将开发环境、测试环境、生产环境的隔离,默认不配置为public命名空间
    • 在不同命名空间内的服务无法互相调用

新建命名空间

  • 命名空间->新建命名空间->填写命名空间名描述,如果不填写命名空间ID将会自动生成->确定

修改配置

  • 将服务添加到命名空间

spring.cloud.nacos.discovery.namespace:指定命名空间名

src/main/resources/application.yml
1
2
3
4
5
spring:
cloud:
nacos:
discovery:
namespace: 命名空间ID

临时实例与非临时实例

  • 在Nacos中默认创建的都是非临时实例,非临时实例的心跳检测方式与Eureka一样,都是客户端向服务端发起心跳,当服务端接收不到心跳后,会立即从列表中剔除
  • 如果将实例改为了非临时实例,心跳检测将变为服务端向客户端询问的方式,当检测到客户端有问题后,不会立即从列表中剔除,而是将健康状态改为不健康
  • Nacos采用的是Pull和Push的结合,当出现了异常实例,会主动告诉消费者异常情况

修改配置

spring.cloud.nacos.diiscovery.ephemeral:设置是否为临时实例

true:缺省值,临时实例
false:非临时实例

src/main/resources/application.yml
1
2
3
4
5
spring:
cloud:
nacos:
diiscovery:
ephemeral: false

Nacos作为配置管理的配置

服务端发布需要更新的配置

  • 配置管理->配置列表->+

  • 指定需要更新的配置的ID为服务名-环境名.yaml->修改配置格式YAML->在配置内容中添加需要更新的配置信息

客户端读取需要更新的配置

  • 为了能在项目启动后先读取Nacos中需要更新的配置,再读取项目的配置,需要把Nacos的连接信息配置在bootstrap.yml配置文件中,这样在项目启动后,会先从bootstrap.yml配置文件中获取Nacos的连接信息,再连接Nacos获取需要更新的配置,最后读取项目配置,实现配置的热更新

添加依赖

pom.xml
1
2
3
4
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

添加配置

  • 新建一个bootstrap.yml配置文件,添加服务名称、开发环境、Nacos地址、配置文件类型的配置

spring.application.name:服务名称
spring.profiles.active:环境名称
spring.cloud.nacos.server-addr:Nacos服务端地址
spring.cloud.nacos.config:配置文件类型

src/main/resources/bootstrap.yml
1
2
3
4
5
6
7
8
9
10
spring:
application:
name:
profiles:
active: dev
cloud:
nacos:
server-addr: http://127.0.0.1:8848
config:
file-extension: yaml

获取更新的配置

准备工作
更新的配置
1
2
myproperties:
key: value
方式一
直接使用更新的配置
  • 将自定义配置注入到变量
1
2
@Value(${myproperties.key})
private String value;
添加热更新配置(可选)
  • 微服务无需重启就可以感知
  • 在主启动类添加@RefreshScope注解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.context.config.annotation.RefreshScope;

@RefreshScope
@SpringBootApplication
@MapperScan("com.dao")
public class OrderDemoApplication {

public static void main(String[] args) {
SpringApplication.run(OrderDemoApplication.class, args);
}

}
方式二
直接使用更新的配置
  • 将整个自定义配置注入到类
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.pojo;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "myproperties")
public class MyProperties {

private String name;
}
  • 注入到变量
1
2
@Value(${myproperties.key})
private String value;
添加热更新配置(可选)
  • 微服务无需重启就可以感知
  • 通过将自定义配置注入到类得到配置的方式,无需额外配置即可实现热更新

多环境配置共享

  • 在添加需要更新的配置时,配置ID不指定环境名,默认会将所有环境的配置都更新

  • 配置管理->配置列表->+

  • 指定需要更新的配置的ID为服务名.yaml->修改配置格式YAML->在配置内容中添加需要更新的配置信息

多环境配置的优先级

  • 远端服务名-环境名.yml>远端服务名.yml>本地application.yml

踩坑

  • 启动失败,报错:Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

解决问题

  • 添加配置,当出现相同名字的类进行注册时,准许覆盖注册
src/main/resources/application.yml
1
2
3
spring:
main:
allow-bean-definition-overriding: true

踩坑

  • 启动失败:报错Consider defining a bean of type 'com.netflix.client.config.IClientConfig' in your configuration.

解决问题

  • 添加Bean
src/main/java/conf/MyConfig.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.conf;

import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.client.config.IClientConfig;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;

@SpringBootConfiguration
public class MyConfig {

@Bean
public IClientConfig iClientConfig() {
return new DefaultClientConfigImpl();
}
}

完成

参考文献

哔哩哔哩——黑马程序员
CSDN——任恒生