内容来源:2017 年 12 月 17 日,华为高级软件工程师马博文在“辞旧迎新的第七届西安DevOps MeetUp”进行《云设计模式和Service Mesh》演讲分享。IT 大咖说(微信ID:itdakashuo)作为独家视频合作方,经主办方和讲者审阅授权发布。
阅读字数:3817 | 10分钟阅读
摘要
随着IT技术的快速发展,扩展性越来越成为企业关注的焦点。从应用架构上表现为微服务化,基础设施架构上表现为云化,组织结构去中心化,开发流程敏捷/DevOps化。这其中,企业应用云化是最不被质疑的趋势。然而,现实情况是企业大量的存量应用系统架构不加修改直接移植到云上的可能性比较低,虽然我们可以采用服务的拆分策略(按照功能、数据或者DDD的原则等)来将拆分应用,使其更适于在云上部署。但是在实际的实施过程中,还是会面临很多问题。本次话题将尝试从微软Azure总结云设计模式的角度来看待应用云化、微服务以及被称为可能是下一代微服务的Service Mesh。
架构、基础设施演进历史
架构演进
单体架构相信大家都很熟悉,它所对应的是早期的大型机时代,当时我们期望通过一台性能非常好的机器来承载程序中的所有部分,比如数据库、业务逻辑等。 但这种架构不仅代码复杂,相互之间的调用也很复杂,还很难进行修改。
后来为了方便功能之间的交互,分层架构被提出。这种架构中代码被分为了表现层、业务逻辑层、数据持久层以及数据库层。
之后又发展出了面向服务的SOA架构。所谓服务指的是一个单独的功能单元,可以远程访问并独立执行和更新,例如在线检索信用卡账单。这套架构的基本原则是独立于厂商、产品和技术,并通过网络上的通信协议,应用程序组件将服务提供给其他组件。SOA在技术架构上有局限性,虽然所有的服务都已解耦,但是部署还是在一起,维护起来依然很麻烦。
接下来出现的就是大家很熟悉的微服务架构,它将单体应用程序划分成一组小的服务,服务之间松耦合,使用轻量级通信协议(RPC/REST)进行服务间通信。微服务架构与SOA架构最大的不同在于可以独立部署。基于这些特性所带来的好处不仅是可以更快上线,并且由于服务间使用通信协议交流,所以能够技术异构。另外从应用架构角度来看它的可扩展性和伸缩性也很好,同时它还有一个很好的特性API first,这使得架构对mobile应用很友好。
注:除了这些典型架构外,还有微内核架构以及事件驱动架构,这里不再介绍,读者可以查看Oreilly的《软件架构模式》。
基础设施演进
在基础设施演进的早期阶段,最先使用的是大型机,再往后是x86小型机服务器,一直到这一阶段基础设施的成本还是很高,所以后续才会发展出虚拟化和云化。云化使得基础设施被外包出去,成本得以降低,可维护性得以保障,同时,云服务通常具备可编程性,更容易自动化,很多服务还有着弹性和自恢复的特性。容器化有着平台无关,标准化的特性,可以无缝的在云平台之间切换,由于对资源的利用率高,所以更适合部署微服务,同时还有易伸缩的特性。
基于架构、基础设施、工程实践以及组织结构这四个角度,云原生的概念被提出来,它主要是为了让服务或组织更适应云上运行。在架构层面上微服务是云原生推荐的标准架构,以及12factors应用的实践,基础设施层面主要涉及的是云化和容器化,工程实践层面上则是使用DevOps理念让交付流程更顺畅,组织结构上是去中心化,让团队自治。
不管是云化还是微服务化都不是能够简单完成的,还要面临诸多挑战。首先是云化的挑战,主要有两点,一是如何将遗留系统改造的更适合上云,二是如何更加有效的利用已有的云服务。
微服务化的挑战有以下四点,一是较高的存量遗留系统改造成本,单就从微服务拆分角度来看,业务的复杂度越高拆分难度越大。二是微服务化开发框架方面的问题,目前的微服务框架仅有Java的Spring Cloud和GO的ServiceComb等少量几个,另一方面这些框架虽然能够提供熔断和服务治理方面的能力,但是提高了团队的学习成本和升级维护成本。三是微服务治理功能不完善。四是关于微服务的监控和运维,比如日志、调用等。
云设计模式
云设计模式由微软Azure架构中心推出,提供了32个云设计模式,是可重复的上云方案。我们认为设计模式解决软件的重复性,而云设计模式解决云化的重复性。
云设计模式的分类和内容
Azure从可用性、数据管理、设计实现、消息、管理和监控、性能和可扩展性、弹性、安全等角度抽象出了不同的云设计模式,对于每个模式的描述都遵循模式描述、背景和问题、解决方案、问题和注意事项、何时使用、案例、相关模式和指南这样的流程。下面将对其中的一些设计模式进行具体介绍。
可用性模式:健康端点监控模式
我们一般采用的服务监控方式,不太适用在微服务化场景,一方面是时间滞后,另一方面则是准确性不够。假设这样一个场景,A服务依赖于B服务和某个数据库,某一时刻收到了关于A服务响应慢的警告,这时我们可能无法判断问题是出在B服务上还是数据库上,只能通过查看日志系统才能发现问题。
针对上面的问题健康端点监控系统给出了解决方案,它在应用程序内部实现了检查的功能,外部工具可以定期通过暴露出去的端点访问,以帮助验证应用程序和服务是否正常运行。
数据管理模式:静态内容托管模式
静态内容托管模式是将静态内容部署到云存储服务,然后直接返回给浏览器(前后端分离就是使用这样的模式),当要进行请求的时候,使用CDN来提升性能。这样带来的好处就是完全不用维护,因为这是一个托管服务,也不需要使用工具做监控,同时这样对基础设施的开销也更低。
设计和实现——绞杀者模式
绞杀者模式是服务解耦常用的一种模式,简单来说就是用新的应用程序和服务逐步替换特定的功能。 创建一个外层来拦截请求前往后端旧版系统。 外层可将这些请求路由到旧版应用程序或新服务。 现有功能可逐步迁移到新系统,使用者可继续使用相同的接口,他们并不知道迁移已发生。
设计和实现——网关聚合模式
前后端分离中前端会请求很多的API数据,这不仅造成了网络和性能的损耗,同时也会给服务器带压力。使用网关能够减少客户端与服务之间的通信频率。 网关会接收客户端请求,将请求分派到不同的后端系统,然后聚合结果并将其返回给请求客户端。
设计和实现——网关路由模式
网关路由模式类似Nginx反向代理,在一组应用程序、服务或部署前放置网关。 使用应用层 7 路由将请求路由到相应实例。使用此模式,客户端应用程序只需了解单个终结点并与之通信。 如果服务进行合并或分解,客户端不一定需要更新。 它可以继续向网关发出请求,只有路由会更改。
Service Mesh是用来处理服务间通信的基础设施层,在服务拓扑间实现请求可靠传递,通常实现为一组和应用程序部署在一起的轻量级的网络代理,但对应用程序来说是透明的。Service Mesh的网络代理能够实现很多功能,比如服务发现、负载均衡等,对比微服务框架它让开发者能够更专注于业务开发。而之所以被叫做服务网格,是由于sidecar(单个服务调用)连接起来类似网格。
Istio
Istio是Service Mesh的一个实现,它分为控制面和数据面。数据面就是代理,通过sidecar挎斗模式接入服务,由于和服务本身没有关系,所以可以使用HTTP2、gRPC不同协议等。控制面分为Pilot、Mixer、Istio-Auth三个部分,Pilot包含服务发现、路由、负载均衡等功能,Mixer可以做代理的访问控制、遥测、监控、指标收集、限流等,Istio-Auth负责身份验证、秘钥管理、审计等。
Service Mesh带来的好处显而易见,首先是能够0侵入接入遗留系统或者无微服务框架系统,其次应用层只需要关注业务逻辑,还解决了微服务监控、运维、治理等问题,最后Service Mesh本身的升级和运维是独立的。
目前Service Mesh还是一个比较新的概念,所以还没有能够完全在生产环境中使用。它在数据面工具还算比较多,有Linkerd、Nginx、Envoy、Mesher、Conduit,控制面则寥寥无几,现阶段只有有Istio和CSE。这些工具由于都是容器化的,所以大部分都是运行在k8s上。
注:本话题分享时,Istio还处于比较早期的版本,在0.6以后,我们尝试使用Istio,在生产环境上部署流量较少,不那么重要的服务。从实际的使用过程来看,它在如下方面带来的极大的好处:
1)开发可以专注业务代码开发,服务治理的任务交给Istio来完成。
2)可以根据服务特性,采用合适的语言开发,不用担心服务注册发现客户端引入的问题。
3)使用很小的成本就可以实现0宕机时间的自动化部署以及灰度发布。
在目前的使用中,我们使用Istio遇到的问题主要是Kubenetes的维护上,以及Istio本身还不够成熟,遇到的bug通常只能通过升级、重启去解决,团队缺乏Istio的经验。当然这些随着Istio本身的成熟以及团队成员进一步的总结学习,是可以解决的。