以前写了一篇秒杀系统的文章,最后给本身埋了分布式事务的坑,而后不少读者就要求我去写分布式事务,那做为程序员届的暖男,我一贯是有求必应的,就算是不睡觉我都要写给大家看的!
由于分布式事务是:分布式 + 事务 = 分布式事务。前端
理所固然的要先谈谈分布式,而分布式又得谈谈这个概念是如何演进得来的,所以做为创做鬼才的我,就先来说讲架构的演进,什么叫分布式?什么是集群?SOA、微服务这两个东西的关系和区别,下篇再讲分布式事务。程序员
由于我发现我读者大多都是学生或者跟我同样刚毕业不久,那一直听分布式估计都听腻了,估计都还不知道分布式的一些细节和架构演进路线吧。
先来讲个题外话,我一直追崇一个技术点不只要理解其原理,还须要知道这个技术点解决了哪些痛点,这些痛点又是由什么引起的?这个技术还未诞生的时候是如何解决的?数据库
也就是总体的演进过程,历史脉络。小程序
好比为什么须要HTTP?HTTP0.9为什么须要演进到HTTP1.0?进而又向1.一、2演进到最新要将Google开发的基于UDP的QUIC协议应用到HTTP3中。后端
搞懂这些前因后果相信你不只仅对HTTP会有更深层次的理解,对网络也会有更加深入的认识。固然也不是说同样东西一来就得全盘理清,有些东西仍是比较复杂的,只是说咱们要往这个方向去学。浏览器
这也是我一直以为很重要的一个学习思想,知其然知其因此然,会让你们更好的理解不少东西。服务器
好了,让咱们回到今天的主题,我们先来看看通常架构的演进过程。网络
为何说通常呢?举个例子,好比某线下龙头企业,如今想开展网上相关业务,那么有大批线下忠实用户的支撑,而且自身钱包鼓鼓,人力财力都不缺。架构
那么线上的软件架构就得考虑清楚了,几乎不可能按照初始阶段来,固然也不能用力过猛,实际得靠架构师以及团队实力进行权衡。负载均衡
什么是单体应用?简单的说就是无论啥功能都往一个应用里写,好比电商系统。用户功能、商品功能、订单功能等等,都往一个应用里写。
在项目初期,小公司人力财力不足,急于拓宽市场,这种单体应用架构简单粗暴,将全部的功能都打包在一个的应用中,直接部署。
本地开发调试方便,直接起一个项目,调试也是在一个进程内,没有冗长跨进程的调用链,出错可快速定位。
本地的函数调用,没有网络调用的开销。
线上出了问题回滚这一个应用便可(这一点其实在某种程度上看是优势,某种程度上看是缺点)。
总结的说就是开发、测试、部署方便,本地调用对于远程调用性能较好。
系统耦合性高,致使开发效率低下。
一开始可能模块结构还很清晰,随着需求日益增加,不断的添加新功能,代码量巨增,模块之间的边界开始模糊,调用关系开始混乱,总体的代码质量很是依赖我的水平。
假使某个同事水平较差,实现的代码冗余,逻辑混乱,这时候要在上面添加新功能或者修改老功能实际上是一件很困难的事情,你不能保证你修改的功能模块不会影响到其余功能。
并且代码会有“破窗效应”(这里其实不只仅是单体架构,对于全部架构来讲都是如此,只是单体应用更大的庞大,业务界限不清晰,所以这种问题更容易被放大)。
有些人看到这就可能会说,这上面还说开发方便,这就又效率低下了?是的,过犹不及。
再好比一个新需求上线例如短信相关的,而且订单也作了一些改造,可是短信功能出了 bug,须要回滚的是整个应用,订单模块冤啊,陪着一块儿回滚。
我在老东家作电商活动,咱们上线一个需求可能涉及六、7个服务,回滚也得所有回滚,并且都是负载均衡的,那机器可能就是上百台了。
语言单一,不能根据场景选择更加合适的语言,例如要实现数据分析,应用的语言是 Java,那么就不能利用到 Python 丰富的类库。
系统的总体可靠性不高,什么意思呢?仍是拿短信功能说事,新上的短信功能写的有 bug,无论是堆栈溢出仍是死循环等等,核心的订单等功能都会受到影响。所以你上线的功能有问题影响的不只仅是这个功能模块,多是总体系统的瘫痪。
系统不易于扩展部署,假设你发现大家的商品查询的流量特别大,顶不住就得加机器。由于是单体应用因此为了商品查询这一个功能,你须要在新加的机器上部署这一个应用,无法单独为这一个功能作定制化部署,对硬件资源有必定的浪费。
总结的说缺点就是随着需求不断增加,代码结构日益复杂,各功能掺杂在一块儿,系统耦合性高,模块之间边界维护很是依赖开发者的我的水平。
模块之间常常会有公共功能难以划分清楚,添加或修改功能困难,不肯定是否会影响到其余模块,全部功能都在一个进程内,某个功能出问题可能影响的就是整个应用,并且没法根据特色场景选择更加合适的语言去实现功能,技术单一。
随着用户的增加,没法作到热点功能单独扩展,只能总体应用部署。
至此咱们已经明白了单体应用架构的优缺点,能够看出初始阶段单体应用优势突出,随着需求和用户的增加渐渐的单体应用顶不住,缺点在不断的放大。
也就是说你的产品须要发展到必定的阶段,单体应用才会顶不住。在这以前单体应用是你的最佳选择。
你要是说个人产品确定顶的,因此一开始就大刀阔斧的设计,单体应用太 low 坚定不用。
能够的,秀出你的花样,你有你的 Young。
咱们再来看下单体应用通常的架构图,注意单体应用不是真的就线上部署一个,好歹得两台,互相 backup 下,不能太虎一台顶。
又过了一段时间,你发现大家还须要开发手机版。因而大家的架构又变成下图所示的样子。
没错,为了让每一个端不会相互影响,粗暴的拷贝现有的应用,稍加修改便可为手机版和小程序提供服务,你会发现不少功能代码都是重复的。这时候来个需求你改的就是多份代码了。
又过了段时间你已经强烈感觉到单体应用所带来的痛点,这证实你的产品发展的不错,一开始确定会忍,继续忍,终有一天你会一拍桌子!来开个会我们得还债了。
理所固然的你会根据不一样业务拆分出不一样的服务,而且会整理出当前公共的功能变成一个公共服务,每一个服务独立部署,独立运行,代码进行了物理隔离,一个小团队维护一个服务或多个服务。
而且通常而言服务化了,数据库也会拆分出来每一个服务维护本身的数据库,数据库之间的数据经过接口传递,而再也不是直接访问。
此时你的系统变成了下图所示的样子。
那如今解决了单体应用什么问题?
系统的耦合度下降,模块之间的边界清晰,都按业务物理隔离了。
在必定的措施下(下文会提到),系统总体可靠性变高。
技术选型丰富,不一样的服务能够利用不一样的技术或语言实现,例如数据分析服务能够用 Python 实现,一些底层的服务团队说我要用 GO,那就用 GO 呗。
可根据服务扩展部署,商品服务访问量特大,那咱们就单单给商品服务扩容,增长机器,其余服务照旧。
这就是微服务了。
好像微服务架构解决了单体应用的全部痛点啊?别急上面只是微服务的一部分,真正的微服务架构还须要包含不少东西,微服务是解决的单体应用的痛点,可是也引入了新的痛点!
服务化了以后上线某个需求,若是是单个服务内的不影响其它服务的你会感到很舒服,若是这个改动是接口层面的改动,涉及到多个服务,你就会以为有点难受了。
上线以前须要定制好服务上线的顺序,定制好每一个服务的回滚计划,涉及到每一个团队之间的合做,上线再也不是一个简单的打包、部署的过程。
出了问题也不是一个简单回滚的过程,而多是各个团队分别回滚各自的服务。若是你本身的服务出了问题你会很焦虑,别的团队都等着。若是别的团队出了问题你也焦虑,怎么还没好啊。
你还会发现本地开发若是依赖别的服务会异常的难受,特别是你依赖的服务还依赖别人的服务,调试、测试将变的复杂。
并且你会发现调用链路变长,调用增长了网络的开销,性能变差。并且出错难以定位问题来源。所以你须要引入分布式链路追踪服务来定位问题。
还须要引入ELK来方便日志的查看,分析问题。
为了可以动态扩容,你的服务须要自动注册且能被自动发现,所以须要个注册中心。
网络之间的调用较为不可靠,所以还须要让调用有重试机制,防止其余服务出 bug 或其余缘由疯狂调用你的服务,还须要有限流措施。为了防止一个服务挂了致使总体的雪崩须要有熔断措施。
为了在特殊时候例如大促的时候让出硬件资源给核心功能,还须要有降级策略。
上面说的重试、限流、熔断、降级就是上文提到的必定措施下,可靠性变高。
并且每一个服务都须要配置,所以还得有个配置中心,来作统一管理。
服务太多了,调用关系复杂为了对调用者更加的友好,而且还须要对调用进行权限等控制,所以须要有个网关,对外暴露统一的接口,固然想限流什么的能够在网关实现。
固然总体的监控是必不可少的,对全部的服务都须要作到全面的监控。
其余的还有啥DevOps、容器等等。
能够看到服务化以后须要引入太多太多的东西,有人可能说你这也就才几个服务啊,我上面的服务其实能够再细分。
例如商品的修改和写入动做相比较于商品的浏览访问量确定少不少,那我就将商品的浏览再剥离出来单独作一个服务,这样便于扩容。
这用户量上来,访问量增长这样的服务剥离你会发现愈来愈多,服务的数量到时候就上来了,并且需求也会不断增长,推荐服务啊、搜索服务啊等等不少不少,只是为了简便都没列出来。
上面提到的那些服务于微服务的组件也得部署,也得保证可靠性...你看这系统就愈来愈复杂了,因此服务化以后解耦了业务,却又融入了非业务相关的东西。
不过服务化实际上是一个天然的结果,就像咱们平时去的办事大厅会根据服务类别划分红不一样的服务窗口,为了办一件事情我能可能须要在各个窗口之间来回走动,这对应的不就是调用链路长嘛?走动的耗时等于咱们调用的网络开销。
因此说微服务架构是发展到一个阶段天然而然的演进产物,早在微服务这个概念被提出以前,不少公司就已是这样干的了。
我上面提到的实际上是微服务1.0架构,而微服务2.0就是为了将非业务功能剥离出来而提出的,将服务治理的功能放在 SideCar 即边车上,使得开发者专一于应用业务的开发,进而演进出 Service
Mesh 即服务网格架构。
谈到微服务你会发现 SOA 这个名词常常伴随着出现。
关于SOA和微服务我查阅了不少资料,不过对于这两个名词的解释都各执一词,没有一个统一的答案。今天我就说说个人理解,抛砖引玉,有纰漏之处,敬请指正。
SOA,全称 Service-Oriented Architecture即面向服务的架构。说到SOA就离不开 ESB,全称Enterprise Service Bus。SOA和微服务同样都是面向服务的。
能够看到 SOA 架构经过企业服务总线进行交互,也就是说中心化,须要按照总线的标准进行开发改造,而微服务是去中心化的。
其实咱们能够抓到关键字企业,SOA 我认为是企业级别的面向服务概念,而微服务是应用级别的概念。
两种都是面向服务,只是 SOA 注重的是企业资源的重复利用,把企业的各个应用经过 ESB 进行整合。
而微服务注重的是应用级别的服务划分,使得应用内服务边界清晰,易扩展。
这二者实际上是两个方向的面向服务,互不冲突。还能是包容的结构,以下图所示
分布式能够认为是经过网络链接多个组件而造成的系统。
广义上说先后分离的应用就能算分布式,前端的 js 代码在浏览器跑着,后端的代码在服务器跑着,两种不一样的组件协力对外提供服务构成分布式。
而咱们常提到的分布式是狭义上的,指代不一样的组件经过协做构成的系统。
而集群常指的同一个组件多实例而构成逻辑上的总体。
这两个概念不冲突,分布式系统里面能够包含集群,像咱们的商品服务就能够是集群部署。
今天主要简述了下架构的演进,单体应用的优缺点以及微服务的优缺点。
再谈了谈SOA 和微服务之间的区别,以及分布式和集群的区别。
说了这么多,也不知道有没有说清楚,我的能力有限,若是有纰漏,敬请指正,分布式事务也在疯狂爆肝中。
我是敖丙,你知道的越多,你不知道的越多,咱们下期见!