前言
在聊服务注册中心时,便提到了Nacos。这次便来认识一下。当然,这自然没有官方介绍那般详尽,权当是学习了解Nacos原理的一个过程吧。
Nacos简介
Nacos,全名:dynamic Naming And Configuration Service. 而这个名字则强调了Nacos的两大基石: Naming Service 和 Config Service。
-
Config Service
自然是负责提供配置管理服务。Nacos作为配置中心时,主要使用的便是该服务 -
Naming Service
想必不用多说,也能猜到就是负责提供服务注册中心能力的扛把子。不过官方关于该服务的描述很有意思:提供分布式系统中所有对象(Object)、实体(Entity)的“名字”到关联的元数据之间的映射管理服务。服务发现和 DNS 就是名字服务的2大场景
简而言之,就是映射服务。通过一个名字找到相关分布式组件的元数据/元信息。这不就是服务注册中心的本质吗?嘿嘿。
Nacos入门使用
Nacos服务的搭建
Nacos服务的搭建可以参考官网的Quick-Start,可通过源码编译打包部署,也可以通过docker部署。这里给大家提醒一下我搭建过程中遇到过的问题:
- Nacos2.x为了提高性能,增加了grpc通信方式,因此需要开放对应的端口,默认为9848.
- Nacos2.x的表结构与Nacos1.x也有所区别,如果表结构错误则会导致Nacos启动失败的。
- Nacos2.x需要使用对应的Nacos2.x的客户端,否则客户端连接服务端会失败。
附上
Nacos2.0兼容性说明
Nacos 2.0.0部署及升级文档
Nacos配置服务 - 配置中心
- 先在Nacos控制台新建一个命名空间
命名空间,这个概念官方的解释比较容易理解,用于隔离不同环境。例如:开发环境、测试环境、生产环境。
这里我们等于是新建了一个开发环境的命名空间。
- 新建一个配置集
-
配置集——DataID,这里就是指代我们常说的配置文件。从我们使用的角度来理解官网上的这些概念就容易许多了。我们一个配置文件里面本身就是包含了很多配置项,从配置服务的管理角度看,就是一个配置集。这也就不难理解官方定义所说的:“一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。”从使用的角度说,就是一个系统可以有多个配置文件。
-
配置分组。对于单体系统,这个概念显得比较鸡肋。对于微服务系统,则比较有意思。“不同的应用或组件使用了相同的配置类型,如 database_url 配置和 MQ_topic 配置。”。理解一下这句话:以MQ为例,意味着有一个生产者服务和一个消费者服务,当生产者更改MQ配置(例如Topic),那么消费者也需要同时更改。这时,不妨把MQ的配置单独作为一个配置集,设置一个特定的分组,生产者跟消费者都是这个配置即可。至于分组名,取一个跟这两服务确切相关的即可。
不过,从这我们也可以发现,我们可以发布多个相同配置文件,分组不同的配置集。这可以用在相同的组件但业务不同的场景下。 -
在java客户端获取配置
我们从控制台就可以拿到读取该配置集(配置文件)的示例代码:
// Nacos服务的地址
String serverAddr = "localhost:8848";
// 配置所属的命名空间:开发环境
String namespace = "b7984b05-f2fe-4213-8fdf-47ef799315a5";
// 目标配置集DataId
String dataId = "nacos-config-example.yaml";
// 目标配置集分组
String group = "DEFAULT_GROUP";
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
properties.put(PropertyKeyConst.NAMESPACE, namespace);
ConfigService configService = NacosFactory.createConfigService(properties);
String content = configService.getConfig(dataId, group, 5000);
System.out.println(content);
这就是配置服务的简单使用,以及我们在使用的时候需要关注的相关概念了。如果大家在官网看相关概念,需要注意,只有《配置管理》这里面的东西才是配置服务相关的概念
Nacos映射管理服务 - 注册中心
与其他注册中心类似,只需要启动注册中心即可注册。先看看Java客户端怎么注册的。
Properties properties = new Properties();
// 指定 Nacos 地址
properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848");
// 默认命名空间是空,可以不填写
properties.put(PropertyKeyConst.NAMESPACE, "b7984b05-f2fe-4213-8fdf-47ef799315a5");
// 如果在云上开启鉴权可以传入应用身份
// properties.put("ramRoleName", "$ramRoleName");
// properties.put(PropertyKeyConst.ACCESS_KEY, "${accessKey}");
// properties.put(PropertyKeyConst.SECRET_KEY, "${secretKey}");
NamingService serviceRegistry = NacosFactory.createNamingService(properties);
// 分组 可用于区分数据中心,同个数据中心的服务互相调用,提高效率
String groupName = "DataCenter-DongGuang";
// 京东商城服务 —— Service:微服务;系统
String serviceName = "JingDong-Mall";
Instance instance = new Instance();
instance.setIp("192.168.1.125");
instance.setPort(8080);
instance.setWeight(1.0);
// 订单服务集群
instance.setClusterName("order-service");
instance.setInstanceId("1");
// instance.setEphemeral(false);
serviceRegistry.registerInstance(serviceName, groupName, instance);
// 死循环,为了不让服务关停,方便在nacos控制台观测状况
while(true);
注册成功之后,控制台看看
在demo中也涉及了一些关于Nacos的注册中心的相关概念。再从官网捞了两张图帮助大家理解。
- 命名空间Namespace:使用场景是区分不同环境,因此没有异议。
- 服务分组Group:不同的服务可以归类到同一分组。
- 服务Service:通过预定义接口网络访问的提供给客户端的软件功能。
- 虚拟集群Cluster: 同一个服务下的所有服务实例组成一个默认集群, 集群可以被进一步按需求划分,划分的单位可以是虚拟集群。
关于以上定义,我的解读如下:
- 服务,这个比较有意思。网络可以访问的软件。可以是一个大型的微服务系统,也可以是一个小的自治服务。
- 服务分组,这个也有意思。不过从其实现来说,同一个分组的服务才能互相发现。
- 虚拟集群,关键词:虚拟。可以被进一步划分!如果是大型微服务系统,按照定义其所有的实力都归属于一个集群。但进一步划分后,又可以按照各微服务划分小集群。
从demo而言,算是对分组的一种应用。可以方便同一个数据中心的服务互相调用,提高调用效率。这里提示一下,Nacos算是一个平台,能装很多Service。
不过这种应用也有其弊端,如果数据中心的某个机房的某些机器损坏导致部分服务需要访问其他数据中心时是无法做到的。
据《Nacos架构与原理》,这些都是为了实现不同程度的隔离。分组和服务,可以实现接口级别的隔离。而从控制台的UI,我们也可以发现namespace是需要选择才切换的,而分组与实例则是直接展示的。
而接口级别的隔离,个人觉得就取决于你如何应用了。
有人说可以通过分组来区分环境,个人不是很支持,因为不便于在控制台管理。
一般情况下,使用命名空间来区分环境,至于分组则都没有使用(即默认分组:DEFAULT_GROUP).
不过,与注册中心不同,作为配置中心时配置分组倒是可以用来区分应用/组件。当然,你也可以通过dataID增加特定的服务名前缀来区分。
后记
本来想把数据结构也聊一聊的,但感觉篇幅又太长了。其次,要想讲清楚,就不得不深入到源码中。因此决定分开说,这次聊的是使用。下次,咱深入源码,聊聊设计和数据结构。