微服务架构 | 服务架构的演进
hi,这里桑小榆。
本篇,我们开始探讨微服务架构这块内容,并打算专门写一个微服务的专栏。写微服务的知识体系其实早有动机,把微服务架构知识梳理完整,由于很多因素没能开展开来,所以一直搁置了。
这次,我继续持大道至简的思想,来探讨微服务架构的全面内容。尽管我们在实际工作中并没有用到这块内容,本职本分或许是螺丝钉角色,但微服务的热门程度以及发展趋势,迫切使你很有必要了解这块内容,并当作知识储备起来,也许有朝一日在面试中或者和码友谈论时也能够有些观点。
我们先不直接引出微服务的概念,我们先了解一下软件架构的演进,毕竟了解一个事务最好的出发点是了解它的背景,由来以及发展,为后续了解微服务更加的得心应手。
单体架构
在早期90年代互联网发展中,产生了软件工程,并催生了以C语言为代表的面向对象的高级语言。同时,单体架构也由此产生,我相信从事it行业的小伙伴对单体架构并不陌生。当时软件概念还没普及,面对需求更多以一个单体项目开发的功能模块,所有的代码逻辑耦合在一起,一两个人就可以负责所有的功能业务开发,对于当时的用户使用量来说,单体架构足够应付。
单体架构的方式,直接干练,到目前为止使用量也不在少数,毕竟这种架构方式也符合人类便捷思维的一种方式。类似的提出面向对象思想之前,使用的面向过程思想,一个功能按照有序的顺序一步步编写有序调用,这也是人们倾向的思考思维。
很明显,我们能够看到单体架构的优势:
易于开发,直接使用开发工具创建一个项目即可入手开发。
易于部署,开发完之后,直接打包部署在适应的服务器,例如:apache,iis,tomcat等。
易于扩展,需要扩展的功能我们也可以直接下手开发,甚至可以将项目打包多份运行在多台服务器实现负载均衡。
然而,以现在用户使用量的角度来看单体架构,它的弊处也随处可见。
庞大的单体代码库,会吓倒自己和同事,也会吓跑新手。一时接手也需要花不少时间去逐个理解,单体架构庞大之后没有清晰的模块划分,可能会随着时间推移,且每个人代码习惯也会面临不一样,导致模块被分解,整体代码变得越来越难理解,代码的质量也逐渐下降,也就是我们俗称的“shit mountain。”谁碰谁倒霉!
IDE过载较大,面临成堆的代码量,你可能早上高兴上班,启动项目的时间就已经喝了两杯咖啡了,或许新同事的不正确操作引来一堆红色警告,上午时间没了,血压也上去了。
持续部署的困难。面临大型单体应用程序,刚开始开发完很顺利,部署也很顺利。然而,产品经理每次经过你的岗位,面带微笑,提了一堆需求给你,今晚改完发布。
改完之后你需要重新部署整个应用程序,有时还得先中断其他后台任务,无论受不受你当前更改的影响,最终导致问题的概率会增加。
或许因为新需求改动了组件,一部署即error警告,此时整个项目便无法运行,或许你在代码里不小心写了一行让cpu飙升的代码,导致服务器宕机整个服务也无法使用了,真让人头大。
扩展应用程序可能变得困难,单体架构扩展只能在本身程序里扩展。我们虽然可以通过复制部署到多台服务器或者云服务来部署实现负载均衡,并根据负载数量来调整实例数量(也就是拷贝部署多少个服务)。
但是在与数据交互时,所有服务始终都是使用一个数据库访问所有数据,这很显然降低了缓存效率并增加了内存消耗和IO流量,也就是数据访问量上来了,本该走缓存了却直接跑去访问数据库,大量访问数据库的同时需要频繁调度内存以及频繁输送数据,这将会是很糟糕的情况。
扩展开发的障碍。单体应用也会阻碍扩展开发,到了一定规模之后,我们很难将UI,商品,库存分开独立开发,都将在一个应用程序里开发,任何一个出问题或者拖延了开发周期都将会影响到整个的服务,团队也将必须协调开发工作和重新部署。
需要对技术堆栈做出长期承诺。开发单体程序被迫使你在开发之初时选择的技术栈要保持一致。如果我们当初选择了C#开发,那么后期想使用Go开发,那么将会是一件困难的事情,因为单体程序很难兼容其他的技术栈使用,要么将选择重构,面对庞大的单体程序重构一堆“shit mountain”将会面临不小的挑战。
说了单体应用的诸多缺点,并不是我在找茬,它本身不是缺点,是在于面对型应用和超大型应用的出现(单纯应用的庞大,用户数并不庞大),以及用户量剧增时体现出来的不适用性,迫切需要新的且适应的架构方式来解决我们的麻烦。
垂直架构
于是,垂直架构出现了,也成为竖井式架构。可能有伙伴没听过垂直架构,这也是架构演进的一种必然趋势。面对单体架构的不足,架构师们很显然会从单体架构里按照业务做垂直划分成多个单体应用,此时由原来的单体应用变成了多单体应用部署。所谓的垂直就是在一个应用里,根据业务来划分独立的模块,每个业务模块做专一的事情并没有直接的关联。
将庞大的系统进行划分多个单体应用,可以很好地实现流量分担,解决一定程度的并发问题。
可以针对不同模块进行优化,将减少因为一个改动影响整个系统的麻烦。
更加方便水平扩展,也就是多个单体里每个单体拷贝副本部署到多个服务器里,更好地实现负载均衡,容错率也显著提高。
单体之间相互独立,互不影响,针对不同模块进行优化,不会因为一个组件或者一个error导致整个系统崩溃,面对新增业务的迭代更加高效。
然而,虽然是将一个单体拆分为多个单体,但是必然需要服务之间互相调用,如果某个服务的端口或者ip发生改变,调用的系统也需要手动更改,偏向硬编码。
搭建集群时,我们拆分的多个单体应用并拷贝副本部署多套服务搭建在一起共同工作,集群之后看似一个完整的个体应用实则内部多个节点互相协同负载工作均衡。但是,垂直架构的集群将会面临内外网负载的问题,迁移机器时影响调用方的路由,导致路径故障无法正常使用。
服务之间的调用方式存在不统一,基于httpclient,webservice等接口的协议不统一。
服务监控不够健全。除了依靠端口、进程监控这些能够提供监控,其余调用的成功率、失败率、耗时等等指标性的是没有的。
所以面对现有的瓶颈,且伴随互联网的急剧发展,应用的使用逐渐普及挨家挨户,用户规模呈指数级增长。垂直架构虽然能够应付应用的庞大,但是很难满足承载海量用户的需求。并且随着分布式理论和分布式技术的日渐成熟,面向服务架构(SOA)开始出现,并广泛应用于大型的系统上。
面向服务架构
面向服务架构(SOA),可以理解为一个组件模型,将应用程序按照不同功能单元(称为服务)进行拆分,使得这些服务之间定义良好的接口和协议联系起来。
它的宗旨在于将程序或软件组件构建为服务,提供一种发布可用服务机制,包括它们的功能和输入输出(I/O)要求。并且控制这些服务的正常使用以及避免安全和治理问题。
看到这里,你会发现面向服务架构对于应用的拆分相比于垂直机构的拆分,颗粒度粗细上明显细了一个量级。
面向服务架构的模式主要有两种,一种是企业服务总线(ESB)为代表的SOA,另一种是RPC为代表的SOA。
企业服务总线(ESB),是一种模式,当我们通过SOA按照不同功能进行拆分的多个服务,然后我们搭建一个消息总线,来连接这些拆分的各个服务,所有的服务产生的消息都需要经过消息总线,通过消息总线来进行转化、解释以及路由工作,达成了一种以消息总线为中心的服务通讯的协议。
RPC(remote procedure call)远程过程调用,也就是本地调用一个函数或者对象方法,实际上是调用了远程服务器上的函数和方法。这也很好理解,我们划分了多个一定颗粒的服务,此时是游离且独立的,我们需要使得这些服务具备互相通讯的功能,我们会想到http或者webservice来进行通讯,也是rpc思想的一种体现,http虽然具备完整的通讯体系和标准的规范,但是满足不了企业的内网和外网之间日益复杂的信息交互。所以现如今成熟的prc框架也有不少,可以拿来使用,例如:阿里巴巴开源的Dubbo,微博开源的Motan,腾讯开源的Tars,国外Pivotal公司开源的SpringCloud,谷歌开源的gPRc,facebook开源的Thrift等。这里不再展开讲解框架的内容,有兴趣伙伴可各自翻阅相关资料,
相比于ESB和RPC这两种模式,由于ESB的初始搭建需要一定的人力物力,以及面对持续高涨的数据通讯压力而难以追踪,人们更加倾向于使用RPC模式,可以直接引用标准的http来通讯,或者使用开源的框架。
我们可以看到面向服务架构(SOA)的优点:
可重用性高。由于一个个服务具备独立且规范的restful风格,我们不再需要重构或者考虑它的底层技术栈如何。
易于维护。因为所有的服务都是相互独立的,因为我们可以轻松应对后期的修改和更新,不会影响到其他服务。很好地降低了组织的运营成本。
促进互操作性。我们使用标准化的通讯协议使得平台能够轻松地在客户端与服务之间传递数据,无需考虑它们所构建的语言是什么。
高可用性。我们可以很好的提供服务的可用性,服务的独立增加系统的容错率,通过集群可以大大的提高服务的可用性。
高可靠性。SOA架构能够生成可靠的应用程序,因为调试小型服务要比调试大型服务要方便的多。
可扩展性。SOA架构使得服务可以在不同的服务环境运行,从而提高了可扩展性。此外,使用标准通讯协议允许组织降低客户端和服务器之间的交互级别。降低交互级别允许在不增加额外的压力情况下进行扩展应用程序。
但是SOA的架构的ESB模式由于本身存在复杂性,和internet的restful api模型也不兼容,且面对高涨的数据通讯一时也难以捕捉和追踪。
SOA架构的初期实施也需要大量的人力和物力的投资。
服务管理很复杂,因为服务交换了数百万条数据难以跟踪消息。
每次服务通讯时都会验证服务的输入参数,从而降低性能并增加负载和相应时间。
总结
发展到SOA时,更多的使用这些架构的驱动力是业务推动的。由于restful(统一接口服务原则)的出现,人们更为广泛接受这个模式,将广泛的“服务”概念转换为“软件流程”而不是“业务流程”,并且以软件架构为中心的趋势,也就是说我们常说的微服务。微服务对于服务的分解更为多样,比如我们可以根据业务能力拆分、子域拆分、独立服务,按照团队等。
当然这些思想将会在后续逐一探讨,本篇主要以服务架构的演进为主。
纵观以上服务架构演进的历程,我们很容易发现软件架构演进的规则,那就是一个字:拆!从一个单体应用拆分为多个单体,再进行拆分,拆分为众多的小型服务,最终拆分成一个个细微且独立的服务,每个独立的服务拥有高度自治的能力,这也是去中心化的体现。
好了,软件架构的发展部分就到这了,如果有兴趣对文中提到的技术栈感兴趣也可去多了解,接下来我们一起推进微服务,认识微服务到底是啥。
抛一个网络出现的一个话题:领导说把服务拆分开来,就是在做微服务,对此你怎么看呢?
喜欢的话,点个👍也是支持~