云原生
参考:https://blog.csdn.net/csdnnews/article/details/90093190
云原生从字面意思上来看可以分成云和原生两个部分。
云是和本地相对的,传统的应用必须跑在本地服务器上,现在流行的应用都跑在云端,包含IaaS,、PaaS和SaaS。
原生就是土生土长的意思,我们在开始设计应用的时候就考虑到应用将来是运行云环境里面的,要充分利用云资源的优点,比如️云服务的弹性和分布式优势。
那具体要怎么利用呢,请参考下图:
所以,可以简单的将云原生理解为:云原生 = 微服务 + DevOps + 持续交付 + 容器化
南北流量和东西流量
南北流量(NORTH-SOUTH traffic)和东西流量(EAST-WEST traffic)是数据中心环境中的网络流量模式。
假设我们尝试通过浏览器访问某些Web应用。Web应用部署在位于某个数据中心的应用服务器中。在多层体系结构中,典型的数据中心不仅包含应用服务器,还包含其他服务器,如负载均衡器、数据库等,以及路由器和交换机等网络组件。假设应用服务器是负载均衡器的前端。
当我们访问web应用时,会发生以下类型的网络流量:
-
客户端(位于数据中心一侧的浏览器)与负载均衡器(位于数据中心)之间的网络流量
-
负载均衡器、应用服务器、数据库等之间的网络流量,它们都位于数据中心。
南北流量
在这个例子中,前者即客户端和服务器之间的流量被称为南北流量。简而言之,南北流量是server-client流量。
东西流量
这种流量即不同服务器之间的流量与数据中心或不同数据中心之间的网络流被称为东西流量。简而言之,东西流量是server-server流量。
当下,东西流量远超南北流量,尤其是在当今的大数据生态系统中,比如Hadoop生态系统(大量server驻留在数据中心中,用map reduce处理),server-server流量远大于server-client流量。
什么是Service mesh
一言以蔽之:Service Mesh是微服务时代的TCP协议。
时代0:开发人员想象中,不同服务间通信的方式,抽象表示如下:
时代1:原始通信时代
然而现实远比想象的复杂,在实际情况中,通信需要底层能够传输字节码和电子信号的物理层来完成,在TCP协议出现之前,服务需要自己处理网络通信所面临的丢包、乱序、重试等一系列流控问题,因此服务实现中,除了业务逻辑外,还夹杂着对网络传输问题的处理逻辑。
时代2:TCP时代
为了避免每个服务都需要自己实现一套相似的网络传输处理逻辑,TCP协议出现了,它解决了网络传输中通用的流量控制问题,将技术栈下移,从服务的实现中抽离出来,成为操作系统网络层的一部分。
时代3:第一代微服务
在TCP出现之后,机器之间的网络通信不再是一个难题,以GFS/BigTable/MapReduce为代表的分布式系统得以蓬勃发展。这时,分布式系统特有的通信语义又出现了,如熔断策略、负载均衡、服务发现、认证和授权、quota限制、trace和监控等等,于是服务根据业务需求来实现一部分所需的通信语义。
时代4:第二代微服务
为了避免每个服务都需要自己实现一套分布式系统通信的语义功能,随着技术的发展,一些面向微服务架构的开发框架出现了,如Twitter的Finagle、Facebook的Proxygen以及Spring Cloud等等,这些框架实现了分布式系统通信需要的各种通用语义功能:如负载均衡和服务发现等,因此一定程度上屏蔽了这些通信细节,使得开发人员使用较少的框架代码就能开发出健壮的分布式系统。
时代5:第一代Service Mesh
第二代微服务模式看似完美,但开发人员很快又发现,它也存在一些本质问题:
- 其一,虽然框架本身屏蔽了分布式系统通信的一些通用功能实现细节,但开发者却要花更多精力去掌握和管理复杂的框架本身,在实际应用中,去追踪和解决框架出现的问题也绝非易事;
- 其二,开发框架通常只支持一种或几种特定的语言,回过头来看文章最开始对微服务的定义,一个重要的特性就是语言无关,但那些没有框架支持的语言编写的服务,很难融入面向微服务的架构体系,想因地制宜的用多种语言实现架构体系中的不同模块也很难做到;
- 其三,框架以lib库的形式和服务联编,复杂项目依赖时的库版本兼容问题非常棘手,同时,框架库的升级也无法对服务透明,服务会因为和业务无关的lib库升级而被迫升级;
因此以Linkerd,Envoy,Ngixmesh为代表的代理模式(边车模式)应运而生,这就是第一代Service Mesh,它将分布式服务的通信抽象为单独一层,在这一层中实现负载均衡、服务发现、认证授权、监控追踪、流量控制等分布式系统所需要的功能,作为一个和服务对等的代理服务,和服务部署在一起,接管服务的流量,通过代理之间的通信间接完成服务之间的通信请求,这样上边所说的三个问题也迎刃而解。
如果我们从一个全局视角来看,就会得到如下部署图:
如果我们暂时略去服务,只看Service Mesh的单机组件组成的网络:
相信现在,大家已经理解何所谓Service Mesh,也就是服务网格了。它看起来确实就像是一个由若干服务代理所组成的错综复杂的网格。
时代6:第二代Service Mesh
第一代Service Mesh由一系列独立运行的单机代理服务构成,为了提供统一的上层运维入口,演化出了集中式的控制面板,所有的单机代理组件通过和控制面板交互进行网络拓扑策略的更新和单机数据的汇报。这就是以Istio为代表的第二代Service Mesh。
只看单机代理组件(数据面板)和控制面板的Service Mesh全局部署视图如下:
至此,见证了6个时代的变迁,大家一定清楚了Service Mesh技术到底是什么,以及是如何一步步演化到今天这样一个形态。
现在,我们再回过头来看Buoyant的CEO William Morgan,也就是Service Mesh这个词的发明人,对Service Mesh的定义:
服务网格是一个基础设施层,用于处理服务间通信。云原生应用有着复杂的服务拓扑,服务网格保证请求在这些拓扑中可靠地穿梭。在实际应用当中,服务网格通常是由一系列轻量级的网络代理组成的,它们与应用程序部署在一起,但对应用程序透明。
这个定义中,有四个关键词:
基础设施层+请求在这些拓扑中可靠穿梭:这两个词加起来描述了Service Mesh的定位和功能,是不是似曾相识?没错,你一定想到了TCP;
网络代理:这描述了Service Mesh的实现形态;
对应用透明:这描述了Service Mesh的关键特点,正是由于这个特点,Service Mesh能够解决以Spring Cloud为代表的第二代微服务框架所面临的三个本质问题;
总结一下,Service Mesh具有如下优点:
- 屏蔽分布式系统通信的复杂性(负载均衡、服务发现、认证授权、监控追踪、流量控制等等),服务只用关注业务逻辑;
- 真正的语言无关,服务可以用任何语言编写,只需和Service Mesh通信即可;
- 对应用透明,Service Mesh组件可以单独升级;
当然,Service Mesh目前也面临一些挑战:
- Service Mesh组件以代理模式计算并转发请求,一定程度上会降低通信系统性能,并增加系统资源开销;
- Service Mesh组件接管了网络流量,因此服务的整体稳定性依赖于Service Mesh,同时额外引入的大量Service Mesh服务实例的运维和管理也是一个挑战;
历史总是惊人的相似。为了解决端到端的字节码通信问题,TCP协议诞生,让多机通信变得简单可靠;微服务时代,Service Mesh应运而生,屏蔽了分布式系统的诸多复杂性,让开发者可以回归业务,聚焦真正的价值。
要想业务中台建得快,最好用Service Mesh来带
如图是一个简化的Service Mesh架构,服务A和服务B相互调用,不再是以前通过微服务框架直接指向的方式,而是在中间加了两个叫做Sidecar(边车)的东西,各种服务都在这里处理数据上的逻辑。Sidecar的作用是数据面的代理,它是更贴近于数据的;而Sidecar不能完全不受控,上面控制它的就叫做控制面。
实际业务中,尤其是中台架构下,企业往往需要很多的微服务,也就是上述服务A、服务B相互调用的情况会不断扩展,就会逐渐形成更多的服务加Sidecar的组合,就变成了一个真正意义的Service Mesh。
Service Mesh具有三个明显的优势:第一它是一个独立的进程,和业务是解耦的,对业务代码无侵入;第二,是具备跨语言特性,上文说的Dubbo和Spring Cloud其实都是Java技术栈,而Service Mesh具备整合一些C++、Golang之类的异构语言应用的能力,因为它没有进入到进程内;第三是它提供了熔断、限流等丰富的微服务服务治理功能。
这些优势,使得Service Mesh可以比较容易地解决中台架构下微服务化存在的问题。对于使用采购或外包模式的传统企业尤其如此。传统企业往往需要将后台的应用进行封装或者重构为中台,来支撑前台灵活的业务变化,自研系统还可以采用Spring Cloud来重构,但采购的系统只能使用封装的模式,而采购的不同系统一般采用.Net、Spring MVC、PHP、Python等不同的技术栈,如果没有Service Mesh,接入微服务体系就会是一场噩梦。
实施Service Mesh的技术方案
主流云原生Service Mesh框架是Istio,Istio提供了完整的Service Mesh的解决方案,数据面是一个叫Envoy的组件,控制面的组件包括Pilot、Mixer、Citadel和Galley等。在下图服务A调用服务B的流程中,支持这种调用的Sidecar就是用Envoy组件来实现的,下半部分是控制面的组件,最主要的是Pilot,其他是配合功能完整性的一些组件。
先看数据面核心组件Envoy。数据面跟微服务本身相关性非常大的,因为所有的流量以及大部分治理都需要经过它。
七大优势:第一,它是基于现代C++开发的网络L4/L7的代理,这意味着它能够提供很高的性能。
第二是流量管理,Envoy可以对服务流量做路由、分流等动态的管理。
第三是服务治理方面的特性,包括熔断、限流,以及在里面注入一些故障。
第四是多协议支持,Envoy除了支持比较经典的HTTP 1.x版本,还支持2.x版本,也支持gRPC、TCP、Web Socket等。它不仅可以对服务之间调用的流量进行管理,一些DB、缓存其实也可以做到,因为它是网络4-7层的。
第五是负载均衡,Envoy支持的算法非常多。
第六是动态配置API,作为一个数据面应该有接口可以动态去控制,让控制面来调用配置。
第七是可观察性设计,作为一个数据面应该把经过它的流量和数据上报,让后端更庞大的监控系统看到整个微服务体系到底是一个怎样的状态。最后是支持自定义插件扩展能力的,企业对Envoy本身的功能如果不满足,还可以通过插件进行扩展。
Istio的控制面核心组件是Pilot,它最主要的功能是和Sidecar建立双向的gRPC连接,可以通过控制面实时下发配置或是服务发现的信息,包括服务发现和抽象,以及配置的转化和分发。
另外三个组件,Mixer主要是做策略检查跟遥测,包括检查一些权限,或者通过它上报监控数据。Citadel负责安全性方面,可以做证书与秘钥管理相关的分发。Galley是1.1版本正式引入的,主要做配置校验。这些组件中,业界诟病最多的是Mixer做策略检查操作的时候会有性能问题。