The following article is from Kirito的技术分享 Author kiritomoe
「技术分享」某种程度上,是让作者和读者,不那么孤独的东西。「Kirito的技术分享」致力于探讨 Java 生态的知识点,内容覆盖分布式服务治理,微服务,性能调优,各类源码分析。追求有深度并兼具表达力的文字。
作者 | kiritomoe
Nacos 支持两种部署模式:单机模式和集群模式。在实践中,我们往往习惯用单机模式快速构建一个 Nacos 开发/测试环境,而在生产中,出于高可用的考虑,一定需要使用 Nacos 集群部署模式。我的上一篇文章《一文详解 Nacos 高可用特性》提到了 Nacos 为高可用做了非常多的特性支持,而这些高可用特性大多数都依赖于集群部署模式。这篇模式文章便是给大家介绍一下,在实践中可以被采用的几种集群部署模式,无论你是希望自行搭建 Nacos,还是希望对 MSE 商业版 Nacos 有一个更加深刻的理解,我都很乐意跟你分享下面的内容。
由于篇幅限制,本文不会介绍如何将一个多节点的 Nacos 集群启动起来,主要介绍的是一个多节点的 Nacos 集群启动之后,我们的应用如何很好地连接到 Nacos 集群,即客户端视角。这中间我们会引入一些其他组件以解决一些问题,本文标题也可以叫做《Nacos 接入点最佳实践》。我将会介绍以下三种方案:直连模式、 VIP 模式和地址服务器模式,并对它们进行对比。
直连模式是部署上最简单,也是最容易理解的一种模式
采用直连模式后,典型的开发场景配置如下:
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.SERVER_ADDR, "192.168.0.1:8848,192.168.0.2:8848,192.168.0.3:8848");
NamingService namingService = NacosFactory.createNamingService(properties);
注意这里的 PropertyKeyConst.SERVER_ADDR 的字面量是:serverAddr
dubbo.registry.address=192.168.0.1:8848,192.168.0.2:8848,192.168.0.3:8848
dubbo.registry.protocol=nacos
如果有一天,Nacos 的 IP 变了,例如扩缩容,机器置换,集群迁移等场景,所有的应用都需要修改,这样的方式并不灵活。所以这种模式并不是生产推荐的模式。
VIP(Virtual IP) 模式可以很好的解决直连模式 IP 变化所带来的应用批量修改的问题。什么是 VIP 呢?
我这里介绍时并没有用【负载均衡模式】,而是用了【VIP 模式】,主要是为了跟 Nacos 官方文档保持一致。事实上,VIP 的叫法在阿里内部比较流行,所以在开源 Nacos 时也被习惯性的带了出去。
知乎砍出正义一刀,PDD祭出终极防御:“供应商员工”!轻松化解攻势!
VIP 帮助 Nacos Client 屏蔽了后端 RIP,相对于 RIP 而言,VIP 很少会发生变化。以扩容场景为例,只需要让 VIP 感知到即可,Nacos Client 只需要关注 VIP,避免了扩容引起的代码改造。
只要是具备负载均衡能力的组件,均可以实现 VIP 模式,例如开源的 Nginx 以及阿里云负载均衡 SLB。
采用 VIP 模式后,代码不需要感知 RIP,典型的开发场景配置如下:
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.SERVER_ADDR, "{VIP}:8848");
NamingService namingService = NacosFactory.createNamingService(properties);
dubbo.registry.address={VIP}:8848
dubbo.registry.protocol=nacos
VIP 模式和直连模式都不具备可读性,所以在实际生产中,往往还会给 VIP 挂载一个域名。
域名背后甚至可以挂载 2 个 VIP 用作高可用,路由到相同的 rs;同时域名的存在也让 VIP 的置换变得更加灵活,当其中一台出现问题后,域名的 DNS 解析只会路由到另外一个正常的 VIP 上,为平滑置换预留了足够的余地。
tips:一个域名可以绑定多个 A 记录,一个 A 记录对应一个 IPv4 类型的 VIP,DNS 域名服务器了对多个 A 记录会有负载均衡策略和健康检查机制
VIP 模式的最终生产高可用版架构便产生了:
典型的开发场景配置只需要将 VIP 替换为域名即可
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.SERVER_ADDR, "mse-abc123qwe-nacos.mse.aliyuncs.com:8848");
NamingService namingService = NacosFactory.createNamingService(properties);
dubbo.registry.address=mse-abc123qwe-nacos.mse.aliyuncs.com:8848
dubbo.registry.protocol=nacos
说起地址服务器,可能大家对这个词会感到陌生,因为地址服务器的概念主要在阿里内部比较普及,也是阿里中间件使用的最广的一种地址寻址模式。但是在开源领域,鲜有人会提及,但对于 Nacos 部署模式而言,地址服务器模式是除了 VIP 模式之外,另外一个生产可用的推荐部署方式。
地址服务器是什么?顾名思义,是用来寻址地址的服务器,发送一个请求,返回一串地址列表。尽管在阿里内部使用的真实地址服务器比这复杂一些,但下图这个简单交互逻辑,几乎涵盖了地址服务器 90% 的内容。
实现一个简易版本的地址服务器并不困难,推荐使用 nginx 搭建一个静态文件服务器管理地址, 当然你可以使用 Java!
@Controller
public class AddressServerController {
@RequestMapping("/nacos/serverlist")
public ResponseEntity<String> serverlist() {
return ResponseEntity.ok().
header("Content-Type", "text/plain").
body("192.168.0.1:8848\r\n" +
"192.168.0.2:8848\r\n" +
"192.168.0.3:8848\r\n"
);
}
}
使用地址服务器可以完成集群地址和客户端配置的解耦,解决直连模式中无法动态感知集群节点变化的问题。客户端根据地址服务器返回的列表,随后采取直连模式连接;并且在客户端启动后,会启动一个定时器,轮询感知 AddressServer 的变化,进而及时更新地址列表。
并且地址服务器建议配置域名,增加可读性。所以最后的部署交互架构是这样的:
熟悉 RPC 的朋友看到这里应该能够很好地对 VIP 模式和地址服务器模式做一个类比。
nacos-client 的源码专门适配了地址服务器模式,我们只需要配置好 addressServer 的 endpoint 即可
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.ENDPOINT, "{addressServerDomain}");
properties.setProperty(PropertyKeyConst.ENDPOINT_PORT, "8080");
NamingService namingService = NacosFactory.createNamingService(properties);
注意,这里 PropertyKeyConst.ENDPOINT 的字面量是:endpoint
,配置的是地址服务器的地址。
dubbo.registry.address=0.0.0.0?endpoint=127.0.0.1&endpointPort=8080
dubbo.registry.protocol=nacos
dubbo.registry.address 的 url 可以任意填写,因为当 serverAddr 和 endpoint 同时存在时,默认是优先从地址服务器去选址的。
此时,只需要把真实的 Nacos Server IP 配置到地址服务器中即可。
Dubbo 通过 url 的 kv 属性将值透传给 Nacos 创建 Nacos-Client。Dubbo + Nacos 使用地址服务器模式时,建议 Dubbo 版本 >= 2.7.4,nacos-client 版本 >= 1.0.1
直连模式 | VIP 模式 | 地址服务器模式 | |
---|---|---|---|
转发模式 | 直连 | 代理(网络多一跳) | 直连 |
高可用 | 弱,代码配置不灵活,节点故障时无法批量变更 | 强 | 强 |
可伸缩性 | 弱 | 强 | 强 |
部署成本 | 无 | 负载均衡组件运维成本高 | 地址服务器运维成本低 |
负载均衡模式 | nacos-sdk 客户端负载均衡 | 负载均衡组件提供负载均衡能力 | nacos-sdk 客户端负载均衡 |
开源接受度 | 高 | 高 | 低,地址服务器模式在开源领域不太普遍 |
企业级能力 | 不方便 | 灵活 | 灵活 |
跨网络 | 内网环境,平坦网络 | VIP 模式灵活地支持反向代理、安全组、ACL 等特性,可以很好的工作在内/外网环境中,使得应用服务器和 Nacos Server 可以部署在不同的网络环境中,借助 VIP 打通 | 内网环境,平坦网络 |
推荐使用环境 | 开发测试环境 | 生产环境,云环境 | 生产环境 |
Nacos 这款开源产品很好地支持了地址服务器这种模式,所以无论是大、中、小型公司在自建 Nacos 时,都可以选择地址服务器模式去构建生产高可用的 Nacos 集群,地址服务器组件相对而言维护简单,Nginx,Java 构建的 Web 服务器均可以轻松实现一个地址服务器。使用地址服务器后,nacos-client 与 nacos-server 之间仍然是直连访问,所以可以很好的运作在平坦网络下。
VIP 模式同样推荐在自建场景使用,但运维成本相对地址服务器还是要高一些,可以根据自己公司的运维体系评估。经过了 VIP 的转发,有利有弊。弊端比较明显,网络多了一跳,对于内网环境这样的平坦网络而言,是不必要的;优势也同样明显,大公司往往环境比较复杂,数据中心之间有网络隔离,应用和中间件可能部署在不同的网络环境中,借助于 VIP 可以很好地做网络打通,并且基于 VIP 可以很好实现安全组、ACL 等特性,更符合企业级诉求。
当然,组合使用地址服务器 + VIP 也是可以的,可以充分的融合两者的优势:
上述场景主要介绍了三种模式的具体部署方案,以及自建 Nacos 场景如何做到高可用,最后要介绍的是阿里云环境 MSE 是如何部署的。
MSE(微服务引擎)提供了 Nacos 注册中心中心的全托管能力,除了要做上述提到的高可用、可伸缩、易用性,还要考虑以下的因素:
综上,MSE Nacos 最终采用的是域名 + SLB 的 VIP 模式。
MSE Nacos 提供两个域名,其中公网域名可以用做本地开发测试,或者自建环境、混合云等场景的接入点,内网域名用做阿里云生产环境接入点。公网域名有带宽限制,需要在集群创建时根据场景选择合适的带宽,而内网域名则没有带宽限制。公网域名请注意添加 IP 访问白名单。
MSE 微服务引擎用户交流群钉钉群号:23371469
官网首页:https://mse.console.aliyun.com/
本文介绍了 Nacos 的三种部署模式,并就高可用、可伸缩、易用性等方面对各个模式进行了介绍,并对自建 Nacos 场景的部署选型进行了分析,同时介绍了 MSE Nacos 企业版的部署架构,对云环境部署 Nacos 进行了补充。
文章提及的三种模式其实也都是中间件组件常见的部署模式,不仅仅 Nacos,例如 Redis、DB 等场景,同样有参考价值。
本文提及了地址服务器这个可能在开源领域不太常见的组件,在阿里内部则用的非常普遍。
另外,Nacos 本身也提供了 addressServer 模块,出于篇幅考虑没有在本文中提及,后续我会单独整理一篇文章介绍,感兴趣的同学可以自行参考 Nacos 官方文档和官方博客中的内容。
往期推荐
Go to "Discover" > "Top Stories" > "Wow"