官方是这么说的 🔈
怎么去理解这两句话呢?也就是说Nacos不仅提供了服务注册与发现功能,还提供了配置管理的功能,同时还提供了可视化的管理平台。而Nacos又是围绕着Service转的。
如果大家查看源码,会发现Nacos的核心API中定义了两个接口NamingService和ConfigService。服务注册与发现围绕着NamingService展开,而配置管理则围绕着ConfigService展开。
服务发现和服务健康监测
动态配置服务
动态DNS服务
服务和元数据管理
Nacos能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述,生命周期,服务的静态依赖分析,服务的健康状态,服务的流量管理,路由及安全策略。
nacos config对比springcloud config有何优势? 👇
springcloud config大部分场景结合git 使用, 动态变更还需要依赖Spring Cloud Bus 消息总线来通过所有的客户端变化。
springcloud config不提供可视化界面。
nacos config使用长连接更新配置, 一旦配置有变动后,通知Provider的过程非常的迅速, 从速度上秒杀springcloud原来的config几条街。
注册中心有了Eureka ,为何还要用Nacos? 👇
eureka 2.0闭源码了。
从官网来看nacos 的注册的实例数是大于eureka的。
因为nacos使用的raft
协议,nacos集群的一致性要远大于eureka集群。
分布式一致性协议 Raft,自 2013 年论文发表,之后就受到了技术领域的热捧,与其他的分布式一致性算法比,Raft 相对比较简单并且易于实现,这也是 Raft 能异军突起的主要因素。
Raft 协议强依赖 Leader 节点来确保集群数据一致性。即 client 发送过来的数据均先到达 Leader 节点,Leader 接收到数据后,先将数据标记为 uncommitted 状态,随后 Leader 开始向所有 Follower 复制数据并等待响应,在获得集群中大于 N/2 个 Follower 的已成功接收数据完毕的响应后,Leader 将数据的状态标记为 committed,随后向 client 发送数据已接收确认,在向 client 发送出已数据接收后,再向所有 Follower 节点发送通知表明该数据状态为committed。
下载地址:https://github.com/alibaba/nacos/releases/tag/1.1.4
解压安装包,解压完成后直接运行bin目录下的startup.cmd
运行成功后直接访问 http://localhost:8848/nacos
nacos
如需使用Docker下载安装Nacos并完成持久化配置点击后方链接进行跳转 👉 Docker下载安装Nacos并完成持久化配置
由于项目应用环境的复杂度,同时考虑到各类数据的有效存储管理,在Nacos中对于数据的归类存储提供了不同的模型结构。
Namespace(命名空间):对不同的环境进⾏隔离,⽐如隔离开发环境、测试环境和⽣产环境。
Group(分组):,将若⼲个服务或者若⼲个配置集归为⼀组,通常习惯⼀个系统归为⼀个组。推荐命名格式:产品名称+分组名称
Service(服务):某⼀个服务,例如会员微服务。
在下图的分级存储模型可以看到,在服务级别,保存了健康检查开关、元数据、路由机制、保护阈值等设置,而集群保存了健康检查模式、元数据、同步机制等数据,实例保存了该实例的ip、端口、权重、健康检查状态、下线状态、元数据、响应时间。
Cluster(集群):集群是一个逻辑概念,可以区分不同的服务节点所处的网络环境。
Instance(实例):保存具体的微服务注册数据,每一个服务节点对应一个实例数据。
DataId(配置数据ID):自定义的配置数据集推荐命名格式:包名称.类名称(小写字母)
可以在nacos控制台看到与之对应的界面
如果还无法理解,我们可以直接从代码层面来看看Namespace、Group和Service是如何存储的。
/** * Map(namespace, Map(group::serviceName, Service)). */
private final Map<String, Map<String, Service>> serviceMap = new ConcurrentHashMap<>();
Nacos服务注册表结构为 Map。这个双层Map的key分别是namespace和group::serviceName,Nacos基于namespace的设计是为了做多环境以及多租户数据(配置和服务)隔离的。如果用户有多套环境(开发、测试、生产等环境),则可以分别建三个不同的namespace。
在此我们先忽略掉一对多的情况,假如只有一个命名空间它的整个层级包含关系为Namespace包含多个Group、Group可包含多个Service、Service可包含多个Cluster、Cluster中包含Instance集合。
// ServiceManager类,Map(namespace, Map(group::serviceName, Service))
private final Map<String, Map<String, Service>> serviceMap = new ConcurrentHashMap<>();
// Service类,Map(cluster,Cluster)
private Map<String, Cluster> clusterMap = new HashMap<>();
// Cluster类
private Set<Instance> persistentInstances = new HashSet<>();
private Set<Instance> ephemeralInstances = new HashSet<>();
// Instance类
private String instanceId;
private String ip;
private int port;
private double weight = 1.0D;
其中,实例又分为临时实例和持久化实例。它们的区别关键是健康检查的方式。临时实例使用客户端上报模式,而持久化实例使用服务端反向探测模式。
临时实例需要能够自动摘除不健康实例,而且无需持久化存储实例。持久化实例使用服务端探测的健康检查方式,因为客户端不会上报心跳,自然就不能去自动摘除下线的实例。
注册中心可以说是微服务架构中的通讯录
,它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到这里,当服务需要调用其它服务时,就到这里找到服务的地址,进行调用。
注册中心主要有三部分组成服务注册中心、服务提供者、服务消费者
服务注册的策略的是每5秒向nacos server发送一次心跳,心跳带上了服务名,服务ip,服务端口等信息。同时 nacos server也会向client 主动发起健康检查,支持tcp/http检查。如果15秒内无心跳且健康检查失败则认为实例不健康,如果30秒内健康检查失败则剔除实例。
Nacos注册中心分为Server与Client,Nacos提供SDK和openApi,如果没有SDK也可以根据openApi手动写服务注册与发现和配置拉取的逻辑。
Server采用Java编写,基于Spring Boot框架,为Client提供注册发现服务与配置服务。Client支持包含了目前已知的Nacos多语言客户端及Spring生态的相关客户端。Client与微服务嵌套在一起。
Nacos的DNS实现依赖了CoreDNS,其项目为nacos-coredns-plugin。该插件提供了基于CoreDNS的DNS-F客户端,开发语言为go。
本文演示的nacos版本为1.1.3,springcloud版本为2.1.0.RELEASE,springcloud-alibaba采用的版本为Greenwich.SR3,springboot对应版本为2.1.8.RELEASE。
nacos的Maven依赖
<!--nacos 服务注册/发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
</dependency>
要想引入上方依赖,首先需要确定本项目是个boot项目,还需先引入SpringCloud-Alibaba依赖。如果实在不会修改可参考下方pom
文件。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--在下方填上自已的gva坐标-->
<groupId>com.xxx</groupId>
<artifactId>xxx-xxx</artifactId>
<version>1.0-SNAPSHOT</version>
<!--版本控制-->
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
</properties>
<dependencies>
<!--nacos 服务注册/发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
声明需注册到,注册中心的地址,以及服务名称等
spring:
cloud:
nacos:
discovery:
server-addr: xx.xxx.xxx.xx:8848 #注册中心地址
application:
name: lgmall-coupon #服务名称
server:
port: 8010 #端口号
使用@EnableDiscoveryClient注解在我们启动类上开启服务注册与发现
@EnableDiscoveryClient
成功启动后我们打开注册中心控制台,可以查看到注册成功的微服务。
在微服务架构中,当系统从一个单体应用拆分成分布式系统上一个个服务节点后,配置文件也必须跟着迁移(分割),这样配置就分散了,不仅如此,分散中还包含着冗余,如下图
为了解决这种情况,就诞生了配置中心。配置中心会将配置从各个应用中剥离出来,对配置进行统一管理。使应用自身不需要自已去管理配置。
配置中心本身并不复杂,前提是你先将 CAP 的取舍问题晾在一边的话。配置中心最基础的功能就是存储一个键值对,用户发布一个配置(configKey),然后客户端获取这个配置项(configValue);进阶的功能就是当某个配置项发生变更时,将变更告知客户端刷新旧值。
下方的架构图,简要描述了一个配置中心的大致架构,用户可以通过管理平台发布配置,通过 HTTP 调用将配置注册到服务端,服务端将之保存在 MySQL 等持久化存储引擎中;用户通过客户端 SDK 访问服务端的配置,同时建立 HTTP 的长轮询监听配置项变更,同时为了减轻服务端压力和保证容灾特性,配置项拉取到客户端之后会保存一份快照在本地文件中,SDK 优先读取文件里的内容。
配置中心与注册中心所有的版本都是一致的。
引入 Nacos Config Starter依赖。
<!--nacos 配置中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
创建bootstrap.properties
配置文件,并配置nacos config元数据
spring.application.name=lgmall-coupon
spring.cloud.nacos.config.server-addr=xx.xxx.xxx.xx:xxxx
在配置中心添加一个叫 数据集(Data Id) lgmall-coupon.properties。
应用名.properties
通过@Value
读取远程配置,另外为保证动态刷新配置还要加上@RefreshScope
注解
@RefreshScope
@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
@Autowired
private CouponService couponService;
@Value("${user.ponName}")
private String name;
@GetMapping("/test")
public R test(){
return R.ok().put("name",name);
}
}
成功启动后,我们调用接口查看最终结果,发现成功读取到了配置中心的值
创建好后整体效果如下
bootstrop.properties
中说明加载哪些配置文件即可,以前springboot任何从配置文件中获取值的方法(如:@Value``@ConfigurationProerties
)都能使用,配置中心有的优先读取配置中心的。# bootstrap.properites 比yml文件优先加载
spring.application.name=lgmall-coupon
spring.cloud.nacos.config.server-addr=xx.xxx.xxx.xx:8848
#使用哪个命名空间下的配置,注意需要写命名空间的唯一id不能写名字
spring.cloud.nacos.config.namespace=ef375233-21be-646b-b955-6f3e0d855951
#数据源相关配置
spring.cloud.nacos.config.ext-config[0].data-id=datasource.yaml
spring.cloud.nacos.config.ext-config[0].group=coupon
spring.cloud.nacos.config.ext-config[0].refresh=true
#mybatis相关配置
spring.cloud.nacos.config.ext-config[1].data-id=mybatis.yaml
spring.cloud.nacos.config.ext-config[1].group=coupon
spring.cloud.nacos.config.ext-config[1].refresh=true
#nacos相关配置
spring.cloud.nacos.config.ext-config[2].data-id=nacos.yaml
spring.cloud.nacos.config.ext-config[2].group=coupon
spring.cloud.nacos.config.ext-config[2].refresh=true
#其它配置
spring.cloud.nacos.config.ext-config[3].data-id=other.yaml
spring.cloud.nacos.config.ext-config[3].group=coupon
spring.cloud.nacos.config.ext-config[3].refresh=true
data-id代表具体哪个配置,group代表读取哪个组,refresh=true代表动态刷新,可对应下图查看
通过上方日志我们可以发现,启动成功后他会优先读取lgmall-coupon.properties
配置文件,我们没有配置该配置文件,它就会继续读取datasource.yaml
,other.yaml
,nacos.yaml
,mybatis.yaml
Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='lgmall-coupon.properties'}, NacosPropertySource {name='other.yaml'}, NacosPropertySource {name='nacos.yaml'}, NacosPropertySource {name='mybatis.yaml'}, NacosPropertySource {name='datasource.yaml'}]}
我们访问数据库发现请求成功!
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://chonglian.blog.csdn.net/article/details/122329185
内容来源于网络,如有侵权,请联系作者删除!