本文介绍
本文旨在深入探讨和分析微服务架构以及云原生架构中的服务发现机制原理。我们将重点关注K8S(Kubernetes)服务发现的原理和实现机制,以期为读者提供全面而深入的理解。通过对这些核心原理的剖析,我们能够更好地理解服务发现在现代分布式系统中的重要性和应用价值,从而为实际应用提供有力支持。
下面是历史总体的服务架构发展历史:
单体架构
在业务初期,面对简单场景和体系,单体架构确实凸显了其显著优势:部署便捷、测试高效、横向扩展灵活。这种架构模式在早期的应用中,以其简洁性和高效性,为业务的快速起步和稳定发展提供了有力支撑。
随着业务规模的扩大和复杂性的增加,单体架构逐渐暴露出其局限性。为了应对这些挑战,我们逐渐转向微服务架构,以更好地满足现代应用的需求。
此外,由于单体架构中的变更往往涉及多个模块,因此很容易引发回归问题,使得系统的稳定性和可靠性受到威胁。更为重要的是,单体架构难以适应持续集成和持续部署的需求,这在快速迭代和交付的现代软件开发环境中显得尤为突出。
微服务架构
微服务架构显著提升了系统的复杂性,实现了从集中部署向分布式部署的转变。这一转变引发了诸多挑战,包括进程间通讯方式的革新(基于消息或RPC)、分布式系统复杂问题的处理(如部分失败情形),以及分区数据库架构的采用。
将一个复杂的系统拆解为具备高内聚性、低耦合性的组件,不仅加速了系统的部署速度,还显著提升了系统的可理解性和可维护性。这种设计使得不同的服务可以由不同的团队进行维护,分工更为明确,从而能够更专注于各自的业务领域。
同时,微服务架构往往涉及异构系统,这意味着开发团队可以根据实际需求自主选择技术栈,增加了架构的灵活性和适应性。此外,每个微服务都可以独立部署,这极大地方便了持续集成和持续部署的实施,使得系统的更新和迭代更为高效。而且,每个微服务可以独立进行扩展,根据实际需求灵活调整资源分配,从而确保系统始终保持在最佳运行状态。
微服务的方法建议
微服务的拆分策略在提升资源利用率和成本控制方面发挥着重要作用,为企业的业务发展注入了源源不断的活力。具体而言,这一策略主要包括以下三种方式:
- 业务逻辑拆分:深入剖析业务逻辑,精准识别那些具备天然隔离特性的代码模块,为后续的微服务拆分奠定坚实基础。
- 并发逻辑拆分:针对不同的并发规模,我们进行细致的模块拆分,确保每个微服务能够独立应对各种并发挑战,保障系统的稳定高效运行。
- 内存需求拆分:考虑到不同服务对内存的需求差异,我们实施精准的模块拆分策略,将具有相似内存需求的模块聚合为独立的微服务,从而优化资源分配,降低成本开销。
微服务的通信机制
微服务架构显著地展现出两大核心特性:一是API网关的统一控制门面,它作为服务间的协调者,确保请求的有序流转与服务的统一管理;二是基于RPC的P2P调用实现机制,它实现了服务间的高效通信与数据交互,为微服务架构的灵活性和可扩展性提供了有力支撑。
P2P的调用通信
针对简单系统而言,若存在大量重复模块,如认证授权等,且缺乏统一规范,这往往表明系统在设计上存在冗余和不一致性。同时,若系统缺乏监控、审计等关键功能,则可能难以保障其稳定性和安全性。
因此,在微服务架构中,这种情况通常被视为一种反模式(anti-pattern),因为它违背了微服务架构的初衷,即实现服务的独立部署、高内聚和低耦合。为了优化这类系统,我们应该努力消除重复模块,建立统一规范,并加强监控和审计功能,以更好地发挥微服务架构的优势。
API网关统一门面
通过一个轻量级的API Gateway,实现了新API的整合。这一过程中,新API通过注册至gateway,从而实现了与Common function的无缝对接。这种整合方式不仅提高了系统的灵活性和可扩展性,同时也确保了数据的安全性和准确性。
通过轻量级的API Gateway,我们有效地简化了API的整合流程,提高了系统的整体性能。
微服务服务发现
在微服务架构中,相较于传统的三层架构,服务发布后的访问点呈现出动态创建的特性。构建一个高效且可靠的服务发现机制显得尤为重要。这一机制能够确保服务之间的顺畅通信,提高系统的可扩展性和可维护性,为微服务架构的稳定运行提供有力支撑。
微服务的服务发现机制主要采用以下两种模式:
DNS服务发现
DNS是一个功能强大的系统,提供了多种记录类型,这些记录类型在服务定位与识别方面发挥着至关重要的作用。它们允许网络中的设备和服务通过特定的标识符(如主机名或域名)进行查找和连接,从而确保服务的可用性和可访问性。
其中最基础的三个元素:
- A记录:指定主机名对应IP地址的记录,主要作用是将域名解析为IPv4地址,以说明一台主机和IP地址的对应关系。
- CNAME:将一个域名的别名精准地映射到另一个域名,为服务提供了灵活且高效的别名解析机制。
- PTR记录:负责从IP地址反向解析出对应的主机名,这对于反向DNS查找以及某些网络故障排查场景尤为关键。
- SRV记录:描述服务的位置信息和端口号,使得客户端能够准确地定位到所需的服务,从而实现服务的精确发现与连接。
这些记录类型共同构成了DNS服务发现机制的基础,为服务之间的通信提供了重要支持。
基于一致性原则的key-value数据库
- Consul:HashiCorp公司开发的一款开源服务发现和配置管理工具。
- 它提供了服务注册与发现、健康检查、键值存储以及多数据中心支持等功能。Consul采用Go语言编写,具有高性能和可扩展性。它可以帮助开发者构建弹性、分布式的系统,提高服务的可用性和可管理性。Consul在云原生环境中尤为受欢迎,是许多企业实现服务网格和服务治理的首选工具之一。
- Zookeeper:一个开源的分布式协调服务,为分布式应用提供高性能、可靠、有序的协调服务。
- 它主要用于管理分布式应用中的元数据,如配置信息、命名服务、分布式锁等。Zookeeper采用类似于文件系统的数据模型,提供了简单的原语集,使开发者能够轻松实现分布式应用的协调和管理。它广泛应用于大数据、云计算和分布式系统等领域,为构建高可靠、可扩展的分布式应用提供了有力支持。
- Etcd:一个开源的、分布式的键值存储系统,专为共享配置和服务发现而设计。
- 它采用Raft一致性算法,确保数据在集群中的高可用性和强一致性。Etcd在微服务架构中扮演着重要角色,用于管理服务的注册与发现,以及动态配置的分发。通过Etcd,开发者可以轻松地实现服务的自动化部署和动态扩展,提高系统的可维护性和可靠性。
服务发现与负载均衡紧密相关
在服务发现中,VIP(虚拟IP)通常作为访问入口点,在传统应用中,VIP是固定的,因此可以直接作为访问的入口点。用户请求需通过LoadBalancer进行转发,进而到达后端传统应用。
在微服务环境下,尽管VIP相对稳定,但基于context path的服务发现机制仍然需要依赖负载均衡器来确保请求能够正确路由到对应的服务实例。
负载均衡器在微服务架构中扮演着至关重要的角色,它负责将用户请求智能地分发到各个服务节点上,以实现高可用性和负载均衡。
微服务发展到容器化云原生
伴随着K8S的出现,我们将相应的应用服务封装成Docker容器,确保服务的标准化和可移植性。随后,这些容器以Pods的形式运行,实现了服务的独立部署和管理。
- 为了进一步确保服务的稳定性和可扩展性,我们利用ReplicaSet机制,将其作为Deployment组件服务进行部署。这样,当服务需要扩容或缩容时,ReplicaSet能够自动管理Pod的副本数量,满足业务需求。
- 通过引入LoadBalance负载均衡机制和Ingress,我们实现了服务的整体负载均衡和流量调度。LoadBalance确保请求能够均匀地分发到各个Pod上,提升服务的响应速度和处理能力;而Ingress则作为服务的入口,负责外部流量的接入和转发,实现了服务的统一管理和访问。
K8S服务发现和代理
KubeDNS作为集群内部的DNS服务,负责维护服务的访问入口信息,确保服务的可发现性和可访问性。
- Normal Service:KubeDNS保存从服务名到VIP(Virtual IP)的A Record,以及相应的PTR Record用于反向解析。此外,还保存了命名端口(Named Port)的SRV Record,提供了端口级别的服务发现能力。
- Headless Service:KubeDNS则维护了到每个Pod IP的A Record,这样可以直接通过Pod IP进行访问。同时,KubeDNS还保存了Pod的完全限定域名(FQDN)到每个Pod IP的A Record映射,提供了更为精确的Pod级别的服务发现。
基于ETCD的服务发现机制
Kubernetes的核心构建在于分布式键值存储数据库etcd,这一设计确保了其强大的稳定性和可扩展性。通过深度集成etcd,Kubernetes实现了高效的数据存储和访问机制,为集群管理提供了坚实的基础。
基于Namespace隔离控制
采用Namespace作为对象隔离的关键手段,不仅有效避免了对象间的潜在冲突,还增强了系统的稳定性和可靠性。同时,通过精心设计的HTTP Get操作,我们实现了对特定对象的精准服务发现,大幅提升了服务定位的速度和准确性。
K8S代理负载实现
Service服务机制(四层代理)
基于四层负载均衡技术,我们整合了多种Load Balancer Provider,实现了与企业现有ELB的无缝对接。在这一架构中,Kube-proxy发挥着至关重要的作用。它采用iptables规则,为Kubernetes构建了一个全局统一的分布式负载均衡器。
Kube-proxy实质上是一种网络网格结构,确保内部客户端无论是通过Pod IP、NodePort还是LB VIP访问服务,都会经过Kube-proxy的跳转,最终到达目标Pod。
ELB服务机制(七层代理)
Ingress作为一层代理,负责根据hostname和path精确地将流量转发至相应的服务,从而实现单个负载均衡器对多个后台应用的高效管理。而Kubernetes Ingress Spec则是一系列转发规则的集合,它定义了如何精确地将流量路由到不同的服务,确保请求能够准确、高效地到达目标。通过Ingress和Ingress Spec的协同工作,我们能够在Kubernetes集群中实现灵活且可扩展的流量调度。
其他七层代理选型
- Envoy/Istio:实现TLS终止并重定向功能,确保安全通信的同时,灵活引导流量流向。
- Nginx:提供L7级别的路径转发服务,有效管理并分发来自不同路径的请求。
- HAProxy:擅长进行URL和头部信息的重写,以满足复杂的路由和转发需求。