微服务架构及其概念
一、信息技术的发展趋势
信息技术从出现到逐渐成为主流,主要经历了软件、开源、云三个阶段的发展。从软件到开源,再到云,这也是信息技术的发展趋势。
1. 软件改变世界
纵观人类社会漫长的发展历史,农耕时代、工业时代与信息时代可谓是明显的三个分水岭,每个时代都会出现很多新兴的领域,作为信息时代最重要的载体,互联网越来越成为当今社会关注的焦点,互联网的基石之一——软件,正在迅速地改变着这个世界。
2. 开源改变软件
随着软件行业的成熟,相比于“重复造轮子”,“站在巨人的肩膀上”明显可以更加容易和快速地创造出优秀的新产品。随着开源文化越来越被认可,以及社区文化越来越成熟,使用优秀的开源产品作为基础架构来快速搭建系统以实现市场战略,成为当今最优的资源配比方案。
3. 云吞噬开源
仅通过开源产品搭建并运维一个高可用、高度弹性化的平台,进而实现互联网近乎100%的可用性,难度可想而知。因此,在提供技术思路的同时,进一步提供整套云解决方案以保证不断扩展的非功能需求,便成了当今新一代互联网平台的追求。
随着用户集群规模的进一步加大,单纯的分布式系统已经难以驾驭,因此技术圈开启了一个概念爆发的时代——SOA、DevOps、容器、CI/CD、微服务、Service Mesh等概念层出不穷,而 Docker、Kubernetes、Mesos、Spring Cloud、Istio 等一系列产品的出现,标志着云时代已真正到来。
二、互联网架构的核心问题
1. 海量用户
当今的互联网大潮,已经越来越难以估算用户量以及由此产生的自然数据增长有多少了,区别于我们日常的生活(例如商场,仅有 10 个人和有 1000 人的购物体验是明显不同的),企业如何做到无差别地为全世界所有的用户提供服务,成了一道难题。
2. 产品迅速迭代
面对当今快速增长的业务和需求,敏捷开发成为了热门的选择。在不断迭代的过程中,时间成本就显得尤为重要。如何敏捷地探知市场需求并将其实现,是互联网行业的立命之本。产品快速升级必然会推动、测试、交付甚至系统迅速迭代。
3. 7x24 小时不间断服务
我们要保证应用全天候不间断的可用,必须要考虑到随时可能发生的意外,例如光缆挖断、机房失火等,每一次宕机都可能会造成巨大的损失。另外,如果系统设计得不够健壮,对其升级和维护时就要停止服务。频繁的系统升级同样会对系统可用性产生很大的影响。
4. 流量突增
流量突增分为可预期型徒增和不可预期型徒增,像促销活动、有计划的热点事件等引起的流量突增属于前者,可以通过提前扩容、预案演练等方式精心为这些流量突增准备应对方案。而意料之外的热点事件(如地震)往往事发突然,系统来不及准备应对措施,因此若系统本身的可用性、弹性等非功能需求十分成熟,便可以在某种程度上应对这种突增。
5. 业务组合复杂
很多互联网公司都是跨界巨头,我们知道,即使不跨界,在单一领域编织一个大规模的成型业务系统也并不简单。
三、单体架构与微服务架构
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 等。一个应用应该是一组小型服务;可以通过HTTP的方式进行互通,每一个功能元素最终都是一个可独立替换和独立升级的软件单元。
四、如何让微服务架构真正的落地
典型问题
1、服务实例太多怎么办?
2、服务调用关系太杂乱怎么办?
3、服务访问出错了怎么办?
4、配置信息散落在各个服务中怎么办?
5、服务调用链路太长怎么办?
SpringCloud微服务架构的优点:
-
易于开发和维护: 一个微服务只会关注一个特定的业务功能,所以它业务清晰、代码量较少。 开发和维护单个微服务相对简单。而整个应用是由若干个微服务构建而成的,所以整个应用也会被维持在一个可控状态。
-
单个微服务启动较快: 单个微服务代码量较少, 所以启动会比较快。
-
局部修改容易部署: 单体应用只要有修改,就得重新部署整个应用,微服务解决了这样的问题。 一般来说,对某个微服务进行修改,只需要重新部署这个服务即可。
-
技术栈不受限: 在微服务架构中,可以结合项目业务及团队的特点,合理地选择技术栈。例如某些服务可使用关系型数据库MySQL;某些微服务有图形计算的需求,可以使用Neo4j;甚至可根据需要,部分微服务使用Java开发,部分微服务使用Node.js开发。
微服务虽然有很多吸引人的地方,但它并不是免费的午餐,使用它是有代价的。使用微服务架构面临的挑战。
-
运维要求较高: 更多的服务意味着更多的运维投入。在单体架构中,只需要保证一个应用的正常运行。而在微服务中,需要保证几十甚至几百个服务服务的正常运行与协作,这给运维带来了很大的挑战。
-
分布式固有的复杂性: 使用微服务构建的是分布式系统。对于一个分布式系统,系统容错、网络延迟、分布式事务等都会带来巨大的挑战。
-
接口调整成本高: 微服务之间通过接口进行通信。如果修改某一个微服务的API,可能所有使用了该接口的微服务都需要做调整。
-
重复劳动: 很多服务可能都会使用到相同的功能,而这个功能并没有达到分解为一个微服务的程度,这个时候,可能各个服务都会开发这一功能,从而导致代码重复。尽管可以使用共享库来解决这个问题(例如可以将这个功能封装成公共组件,需要该功能的微服务引用该组件),但共享库在多语言环境下就不一定行得通了。
五、什么是微服务
“微服务”与“微服务架构”有着本质的区别: “微服务”强调的是服务的大小,它关注的是某一个点。而“微服务架构”则是一种架构思想,需要从整体上对软件系统进行通盘的考虑。
微服务架构就是将一个完整的应用从数据存储开始水平/垂直拆分成多个不同的服务。每个服务都能独立部署、独立维护、独立扩展,各服务之间通过诸如RESTful API(http)的方式互相调用。即微服务是自理自治的服务单元。
说明:拆分角度有垂直拆分/水平拆分。
水平拆分:按照业务对系统进行划分。举个例子,原系统包括了运营和支付,现水平拆分为运营系统和支付系统。优点是:不同业务,往往性能要求,以及请求量是不一样的。拆分后保证业务之间的可用性影响最小化。
垂直拆分:将同样的系统按照应用场景(调用方)进行拆分 。举个例子,原系统的支付场景中包括了用户支付,第三方调用 支付,现垂直拆分为用户支付,商户支付。优点:各个垂直服务调用之间相互不影响,自理自治;通过配置可以进行上游调用降级等。
六、微服务架构的三大要素
微服务架构的第一要素:业务建模
微服务架构设计首要的切入点为服务建模,首先需要明确服务的类别以及服务与业务之间的关系,尽可能明确领域的边界。
服务建模:推荐使用领域驱动设计(Domain Driver Design,DDD)方法,通过识别领域中的各个子域、判断这些子域是否独立、考虑子域与子域的交互关系,从而明确各个界限上下文(Boundary Context)之间的边界。
对于领域的划分,业界普遍认为系统的各个子域可以分为支撑子域、核心子域、通用子域三种类型
系统的核心业务属于核心子域,
专注于某一方面的业务属于支撑子域,
可以归于某一基础设施的功能属于通用子域。
微服务架构的第二要素:技术体系
1、服务通信
SpringCloud使用网络连接模式是短连接
SpringCloud使用的I/O模型是非阻塞式I/O
SpringCloud服务调用方式是同步与异步相结合的方式
2、服务治理
3、服务路由
4、服务容错
5、服务网关
6、服务配置
7、服务安全
8、服务监控
为了解决单体应用的诸多问题,我们提出了分布式的概念,通过将单体应用拆分成诸多单独的模块来降低耦合以及提升系统性能,其实这里就涉及到一个服务化的概念,而微服务与之不同的是:
- 服务拆分粒度更细。微服务可以说是更细维度的服务化,小到一个子子模块,只要该模块依赖的资源与其他模块都没有关系,那么就可以拆分成一个微服务。
- 服务独立部署。每个服务都严格遵循独立打包部署的准则,互不影响。比如一台物理机上可以部署多个 Docker 实例,每个 Docker 实例可以部署一个微服务的代码。
- 服务独立维护。每个微服务都可以交由一个小团队甚至个人来开发、测试、发布和运维,并对整个生命周期负责。
- 服务治理能力要求高。因为拆分为微服务之后,服务的数量变多,因此需要有统一的服务治理平台,来对各个服务进行管理。
尽管微服务和微服务架构有所不同,但我们通常也可以简单理解为:
微服务是一种软件架构风格,它是以专注于单一责任与功能的小型功能区块为基础,利用模组化的方式组合出复杂的大型应用程序,各功能区块使用与语言无关的 API(例如 REST)集相互通讯,且每个服务可以被单独部署,它具备以下三个核心特点:
- 微服务为大型系统而生。随着业务的快速增长,会带来系统流量压力和复杂度的上升,系统的可维护性和可扩展性成为架构设计的主要考虑因素,微服务架构设计理念通过小而美的业务拆分,通过分而自治来实现复杂系统的优雅设计实现。
- 微服务架构是面向结果的。微服务架构设计风格的产生并非是出于学术或为标准而标准的设计,而是在软件架构设计领域不断演进过程中,面对实际工业界所遇到问题,而出现的面向解决实际问题的架构设计风格。
- 专注于服务的可替代性来设计。微服务架构设计风格核心要解决的问题之一便是如何便利地在大型系统中进行系统组件的维护和替换,且不影响整体系统稳定性。
七、微服务本质
微服务,关键其实不仅仅是微服务本身,而是系统要提供一套基础的架构,这种架构使得微服务可以独立的部署、运行、升级,不仅如此,这个系统架构还让微服务与微服务之间在结构上“松耦合”,而在功能上则表现为一个统一的整体。这种所谓的“统一的整体”表现出来的是统一风格的界面,统一的权限管理,统一的安全策略,统一的上线过程,统一的日志和审计方法,统一的调度方式,统一的访问入口等等。
微服务的目的是有效的拆分应用,实现敏捷开发和部署 。
微服务提倡的理念团队间应该是 inter-operate, not integrate 。inter-operate是定义好系统的边界和接口,在一个团队内全栈,让团队自治,原因就是因为如果团队按照这样的方式组建,将沟通的成本维持在系统内部,每个子系统就会更加内聚,彼此的依赖耦合能变弱,跨系统的沟通成本也就能降低。