前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >课程实录丨解密互联网架构设计(2)

课程实录丨解密互联网架构设计(2)

作者头像
博文视点Broadview
发布2020-06-11 14:36:13
2690
发布2020-06-11 14:36:13
举报

本实录是根据“博文视点在线课堂”线上分享内容汇总整理而成 分享嘉宾:李业兵 相关图书:《架构探险:从零开始写分布式服务框架》

面向服务架构,本质上就是将之前的单体应用拆分成多个应用,每个应用之间是通过分布式服务框架或者是一些RPC的框架进行通讯交互,之前提到了服务化提供的三大能力,一个是提供的物理层面对业务分解抽象的能力,第二个是解决了系统的一个水平扩展问题,第三是能够让一家公司具备百人以上的团队进行协作开发的能力,即提高我们的开发效能。

举个例子,这页PPT左边的应用架构图是我们公司最早期的一个系统架构图,整体看来其实也是按照不同的业务领域进行的一个设计,边界也比较清楚,包括进展、支付、风控、限购等等这些模块,你可以认为它就是一个一个领域,按照了领域驱动来进行设计的。但是这么做的缺点有哪些呢?以我自己的实际体验来说,首先这些所有这些业务领域,实现在一个工程里面,实际上是以包结构进行划分的。对于我们开发者来说没什么约束力,在这个业务后续的一些维护和演进当中,一波一波的人来对这个工程进行持续地迭代开发,可能有某个不懂事的开发,他会把促销的代码写在支付模块或者是订单模块当中,是没有办法保证开发质量的,久而久之,整个系统就乱掉了。

再就是我们公司的开发团队有好几个,开发人员应该也上百了,这么多的团队、这么多人来开发同一个工程应用会导致非常多的问题,比如我同时开发好几个需求甚至十多个需求,就会有大量的分支,而这些分支在开发过程中需要进行Merge,Merge就容易导致冲突,这是一件非常耗精力的事情,并且很容易造成这个因为Merge出错而导致的系统故障,简单的来说,就是在团队之间无法进行一个很好的并行协作开发。还有一点就是当我们的系统的流量越来越大的时候,很容易出现系统的性能瓶颈的,为什么这么说呢?因为这个系统里面集合了所有的业务模块,如果其中某一个模块的性能非常差的话,它会拖慢整个系统的性能,因为这些业务模块没有独立部署,它是部署在一块的,部署在一个机器上,其中某一个模块性能差对其他的请求照样会有影响。还有一个很重要的问题,往往这个时候数据库很容易成为性能的瓶颈。在流量高峰的时候,数据库里的连接词很容易被打满,进而造成这个整个系统的不可用,这个后果是非常惨的,所以我们需要面向服务的设计来解救我们。

我们大家可以看一下PPT右边的图,这是我们做了服务化拆分之后的一个应用架构简图,即我们将之前整块的单体应用、单体工程拆分成了多个独立部署的应用,实际上就是将单体的应用拆分成了一个分布式应用,那么如何拆?拆的时候要注意些什么呢?其实还是以领域驱动为指导来划分业务边界,所以它有一个继承性,即面向服务设计实际上也是继承于领域驱动设计,在这个领域驱动设计上再进行一个演进,我们按照业务边界来拆,使得我们的系统和业务来对齐,因为我们的系统是业务的一个直观表达,这样更有利于我们业务服务的复用,因为我们公司的业务是不断向前发展的,拆分之后服务复用的一个好处就是开展新业务的时候可以复用之前的一些部分服务,不用重复建设,可以在已有的服务基础上更快的搭建我们的新服务。对于讯息方面的互联网行业来说,快人一步就是胜利。拆分之后用一句广告语来说就是:腰不酸了,腿不疼了,大家干活都有劲了。确实是这样,比如说负责促销开发的人,在拆分之后只需要开发拆分出来的促销模块,进行独立地发布、独立地部署不会影响其他人,也不受其他人的影响,我更没有办法把代码乱写到其他的模块去,这样就解决了整个团队的协作问题,整个公司的研发能力得到了极大的释放,研发的效率也得到了极大的提高。

再就是如果我发现某个模块的性能比较差,比如说价格计算性能比较差,我可以集中精力优化这个模块,不会影响其他的应用模块,并且我的数据库层面也隔离了,每个应用都有独立的数据库,应用之间通过RPC或者分布式服务框架进行通信,这样也这样就解决了水平扩展问题。

当然面向服务架构也不是十全十美的,它从单体应用变成分布式应用之后,会额外引入很多的复杂性。为了解决这个复杂性,针对性地延伸出了一些设计原则。我大概列举了一些,比如说无单点、无状态、可用为、可监控、可测试、可缓存、短事物、柔性事物、补偿机制、最终一致性、病发控治、服务降级等等,其中每一种都是实践中的经验总结。比如说单点,它会导致整个系统存在一个可用性的风险,因为一旦单点出现问题的时候,往往会导致整个系统不可用,所以为了我们系统的兼容性,我们要努力的避免出现单点。所谓的无单点,用大白话说就是我有多个备份,其中某一个备份挂掉之后,其余的备份可以无缝地接管当前挂掉的备份。所谓无状态,就是为了更方便水平扩展,因为一旦有了状态之后就很难水平扩展了。举个大家都熟悉的例子就是C型,C型其实是有状态的,如果我们在分布式环境下面要用C型的话,往往需要改造成分布式C型。可用为、可监控、可测试、可缓存、短事务,实际上是对做系统的一个通用的要求,是考验一个人的编码能力。柔性事物、补偿机制、最终一致性,是关于事物单体应用变为分布式应用之后,在应用模块之间如果要做事务的话还是比较困难的,因为这个时候本地事务是不生效的,我们解决方案一般是放弃强一致性,采取这种补偿机制来做柔性事物以达到最终的一致性。我举个例子,比如说订单系统,客户下单成功之后要扣减库存,其中扣减库存这个操作是通过RPC远程调用完成的。大家应该都知道RPC调用是通过序列化、反序列化机制,它走的是一个网络的通讯,而网络本身是不稳定的,就有可能出现超时等各种不确定的情况,导致调用失败,而解决办法一般是启用另外一个定时任务来依步地核对订单与库存,使得订单和库存达到最终一致性,除了同步调用之外,还会有一个补偿的定时任务来核对订单和库存。

