服务架构演进史
本文为周志明老师的凤凰架构阅读摘抄笔记。
1.原始分布式时代
“调用远程方法”与“调用本地方法”尽管只是两字之差,但若要同时兼顾简单、透明、性能、正确、鲁棒、一致等特点的话,两者的复杂度就完全不可同日而语了。且不说远程方法不能再依靠本地方法那些以内联为代表的传统编译优化来提升速度,光是“远程”二字带来的网络环境下的新问题,譬如,远程的服务在哪里(服务发现),有多少个(负载均衡),网络出现分区、超时或者服务出错了怎么办(熔断、隔离、降级),方法的参数与返回结果如何表示(序列化协议),信息如何传输(传输协议),服务权限如何管理(认证、授权),如何保证通信安全(网络安全层),如何令调用不同机器的服务返回相同的结果(分布式数据一致性)等一系列问题,全部都需要设计者耗费大量心思。
当调用本地服务时(即方法),不会有各种各样的问题。如果是远程调用,则需要解决各种问题。服务发现、负载均衡、服务出现故障、序列化、传输、认证授权等一系列问题。
Spring Cloud是用来解决上述问题的,让我们不用考虑这些实现的细节,但能完成远程调用的目的。
摘抄自原始分布式时代
2.单体系统时代
单体架构(Monolithic)
“单体”只是表明系统中主要的过程调用都是进程内调用,不会发生进程间通信,仅此而已。
单体系统不应该被当做一个大反派,该名词的出现,是因为分布式出现后的追认。但所有的分布式书籍都会嘲讽单体应用是个噩梦。但它们的前提是大型单体应用。如果一个应用在单机上可以完成它的任务,则完全没有必要拆分。
对于小型系统——即由单台机器就足以支撑其良好运行的系统,单体不仅易于开发、易于测试、易于部署,且由于系统中各个功能、模块、方法的调用过程都是进程内调用,不会发生进程间通信(Inter-Process Communication,IPC。广义上讲,可以认为 RPC 属于 IPC 的一种特例,但请注意这里两个“PC”不是同个单词的缩写),因此也是运行效率最高的一种架构风格,完全不应该被贴上“反派角色”的标签,反倒是那些爱赶技术潮流却不顾需求现状的微服务吹捧者更像是个反派。单体系统的不足,必须基于软件的性能需求超过了单机,软件的开发人员规模明显超过了“2 Pizza Team”范畴的前提下才有讨论的价值,因此,本文后续讨论中所说的单体,均应该是特指“大型的单体系统”,也正因如此,本节中说到“单体是出现最早的架构风格”,与上一节介绍原始分布式时代开篇提到的“使用多个独立的分布式服务共同构建一个更大型系统的设想与实际尝试,反而要比今天大家所了解的大型单体系统出现的时间更早”实际并无矛盾。
RPC:Remote Procedure Call。远程过程调用
IPC:Inter-Process Communication。进程间通信
从纵向角度来看,笔者从未见过实际生产环境里有哪个大型的现代信息系统是完全不分层的。分层架构(Layered Architecture)已是现在几乎所有信息系统建设中都普遍认可、采用的软件设计方法,无论是单体还是微服务,抑或是其他架构风格,都会对代码进行纵向层次划分,收到的外部请求在各层之间以不同形式的数据结构进行流转传递,触及最末端的数据库后按相反的顺序回馈响应,如图 1-1 所示。对于这个意义上的“可拆分”,单体架构完全不会展露出丝毫的弱势,反而可能会因更容易开发、部署、测试而获得一些便捷性上的好处。
为了允许程序出错,为了获得隔离、自治的能力,为了可以技术异构等目标,是继为了性能与算力之后,让程序再次选择分布式的理由。然而,开发分布式程序也并不意味着一定要依靠今天的微服务架构才能实现。在新旧世纪之交,人们曾经探索过几种服务拆分方法,将一个大的单体系统拆分为若干个更小的、不运行在同一个进程的独立服务,这些服务拆分方法后来导致了面向服务架构(Service-Oriented Architecture)的一段兴盛期,我们称其为“SOA 时代”。
单体架构最大的问题就是,如果所有的开发人员都在一个服务中开发,那么你就要假设所有的开发人员的水平均在同一层次,否则,程序必然出现健壮性等问题,造成大问题。
如果系统进行合理拆分。比如订单系统、秒杀系统,物流系统。一个系统出现问题,只会影响该系统的问题。但如果采用单体系统,那出现的问题则是致命的。
如果单体服务能解决的问题,就不要采用微服务。
微服务的目的不是“微”,而是合适的大小。如果纯粹为了做微服务而做,则毫无意义。
要注意IO密集型、CPU密集型、内存密集型任务。
“CPU 密集”的功能:图像处理和调整大小、缩略图生成、PDF 导出、PDF 导入、ZIP 压缩文件生成。
3.SOA时代
SOA 架构(Service-Oriented Architecture)
面向服务的架构是一次具体地、系统性地成功解决分布式服务主要问题的架构模式。
为了对大型的单体应用进行拆分,提出过很多种架构。
烟囱架构。即每个应用都是独立的。但每个系统不会真的完全独立。所以不适用。
微内核架构。每个系统不会完全独立,就将一些公用的,核心的,作为一个核心,其余不核心的当做一个个插件。
事件驱动。每个系统之间的通信依靠事件通信,比如系统A需要系统B协助,可以发送一个事件。
SOA 在 21 世纪最初的十年里曾经盛行一时,有 IBM 等一众行业巨头厂商为其呐喊冲锋,吸引了不少软件开发商、尤其是企业级软件的开发商的跟随,最终却还是偃旗息鼓,沉寂了下去。在稍后的远程服务调用一节,笔者会提到 SOAP 协议被逐渐边缘化的本质原因:过于严格的规范定义带来过度的复杂性。而构建在 SOAP 基础之上的 ESB、BPM、SCA、SDO 等诸多上层建筑,进一步加剧了这种复杂性。开发信息系统毕竟不是作八股文章,过于精密的流程和理论也需要懂得复杂概念的专业人员才能够驾驭。SOA 诞生的那一天起,就已经注定了它只能是少数系统阳春白雪式的精致奢侈品,它可以实现多个异构大型系统之间的复杂集成交互,却很难作为一种具有广泛普适性的软件架构风格来推广。SOA 最终没有获得成功的致命伤与当年的EJB如出一辙,尽管有 Sun Microsystems 和 IBM 等一众巨头在背后力挺,EJB 仍然败于以 Spring、Hibernate 为代表的“草根框架”,可见一旦脱离人民群众,终究会淹没在群众的海洋之中,连信息技术也不曾例外过。
4.微服务时代
微服务架构(Microservices)
微服务是一种通过多个小型服务组合来构建单个应用的架构风格,这些服务围绕业务能力而非特定的技术标准来构建。各个服务可以采用不同的编程语言,不同的数据存储技术,运行在不同的进程之中。服务采取轻量级的通信机制和自动化的部署机制实现通信与运维。
微服务:可以不同的服务使用不同的编程语言,只是需要能进行通信。