微服务初识
前排提醒,这是一篇转载文章仅用于学习使用。原文地址:https://www.wmyskxz.com/2019/06/07/shi-me-shi-wei-fu-wu/
一、信息技术发展趋势
信息技术发展的三个阶段
信息技术从出现到逐渐成为主流,主要经历了软件、开源、云三个阶段的发展。从软件到开源,再到云,这也是信息技术的发展趋势。
1. 软件改变世界
纵观人类社会漫长的发展历史,农耕时代、工业时代与信息时代可谓是明显的三个分水岭,每个时代都会出现很多新兴的领域,作为信息时代最重要的载体,互联网越来越成为当今社会关注的焦点,互联网的基石之一——软件,正在迅速地改变着这个世界。
2. 开源改变软件
随着软件行业的成熟,相比于“重复造轮子”,“站在巨人的肩膀上”明显可以更加容易和快速地创造出优秀的新产品。随着开源文化越来越被认可,以及社区文化越来越成熟,使用优秀的开源产品作为基础架构来快速搭建系统以实现市场战略,成为当今最优的资源配比方案。
3. 云吞噬开源
仅通过开源产品搭建并运维一个高可用、高度弹性化的平台,进而实现互联网近乎100%的可用性,难度可想而知。因此,在提供技术思路的同时,进一步提供整套云解决方案以保证不断扩展的非功能需求,便成了当今新一代互联网平台的追求。
随着用户集群规模的进一步加大,单纯的分布式系统已经难以驾驭,因此技术圈开启了一个概念爆发的时代——SOA、DevOps、容器、CI/CD、微服务、Service Mesh等概念层出不穷,而 Docker、Kubernetes、Mesos、Spring Cloud、Istio 等一系列产品的出现,标志着云时代已真正到来。
互联网架构的核心问题
1. 海量用户
当今的互联网大潮,已经越来越难以估算用户量以及由此产生的自然数据增长有多少了,区别于我们日常的生活(例如商场,仅有 10 个人和有 1000 人的购物体验是明显不同的),企业如何做到无差别地为全世界所有的用户提供服务,成了一道难题。
2. 产品迅速迭代
面对当今快速增长的业务和需求,敏捷开发成为了热门的选择。在不断迭代的过程中,时间成本就显得尤为重要。如何敏捷地探知市场需求并将其实现,是互联网行业的立命之本。产品快速升级必然会推动、测试、交付甚至系统迅速迭代。
3. 7x24 小时不间断服务
我们要保证应用全天候不间断的可用,必须要考虑到随时可能发生的意外,例如光缆挖断、机房失火等,每一次宕机都可能会造成巨大的损失。另外,如果系统设计得不够健壮,对其升级和维护时就要停止服务。频繁的系统升级同样会对系统可用性产生很大的影响。
虽然随时随处可用的难度非常大,但互联网应用会尽量缩短宕机时间。通常使用 35 个 9(3 个 9 即 99.9%,4 个 9 即 99.99%,5 个 9 即 99.999%)作为衡量系统可用性的指标,表示系统在 1 年的运行过程中可以正常使用的时间与总运行时间的比值,下面分别计算 35 个 9 指标下的全年宕机时间,感受一下它们的可靠性差异:
3 个 9:(1 - 99.9%) x 365 x 24 = 8.76 小时
4 个 9:(1 - 99.99&) x 365 x 24 = 52.6 分钟
4 个 9:(1 - 99.999&) x 365 x 24 = 5.26 分钟
4. 流量突增
流量突增分为可预期型徒增和不可预期型徒增,像促销活动、有计划的热点事件等引起的流量突增属于前者,可以通过提前扩容、预案演练等方式精心为这些流量突增准备应对方案。而意料之外的热点事件(如地震)往往事发突然,系统来不及准备应对措施,因此若系统本身的可用性、弹性等非功能需求十分成熟,便可以在某种程度上应对这种突增。
5. 业务组合复杂
很多互联网公司都是跨界巨头,我们知道,即使不跨界,在单一领域编织一个大规模的成型业务系统也并不简单。
上图是我从 ProcessOn 模板里随便找的一张关于电商平台应用服务的架构图,可以看到里面交织了各种各样的业务,当行业的扩张速度超出预计的增长的时候,对底层支撑的考验要求也越来越高。
二、什么是微服务
需要注意,“微服务”与“微服务架构”有着本质的区别: “微服务”强调的是服务的大小,它关注的是某一个点。而“微服务架构”则是一种架构思想,需要从整体上对软件系统进行通盘的考虑。
架构的演变
要了解微服务是如何诞生的,我们有必要对架构的演变过程有一定的了解。上面已经对架构主要面临的问题进行了阐述,下面我们来了解一下架构是如何一步一步升级并转化到“云”上的。
1. 单体架构
单体架构比较初级,典型的三级架构,前端(Web/手机端)+中间业务逻辑层+数据库层。这是一种典型的 MVC 框架的应用。
单体架构的应用比较容易部署、测试, 在项目的初期,单体应用可以很好地运行。然而,随着需求的不断增加, 越来越多的人加入开发团队,代码库也在飞速地膨胀。慢慢地,单体应用变得越来越臃肿,可维护性、灵活性逐渐降低,维护成本越来越高。下面是单体架构应用的一些缺点:
- 复杂性高: 以一个百万行级别的单体应用为例,整个项目包含的模块非常多、模块的边界模糊、 依赖关系不清晰、 代码质量参差不齐、 混乱地堆砌在一起。可想而知整个项目非常复杂。 每次修改代码都心惊胆战, 甚至添加一个简单的功能, 或者修改一个 Bug 都会带来隐含的缺陷。
- 技术债务: 随着时间推移、需求变更和人员更迭,会逐渐形成应用程序的技术债务, 并且越积 越多。“ 不坏不修”, 这在软件开发中非常常见, 在单体应用中这种思想更甚。 已使用的系统设计或代码难以被修改,因为应用程序中的其他模块可能会以意料之外的方式使用它。
- 部署频率低: 随着代码的增多,构建和部署的时间也会增加。而在单体应用中, 每次功能的变更或缺陷的修复都会导致需要重新部署整个应用。全量部署的方式耗时长、 影响范围大、 风险高, 这使得单体应用项目上线部署的频率较低。 而部署频率低又导致两次发布之间会有大量的功能变更和缺陷修复,出错率比较高。
- 可靠性差: 某个应用Bug,例如死循环、内存溢出等, 可能会导致整个应用的崩溃。
- 扩展能力受限: 单体应用只能作为一个整体进行扩展,无法根据业务模块的需要进行伸缩。例如,应用中有的模块是计算密集型的,它需要强劲的CPU; 有的模块则是IO密集型的,需要更大的内存。 由于这些模块部署在一起,不得不在硬件的选择上做出妥协。
- 阻碍技术创新: 单体应用往往使用统一的技术平台或方案解决所有的问题, 团队中的每个成员 都必须使用相同的开发语言和框架,要想引入新框架或新技术平台会非常困难。
2. 分布式架构
中级架构,分布式应用,中间层分布式 + 数据库分布式,是单体架构的并发扩展,将一个大的系统划分为多个业务模块,业务模块分别部署在不同的服务器上,各个业务模块之间通过接口进行数据交互。数据库也大量采用分布式数据库,如 Redis、Elasticsearch、Solor 等。通过 LVS/Nginx 代理应用,将用户请求均衡的负载到不同的服务器上。
该架构相对于单体架构来说,这种架构提供了负载均衡的能力,大大提高了系统负载能力,解决了网站高并发的需求。另外还有以下特点:
- 降低了耦合度: 把模块拆分,使用接口通信,降低模块之间的耦合度。
- 责任清晰: 把项目拆分成若干个子项目,不同的团队负责不同的子项目。
- 扩展方便: 增加功能时只需要再增加一个子项目,调用其他系统的接口就可以。
- 部署方便: 可以灵活的进行分布式部署。
- 提高代码的复用性: 比如 service 层,如果不采用分布式 REST 服务方式架构就会在手机 wap 商城,微信商城,PC,Android,IOS 每个端都要写一个 service 层逻辑,开发量大,难以维护一起升级,这时候就可以采用分布式 REST 服务方式,公用一个 service 层。
缺点: 系统之间的交互要使用远程通信,接口开发增大工作量,但是利大于弊。
3. 微服务架构
微服务架构,主要是中间层分解,将系统拆分成很多小应用(微服务),微服务可以部署在不同的服务器上,也可以部署在相同的服务器不同的容器上。当应用的故障不会影响到其他应用,单应用的负载也不会影响到其他应用,其代表框架有 Spring cloud、Dubbo 等。
- 易于开发和维护: 一个微服务只会关注一个特定的业务功能,所以它业务清晰、代码量较少。 开发和维护单个微服务相对简单。而整个应用是由若干个微服务构建而成的,所以整个应用也会被维持在一个可控状态。
- 单个微服务启动较快: 单个微服务代码量较少, 所以启动会比较快。
- 局部修改容易部署: 单体应用只要有修改,就得重新部署整个应用,微服务解决了这样的问题。 一般来说,对某个微服务进行修改,只需要重新部署这个服务即可。
- 技术栈不受限: 在微服务架构中,可以结合项目业务及团队的特点,合理地选择技术栈。例如某些服务可使用关系型数据库MySQL;某些微服务有图形计算的需求,可以使用Neo4j;甚至可根据需要,部分微服务使用Java开发,部分微服务使用Node.js开发。
微服务虽然有很多吸引人的地方,但它并不是免费的午餐,使用它是有代价的。使用微服务架构面临的挑战。
- 运维要求较高: 更多的服务意味着更多的运维投入。在单体架构中,只需要保证一个应用的正常运行。而在微服务中,需要保证几十甚至几百个服务服务的正常运行与协作,这给运维带来了很大的挑战。
- 分布式固有的复杂性: 使用微服务构建的是分布式系统。对于一个分布式系统,系统容错、网络延迟、分布式事务等都会带来巨大的挑战。
- 接口调整成本高: 微服务之间通过接口进行通信。如果修改某一个微服务的API,可能所有使用了该接口的微服务都需要做调整。
- 重复劳动: 很多服务可能都会使用到相同的功能,而这个功能并没有达到分解为一个微服务的程度,这个时候,可能各个服务都会开发这一功能,从而导致代码重复。尽管可以使用共享库来解决这个问题(例如可以将这个功能封装成公共组件,需要该功能的微服务引用该组件),但共享库在多语言环境下就不一定行得通了。
4. Serverless 架构
当我们还在容器的浪潮中前行时,已经有一些革命先驱悄然布局另外一个云计算战场:Serverless 架构。
Serverless 架构能够让开发者在构建应用的过程中无需关注计算资源的获取和运维,由平台来按需分配计算资源并保证应用执行的SLA(服务等级协议),按照调用次数进行计费,有效的节省应用成本。
由于该架构有一定的超前性,这里不做过多介绍,感兴趣的童鞋可以戳这里:https://jimmysong.io/posts/what-is-serverless/
微服务定义
通过上面简单的介绍,我们了解了我们的架构是如何一步一步过渡到微服务的,为了解决单体应用的诸多问题,我们提出了分布式的概念,通过将单体应用拆分成诸多单独的模块来降低耦合以及提升系统性能,其实这里就涉及到一个服务化的概念,而微服务与之不同的是:
- 服务拆分粒度更细。微服务可以说是更细维度的服务化,小到一个子子模块,只要该模块依赖的资源与其他模块都没有关系,那么就可以拆分成一个微服务。
- 服务独立部署。每个服务都严格遵循独立打包部署的准则,互不影响。比如一台物理机上可以部署多个 Docker 实例,每个 Docker 实例可以部署一个微服务的代码。
- 服务独立维护。每个微服务都可以交由一个小团队甚至个人来开发、测试、发布和运维,并对整个生命周期负责。
- 服务治理能力要求高。因为拆分为微服务之后,服务的数量变多,因此需要有统一的服务治理平台,来对各个服务进行管理。
尽管微服务和微服务架构有所不同,但我们通常也可以简单理解为:
微服务是一种软件架构风格,它是以专注于单一责任与功能的小型功能区块为基础,利用模组化的方式组合出复杂的大型应用程序,各功能区块使用与语言无关的 API(例如 REST)集相互通讯,且每个服务可以被单独部署,它具备以下三个核心特点:
- 微服务为大型系统而生。随着业务的快速增长,会带来系统流量压力和复杂度的上升,系统的可维护性和可扩展性成为架构设计的主要考虑因素,微服务架构设计理念通过小而美的业务拆分,通过分而自治来实现复杂系统的优雅设计实现。
- 微服务架构是面向结果的。微服务架构设计风格的产生并非是出于学术或为标准而标准的设计,而是在软件架构设计领域不断演进过程中,面对实际工业界所遇到问题,而出现的面向解决实际问题的架构设计风格。
- 专注于服务的可替代性来设计。微服务架构设计风格核心要解决的问题之一便是如何便利地在大型系统中进行系统组件的维护和替换,且不影响整体系统稳定性。
参考资料
1. 浅谈web网站架构演变过程 - https://www.cnblogs.com/xiaoMzjm/p/5223799.html
2. 互联网架构演进之路 - https://zhuanlan.zhihu.com/p/42115757
3. 四种软件架构演进史 - https://blog.csdn.net/xinyuan_java/article/details/88394332
4. 《未来架构 从服务化到云原生》 - 张亮 等著
扩展阅读:
1.微服务的4个设计原则和19个解决方案 - http://p.primeton.com/articles/59b0f9244be8e61fea00be67