【编者的话】在前面的文章中,小码农介绍过《 基于SpringCloud的微服务演进之路 》,作为一款最近两年比较火的微服务框架Spring Cloud已经在不少创业型互联网公司落了地,然而无奈变化太快,这不还没来得及熟悉Spring Cloud的全部组件,就猛然发现了Service Mesh的崛起,而Spring Cloud就显得有点过时了。
和大部分吃瓜码农一样,刚开始小码农对此也是一头雾水。那么什么是Service Mesh?它与Spring Cloud相比有什么优势呢?在接下来的内容中,就和大家一起初步了解下Service Mesh吧!
在了解Service Mesh之前,我们先来讨论下这样一个问题:“微服务架构的核心技术问题是什么?”。
我们知道在将整个软件系统架构升级为微服务模式以后,服务(这里是指独立对外提供服务的进程实体)的规模会越来越大,少则几个到十几个,多则上百个。而这,还只是从应用拆分本身的数量上看的,在实际的生产部署中,单个微服务进程也不会以单节点的方式部署,而多是以集群的方式进行部署。
此时自然就会产生两个核心的问题:一是服务发现,即服务的消费方(Consumer)如何发现服务的提供方(Provider)的问题?二是负载均衡,即我们的微服务在以集群方式部署后,服务的消费方如何以某种负载均衡策略访问集群中的微服务实例?
在回答以上两个问题时,我们先来回顾下目前业界经历过的三种服务发现及负载模式:
这种模式在微服务架构模式兴起之前,是业界非常主流的模式,目前大部分公司的架构模型依然采用的是这种模式。
在集中式处理方式中,应用系统根据各自需要进行模块化设计与拆分,虽然呈现了一定分布式的特性,但是在服务间调用时,仍然需要通过F5或Nginx这类软硬件负载均衡器来进行通信,从而保证高可用。
并且这种方式的服务注册更多的是一种依赖于运维人员、手工配置、明确调用的方式。在实践中一般是通过DNS域名解析服务的方式配合实现,通过在Nginx或F5上建立服务域名和服务IP/端口之间的映射关系,来实现消费端通过请求服务域名,域名指向代理(Nginx/F5),代理通过解析目标IP地址并最终进行负载均衡和服务调用。
这种架构模式,目前依然是最为普遍的一种方式,即便很多互联网公司最终会转向微服务时代的模式二、模式三,但是在其初创期仍然会选择这种方式进行过渡。
这种方式就是目前以Spring Cloud框架为代表的微服务架构模式所使用的方式,包括在此之前比较著名的Dubbo框架采用的也这样的方式。在这种模式下,服务发现和负载均衡逻辑都是以本地库的方式嵌在具体的应用中。
这种模式一般需要独立的服务中心注册组件配合,服务启动时自动注册到服务中心并定期上报心跳,客户端代理则通过注册中心进行服务发现并进行负载均衡。
在之前的文章中(推荐阅读有链接)我们介绍的基于Spring Cloud的微服务架构就是通过采用Consul作为注册中心,客户端通过集成Spring Cloud提供的相关本地组件(@EnableDiscoveryClient),进行服务调用时通过FeignClient(底层采用Ribbon)实现了服务的发现与负载均衡。
客户端嵌入的模式,在应用本身嵌入了服务发现&负载均衡的逻辑,虽然像Spring Cloud这样的框架提供了很方便快捷的开发集成,但因为应用本身的业务逻辑与底层通信逻辑耦合在了一起,从架构角度看会显得让人有点不是很爽的感觉,当然这种缺陷,也在某些层面的确限制了很多的能力,在我们具体讨论Service Mesh时再和大家讨论。
从目前的实践看,因为微服务架构的概念最近几年才开始流行,加上Spring Cloud的热度,以及之前Dubbo等框架的助推,目前很多互联网公司的微服务架构体系都是基于这种模式进行的。作者所在的公司,目前也主要是基于Spring Cloud框架进行的一些实践,当然,因为最近Service Mesh的火热,也在逐步开始进行新的架构尝试。
在这里,还需要特别澄清一下,这种模式也并非完全是对模式一的替代,这种架构方式的主要关注点在于内部服务的治理,对于需要通过互联网访问的服务,我们依然需要通过F5/Nginx之类软硬件负载均衡器进行负载均衡,例如在这种模式下API Gateway在向外提供公网服务时,仍然是通过DNS+Nginx进行的扩展。
这种模式其实上面两种模式的一种折中方案,用于实现服务发现和负载均衡的代理(Proxy)既不是独立集中部署(像F5/Nginx),也不是嵌入在客户应用程序中(像Ribbon)。而是作为一个独立的进程部署在每一台主机上,主机上的多个消费者(Consumer)应用可以共用这个代理来实现服务发现和负载均衡。
这种模式相比较于模式二而言,也需要独立的服务注册中心组件配合。只是将负责服务发现、负载均衡、熔断限流等相关逻辑从原有的消费客户端进程拆分到单独的代理进程中了,由这个独立部署的代理来负责服务发现、路由分流(负载均衡)、熔断限流、安全控制、监控等功能。
在了解完以上三种模式后,我们再来一起探讨下什么是Service Mesh?Service Mesh又称为服务网格,本质上就是我们前面介绍过的模式三。之所为称之为服务网格是因为按照模式三的结构,每个主机上同时运行了业务逻辑代码和代理,此时这个代理被形象地称之为SideCar(业务代码进程相当于主驾驶,共享一个代理相当于边车),服务之间通过SideCar发现和调用目标服务,从而形成服务之间的一种网络状依赖关系,然后通过独立部署的一种称之为控制平面(ControlPlane)的独立组件来集中配置这种依赖调用关系以及进行路由流量调拨等操作,如果此时我们把主机和业务逻辑从视觉图上剥离,就会出现一种网络状的架构,服务网格由此得名。
在新一代的Service Mesh架构中服务消费方和提供方的主机(或容器)两边都会部署代理SideCar,此时SideCar与服务所在的主机又称之为数据平面(DataPlane),与我们前面说到的用于依赖关系配置和流量调拨操作的控制平面相对应。
通过上述的内容,我们从概念上应该是大概理解了什么是Service Mesh。而具体要落地Service Mesh只有概念是远远不够的,相反,如果没有一种可落地执行的开源框架,这个概念也不会这么快被大家所接受。
Istio就是目前受Google/IBM等大厂支持和推进的一个Service Mesh开源框架组合。它解决了开发人员和运维人员在整体应用程序向分布式微服务体系结构过渡时所面临的挑战。我们知道无论是基于Spring Cloud的微服务架构体系还是目前我们说到的Service Mesh,随着微服务规模的增长会带来很多的复杂性,如服务发现、负载均衡、故障恢复、监控,甚至A/B测试、访问控制等。而要对涉及这些问题的微服务架构体系进行管理,如果没有成熟的组件的话,就会需要耗费很多的精力去开发一些运维工具,而这个成本是非常高的。
而Istio则提供了一个完整的解决方案来满足微服务应用程序的各种需求。下图是Istio官网( https://istio.io )所展示的关于Istio的一张架构图:
在这张架构图中Istio服务网格在逻辑上还是分为数据平面和控制平面。数据平面中的SideCar代理是由一款叫做Envoy的组件来承担的,它是一款用C++开发的高性能代理,用于协调服务网格中所有服务的入站和出站流量。
Envoy提供了很多内在的特性如:
从上面的特性上看实际上Envoy已经提供了很完备的SideCar的功能,只是由于其采用的是C++开发的,目前在国内的落地实践中会有不同的取舍和选择,如蚂蚁金服内部在实践的过程中就没有使用Istio默认集成的Envoy,而是用Golang开发了新的SideCar,已经开源的SOFAMosn,来替代Envoy。
在Istio控制平面中的各个组件的作用如下:
以上就是关于Istio及其组件的一些介绍,具体如何使用Istio进行服务开发及安装操作,大家可以看看Istio的官网,另外需要强调的是kubernetes是目前 Isito 主力支持的容器云环境。
事实上Service Mesh这种架构模式并不新鲜,很早就有公司进行过尝试,之所以最近又火起来的原因,主要还是因为模式一、模式二的确有一些固有的缺陷,模式一相对比较重,有单点问题和性能问题。
而模式二则有客户端复杂,支持多语言困难,路由、熔断、限流等服务操作无法集中治理的问题。而Service Mesh则正好弥补了二者的不足,它是纯分布式的,没有单点的问题,性能也比较优秀并且与开发语言无关,还可以集中进行治理。
此外,随着微服务化、多语言和容器化的发展趋势,很多公司也迫切需要一种轻量级的服务发现机制,加上一些大厂如Google/IBM的助推(如Kubernetes与Docker的容器之争),正好Service Mesh迎合了这种趋势,所以才有今天火热的局面。
目前国内如阿里、微博、摩拜等公司都在积极探索Service Mesh的架构模式,只是在实践中一般具备一定开发能力的公司都会选择基于Istio进行二次开发,如目前阿里开源的SOFAMesh/SOFAMosn两个项目。
而对于开发及运维能力不强的公司,是否有必要将自己的架构体系立刻升级为Service Mesh模式还是需要好好考虑考虑,因为毕竟这会带来很大的运维成本。
以上就是小码农关于Service Mesh的一点认识和见解,由于水平有限,不足之处还请多多包涵!
原文链接: https://mp.weixin.qq.com/s/iSzQgsK4ANoCV0daIHMuNw