做者注:
联系方式 leontian1024@gmail.com || github.com/XinyaoTian
新人入行,很是期待能与各位大牛们讨论,感谢各位的阅读,但愿对您有所帮助。
相信每一位老道的开发者和软件工程师们都会有过,曾经( 也许如今仍然 )被庞大且复杂的软件系统所支配的恐惧。随着软件版本的迭代和开发团队人员规模的扩大,曾经那个小巧别致、设计精良的软件或应用一去不返,现在已经变得遍地狼藉,惨不忍睹——混乱的接口、不规范的调用、像贴狗皮膏药通常贴上去的新功能组件……曾经那个赏心悦目的应用,现在看了就反胃。这一切都预示着一个问题:开发软件的方式须要改变。git
纵使有那么多种软件开发模式,但若是不能从底层技术上实现对设计的约束,问题将会随着时间的推移,最终暴露出来。譬如“高内聚,低耦合”的设计理念,若是不能从底层就实现模块间的隔离,而依靠开发时的技巧和经验,那么最终这个软件依旧会变得一团糟( 由于团队会有新人的加入、即便经验老道的开发者也会有头脑发昏的时候…… )。所以,“不这么写就没法运行”这样的硬性要求就颇有必要了。github
云计算和容器技术的出现,很是及时地帮助咱们解决了这一难题。云计算的高弹性和按需分配、容器技术的快速启停和隔离,都很好的帮助了咱们减小运维开销,且对于不一样模块实现操做系统级别的隔离。在这两种关键技术出现先后,软件架构的差异以下图所示:docker
( 上图: 单体应用 与 微服务应用 )
以 Web 应用为例,按照以前的开发方式,咱们每每会选用一个功能齐全但至关复杂的开发框架( 好比JAVA开发经常使用的 SpringBoot ),而后在这个框架的基础上,根据开发经验和框架的功能将整个应用分层( 好比最经常使用的表示层、业务逻辑层和数据资源层的分层方法 ),以后根据需求分析得出的各个功能,经过不一样目录、文件和函数的方式分别开发,最终一个完整的 Web 应用被开发出来。其过程以下图所示。数据库
( 上图: 基于框架的软件开发架构网格 )
经过使用框架,咱们把软件在层次上分为三层,而以后的每一个功能,就至关于纵向地添加一个新列。若是以这种方式看待一个应用,那么咱们就能够将任何基于这种开发方法的应用看做一个3行n列的表格或矩阵了。编程
虽然这种开发方式已经很是普及,很是成熟,但其仍有许多有待改进的地方。好比:网络
依赖和库过于庞杂。理想状况下,咱们但愿针对每个模块,单独管理其相应的依赖和库,而不是以整个应用做为单位来管理。架构
没法改变层次结构。某种层次结构对于某些业务需求来讲很棒,但对于另一些也许就显得不那么合适了。使用这种方式开发,几乎全部功能都要听从这种既定的层次开发( 好比写 UI、写业务逻辑、写数据库层 )。而对于目前日渐快速的迭代和敏捷的开发思想,咱们须要一种更加灵活轻便的方式进行开发。app
没法实现跨语言开发。咱们知道,几乎每种编程语言都有本身最擅长的领域。也许某些功能选用其余编程语言的开发效率更高,运行效果更好。然而,使用这种方式咱们每每只能使用选定的框架所支持的语言。负载均衡
模块的独立性不足。单纯经过函数和文件来进行隔离,隔离性仍然不够。一个疏忽或是加急上线就会让以前良好的高内聚低耦合的良好软件结构灰飞烟灭。所以,咱们须要更加底层的机制来硬性约束咱们实现“高内聚低耦合”,把“应该这么作”变为“必须这么作”。框架
而伴随着云计算和容器技术的发展,微服务的出现,恰巧将这些问题迎刃而解。
( 上图: 容器技术的基本层次结构 )
Docker 能够看做是轻量级的虚拟机——它能够经过“容器镜像”快速启动和中止预先配置好的相应运行环境。每个容器均可以被看做一个独立的操做系统,相互隔离,互不干扰。所以,借助docker 咱们就能够针对一个应用中不一样的功能,为其独立定制运行环境,独立装载依赖和工具库,独立运行独立中止,独立升级,每一个功能可使用其最适合的编程语言进行开发,也将整个应用拘泥于一种框架了。利用 docker 将每一个模块在操做系统层面进行隔离,对于每一个模块均可以独立管理其生命周期了,这就是“微服务”中“微”字的具体含义。
基于这种开发方式,每一个功能模块能够被独立开发,独立部署,独立运行,独立进行版本控制,等等。而对于规模比较庞大的系统来讲,这种利用微服务架构所开发的应用,其自然的优点就更能体现出来了——即每一个模块能够独立的团队由单独负责。所以,微服务开发中的第一个重点,就是要有很是明确的需求,以及一个经验丰富的架构师,在设计之初就对各个功能模块进行合理的规划和拆分。
在整个应用设计之初由总设计师或架构师设计好各个功能模块后,第二个重点就来了:设计微服务中各个模块间的调用接口——一般由 Rest API 或者 gRPC 组成——来负责模块之间的交互,这就是微服务的第二个重点。良好的接口设计将会使你的应用结构清晰,开发起来事半功倍。并且每一个独立团队在开发时都能感觉到明显的模块边界,且能够放心利用模拟数据和测试数据进行开发( 只要符合接口规则的数据就能用,不用操心其余模块是如何实现的 ),从而真正实现每一个团队富有效率的并行开发。
利用微服务架构开发除了上述好处以外,在运维方面的优点也很是直观——咱们能够清晰地观测到整个系统的资源瓶颈在何处( 哪一个容器的资源开销最大 ),从而实现有针对性的“定向扩缩容”。利用微服务架构先后的扩缩容机制以下图所示意。
( 上图: 单体应用和微服务应用最直观的差异:定向扩缩容 示意图 )
在看完上面的介绍后,相信饱受单体应用折磨的各位读者已经对微服务开发已经跃跃欲试了。可是,对于一个正在运行并使用的应用来讲,完彻底全从零开始开发并不现实。对于一个已经成熟并正在使用的单体应用系统来讲,咱们能够经过本身的努力,将一个单体应用在几回迭代过程当中,逐渐改变为微服务应用。如何办到呢?下面放一张图片来帮助您激发灵感:
( 上图: 热带雨林中的参天大树与附着在其上的藤蔓 )
没错,就像您所想到的那样:在这幅图中,庞大的树木表明着咱们原有的单体项目,而树外所覆盖着的藤蔓就象征着微服务组件。在将您的单体应用微服务化时,也能够采用这种方式,即:新的功能使用微服务架构来开发,经过对原有的单体应用暴露 IP 和端口号的方式供其进行调用和使用。
利用这种方式,您以后新开发的功能所对应的软件实体就都是基于微服务架构的了。这样随着时间的推移和版本的逐渐迭代,采用微服务架构所开发的部分所占比例愈来愈大,最后原来的单体应用也逐渐变为了整个应用中的一个独立服务,您的软件架构就完全地完成了微服务化。
这种改造方式来源于 Chris Richardson 的系列博文中的一篇,若是您对这方面内容感兴趣的话,欢迎您移步其博客一探究竟( 博客的中文翻译连接: https://www.jianshu.com/p/29f... )。因为内容过多,在此再也不展开讨论一一赘述。
显然不是,技术的发展历来没有止境,也不存在止镜。微服务的出现,虽然解决了传统软件开发结构庞大、模块复杂等诸多难点,可是解决了原有的问题后,新的问题又浮出了水面:微服务应用的每一个基本单元之间调用关系复杂、网络位置处于动态变化、且每一个组件的生命周期都各自独立,所以难以实现统一的管理。
这里说的可能有些抽象,那么就为你们举一个小例子:请你们设想一个简单的场景:每个微服务组件都有一个本身独有的网络位置( 在因特网中就是咱们最经常使用的 IP 和端口号 ),以此来惟一肯定一个服务;其余服务若想调用本服务,就须要知道该服务的 IP 和端口号,以此对其发送网络请求。
细心的朋友可能已经察觉到问题了:对于一个微服务架构的应用场景,微服务的每个组件都是不断处于动态扩缩容的状态中的,可能上一秒这个 IP 和端口号还对应着相应的组件,下一秒这个组件就因为当前访问量的降低而被节约成本,自动地缩容释放掉了。若是这时其余服务再来访问这个 IP 和端口号,那必定会出现找不到服务等各类故障。
( 上图: 多变的网络位置是微服务管理中的一大难题 )
架构改变所带来的诸如此类的问题还有许多,在此就不一一列举了。准备将本身的软件架构进行微服务化的朋友们须要三思:改变一种软件架构可能会解决许多曾经的架构所存在的问题,但同时也会带来不少原有架构不会出现的新问题。
不过幸亏微服务架构已经有很多国内外的大公司和优秀团队做为先驱,率先摸着石头过了一次河,而且告诉了咱们许多过河的宝贵经验,甚至已经有许多工具和开源项目被开发出来,帮助咱们解决刚才分析到的种种问题了。
在目前种种微服务场景的解决方案中,有两种是使用最为广泛、同时也广受好评的。它们分别是较早出现的 Spring Cloud 框架,以及近几年微服务领域最为流行的 Service Mesh 微服务管理框架。因为 Service Mesh 所带来的“业务代码零侵入”、“直接与容器管理框架(如 K8s )集成”等诸多优势,所以基于 Service Mesh 的微服务开发和蔚云方式正在逐渐成为主流,特别是 Google 宣布了其 Istio 项目能够与 K8s 完美集成后,国内外社区的开发者对 Service Mesh 的发展更是翘首以盼。下面就对 Service Mesh 进行一下简单的介绍。
“A service mesh is a dedicated infrastructure layer for handling service-to-service communication. “ —— William Morgan( Founder of Service Mesh )
Service Mesh 是一个专一于处理服务间通讯的基础设施层。
云原生应用有着复杂的服务拓扑,而 Service Mesh 保证请求能够在这些拓扑中可靠地穿梭。在实际应用当中,Service Mesh 一般是由一系列轻量级的网络代理组成的,它们与应用程序部署在一块儿,但应用程序不须要知道它们的存在。
( 上图: Service Mesh 示意图——帮助您管理错误复杂的微服务应用 )
Service Mesh 的概念最先由前 twitter 的基础设施工程师 William Morgan 于 2017 年 4 月 25 日提出。虽然在此以前,微服务领域也有相似的概念被提出或用于开发项目,但在业界始终没有一个统一的名称。 William Morgan 在本身的博文 "What’s a service mesh? And why do I need one?" 中正式给 Service Mesh 作出了权威的定义。至此,"Service Mesh" 这个名词正式出如今各大公司以及技术社区的视野中。
随着云计算的普及,愈来愈多的开发者和企业开始使用“微服务”的开发模式。这种开发模式拥有诸如耦合度低、跨语言开发、更小粒度扩容等许多优点,但一样也面临着许多挑战,就如咱们上文所分析的那样。
Service Mesh 从出现至今总共经历了三个阶段:微服务初期、Sidecar 时期和 Service Mesh 时期。
在微服务初期( 2015年前 )开发微服务应用的过程当中,咱们须要重复性地处理一系列基础工做,好比:服务注册、服务发现、获得服务实例后的负载均衡、熔断机制等。这些工做在 Service Mesh 出现以前通通都要开发人员在项目中用代码解决并实现,致使应用程序中加入了大量的非功能性代码。即便使用相似 Netflix OSS 的库和 Spring Cloud 的框架,开发人员依然面临着需掌握内容多、技术门槛高等诸多困难。
( 上图: Sidecar ,中文意思为摩托车的跨斗,不禁赞叹命名的很是生动 )
"Sidecar" 这个词,本人使用 Google 搜索引擎同时检索 sidecar 和 microservices 这两个关键字并按时间顺序排序,最先出现的检索结果是在 2014 年 5 月 14 日的这篇演讲中。根据本人查阅的资料显示,"Sidecar" 这个名词最先由 Netflix 提出并被用于 Eureka 项目。因为这个项目的普遍应用,故在此以后,凡是微服务中“用于端对端通讯的、被单独分离出来的“组件,就都被称为 "Sidecar" 了。
仔细分析上述一系列的重复性工做,咱们能够发现,这些工做几乎所有集中在处理各个服务间的通讯问题。那么,为什么咱们不把这些工做从业务逻辑中抽离出来,使其专一于服务间通讯,并造成单独的组件呢?
Sidecar 模式,即在微服务中将关于服务通信的功能抽离出来,并做为一个单独的组件运行在微服务中。这种在微服务中独立负责端对端通讯的组件,咱们称之为 Sidecar 。这种在微服务中将业务逻辑与服务通讯解藕,并分离为两个独立运行组件的作法,正是 Service Mesh 概念的雏形。
但在这个阶段,每一个微服务中的 Sidecar 还没法通用,即这个微服务的 Sidecar 没有办法拆出来给另外一个微服务使用。
Service Mesh 在 Sidecar 模式的基础上更进一步。Service Mesh 的定义——一个专一于处理服务间通讯的基础设施层——站在开发者的角度来说,就是在每个微服务中将用于通讯的部分从业务中完全解藕,应用程序甚至不须要知道它们的存在。在 Service Mesh 中,每一个微服务至少含有两个组件:一个用于处理业务功能的“应用程序”和一个专职处理服务间通讯的“ Sidecar ”( 相似网络代理 )。
Service Mesh 的愿景是但愿开发者不再须要将精力花费在服务通讯上。服务通讯由每一个微服务的 Sidecar 负责,而 Sidecar 由专门的项目来接管。目前,许多被熟知的项目均可以被咱们看成 Sidecar 来运用,好比 Envoy 、 HAProxy 和 Nginx 。
使用了 Service Mesh 以后,开发团队和运维团队就能够更加明确的划清本身的职责范围——开发团队专一于业务的开发,而运维团队只需关注微服务中的 Sidecar 就能够明确地了解到每一个微服务的健康状况和各类指标。
( 上图: “Service Mesh”一词成为技术术语,首次在公众场合亮相 )
Service Mesh 的设计理念和做用
随着云原生应用的崛起,Service Mesh 逐渐成为一个独立的基础设施层。在云原生模型里,一个应用能够由数百个服务组成,每一个服务可能有数千个实例,而每一个实例可能会持续地发生变化。服务间通讯不只异常复杂,并且也是运行时行为的基础。管理好服务间通讯对于保证端到端的性能和可靠性来讲是很是重要的。
Service Mesh 实际上就是处于 TCP/IP 之上的一个抽象层,它假设底层的 L3/L4 网络可以点对点地传输字节(固然,它也假设网络环境是不可靠的,因此 Service Mesh 也必须具有处理网络故障的能力)。
从某种程度上说,Service Mesh 有点相似 TCP/IP 。TCP 对网络端点间传输字节的机制进行了抽象,而Service Mesh则是对服务节点间请求的路由机制进行了抽象。Service Mesh 不关心消息体是什么,也不关心它们是如何编码的。应用程序的目标是“将某些东西从A传送到B”,而 Service Mesh 所要作的就是实现这个目标,并处理传送过程当中可能出现的任何故障。
与TCP不一样的是,Service Mesh有着更高的目标:为应用运行时提供统一的、应用层面的可见性和可控性。经过每一个微服务中的 Sidecar ,Service Mesh 得以将服务间通讯从底层的基础设施中分离出来,让它成为整个生态系统的一等公民——它再也不是单纯的基础设施,更能够被监控、托管和控制。
尽管 Service Mesh 在云原生系统方面的应用已经有了快速的增加,但仍然存在巨大的提高空间。服务发现和访问策略在云原生环境中仍显初级,而 Service Mesh 毫无疑问将成为这方面不可或缺的基础。就像 TCP/IP 做为互联网的基础同样,Service Mesh 将在微服务的底层基础设施这条路上更进一步。
本文主要介绍了两个关键点:当下最为流行的一种软件开发架构——微服务架构、以及解决微服务架构带来的种种问题的微服务管理模型——Service Mesh(服务网格)模型。
在使用微服务架构开发应用的初期,你们必定会沉醉于其清晰的模块边界和独立运行所带来的种种便利。然而,这并非说微服务应用就已经十全十美了。随着一个庞大的单体应用被拆分为细碎的各个微小模块,若是对它们进行有效的管理就成为了新的挑战。毕竟,一个中等体量的应用被微服务化后,几百个小模块同时运行是常有的事儿。那么,如何控制服务之间的调用?如何定位这些服务( 你知道,在这种场景下手动修改配置文件指定其余服务的 IP 和 port 已经不现实了 )?如何将出现错误的应用及时熔断?这都是亟待咱们解决的事情,也是目前微服务架构所发展的主要方向。
在熟练运用 Docker 后,咱们能够继续去学习 Kubernetes,一款由 Google 和 IBM 共同开发的开源“容器集群管理框架”,相似于控制容器的“操做系统”。
而微服务所面临的上述种种问题,目前咱们能够借助一样由 Google 开发的 Istio(服务网格的一种) 来解决,诸如服务注册、服务发现、服务治理、流量管理和容错机制等等。其基本层次关系以下图所示。
( 上图: 本身整理的“目前微服务架构的技术栈”,但愿各位读者有所帮助 )
但愿本篇文章可以成为您开展微服务相关工做的参考,为您了解为服务理念、转型微服务架构提供帮助。文章中若是存在遗漏或错误,也很是欢迎您指出,很是期待与您的交流与讨论。