下面简单介绍一下面向服务设计的技术栈。面向服务设计,因为涉及到分布式这一块,技术站非常多,我这里只是给大家简单地列举了一些,也不会说深入的介绍。主要包括像分布式服务框架、注册中心,一些序列化化、反序列化的知识以及RPC的框架,服务化之后很重要一点就是需要有服务治理,需要有负载均衡、软负载,需要有配置中心、消息中心等等。每一种技术都是一个比较深的主题,大家可以自行研究一下这方面的技术。

同样的也是要问两个问题,就是面向服务设计为我们解决了什么问题?又有哪些问题是它解决不了的?大家也可以自己先想一想这个还这个问题。实际上我认为面向服务设计能够支撑目前绝大多数公司的业务,即使是淘宝、支付宝这样巨无霸的公司,它们的架构本质也是一个属于服务化架构的范畴,没有超出服务化架构,虽然他们有很多一些匀化的东西,但它的也不足之处在于服务化会引入更多的复杂性,之前也有过介绍,因为这些复杂性才会对开发人员与运维人员在架构方面提出了一个更高的要求。

(说个题外话,因为对人的要求更高了,企业也因此为此付出了更多的心血,用更高的薪资才能找到符合要求的人来做服务化,这实际上也是加重了这个企业的成本。所以选择哪一种架构或者哪一种设计方式,其实是根据当前你所在企业业务的实际需要来的,千万不能盲目的去跟风,不能盲目的去选,不能因为某一种架构高大上,然后就一定要选它,肯定会出问题,要与你所在团队的能力相符,要是团队的能力做不了服务化,你如果强行上服务化,很可能会出问题,就是说面向对象单体能解决我这个问题,我坚决不会去搞面向领域的设计,如果面向领域设计能解决这个问题的,我坚决不会去搞服务化。)

最后一个话题是微服务。微服务我个人认为它和服务化并没有本质的区别,我也不知道现在为什么吵得这么火,其实微服务的很多概念、内涵、原则和服务化是一致的,最多算作是服务化的一个深化和延伸。我认为不同的人对微服务有不同的理解,我认为微服务有下面几个特点。它是一个更彻底的组件化、更彻底的服务化,它的服务力度相对于面向服务设计可能会更细一点,与业务的领域边界可能更一致一点,它强调一个服务的自治。

下面介绍一个目前比较流行的构建微服务的技术站,像Spring boot、Spring cloud,或者是通过Rest API来做技术站,这是比较流行的,因为时间关系就不做深入介绍了。最后介绍一下我写的一本书,就是《从零开始写分布式服务框架》,这本书总结了分布式服务框架涉及到的一些技术点,最终实现了一个相对完整的分布式服务框架。当然了,它在可用性方面并没有经过生产环境的一些考验,培训方面也是可能会有问题的,但是大家可以从中来学习构建分布式服务框架方方面面的一些知识。

  • 分布式服务框架最难的是什么呢?

我个人觉得一个好的分布式服务框架,首先它一定是高可用的,就是能够在一个严酷的生产环境下能够抗大流量,有很高的可用性,要做到这一点是非常难的,甚至这是不能够写出来的,是要通过不断地生产实践来慢慢摸索出来的。其次我认为比较重要一点是它的高性能,因为在互联网企业里面性能始终是一个非常重要的主题。服务化之后和单体应用需求分析的差别,我的理解是需求分析侧重点应该是在分析这个方面,需求分析的首要任务是要把一些业务点理顺,实际上还没有到系统设计那一步,我觉得区别应该是不大的。真正区别大的是在系统设计那一步,因为单体应用和分布式应用,在很多方面都是不一样的,比如通信方式、做事务的方式等等,之前也都有过介绍。

  • 做微服务设计的时候如何确定服务的力度

这是一个很好的问题,同时我也觉得这是一个比较难以回答的问题,因为不管是做服务化还是做微服务,对服务力度的拆分,首先是要建立在对这个业务非常了解的基础上,即你要非常清楚你所要拆分的业务其内部模块的边界在哪里,它们各个模块之间的交互与联系有多紧密,实际上这是一种权衡,并没有一个标准的公式在那里,他可以有多种拆法。

关于这个话题再说两句,它并不是只有唯一的拆法,就像您刚才说的价格和促销之间的联系,它们之间肯定是存在着联系的,关键在于它们之间的联系紧不紧密,或者说它们之间有没有一些强依赖,强依赖多不多,如果强依赖非常多,甚至可能需要一些分布式事务才能解决问题的话,这个时候就不建议拆了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-09-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 博文视点Broadview 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档