加入收藏 | 设为首页 | 会员中心 | 我要投稿 辽源站长网 (https://www.0437zz.com/)- 云专线、云连接、智能数据、边缘计算、数据安全!
当前位置: 首页 > 教程 > 正文

踩坑实践:如何消除微服务架构中的系统耦合

发布时间:2018-09-05 21:14:13 所属栏目:教程 来源:沈剑
导读:【资讯】微服务架构实施后,不少通用数据访问会拆分成服务,通用业务也会拆分成服务,站点与服务之间的依赖关系会变得复杂,服务与服务之间的调用关系也会变得复杂。 如果水平拆分/垂直拆分得不合理,系统之间会严重耦合,如何消除微服务架构中的系统耦合?
副标题[/!--empirenews.page--]

  【资讯】微服务架构实施后,不少通用数据访问会拆分成服务,通用业务也会拆分成服务,站点与服务之间的依赖关系会变得复杂,服务与服务之间的调用关系也会变得复杂。

  踩坑实践:如何消除微服务架构中的系统耦合

  如果水平拆分/垂直拆分得不合理,系统之间会严重耦合,如何消除微服务架构中的系统耦合?

  2018 年 5 月 18 - 19 日,由 51CTO 主办的全球软件与运维技术峰会在北京召开。

  在“微服务架构设计”分会场,58 速运 CTO 沈剑带来了《58 速运微服务架构解耦最佳实践》的主题分享。

  本文将按照如下几个方面来展开分享:

  微服务之前,系统中存在的耦合问题

  微服务架构,存在什么问题?

  58 速运的微服务实践

  总结

  踩坑实践:如何消除微服务架构中的系统耦合

  相对于 58 同城,58 速运属于一家初创型公司。在早期,我们使用的是简单的三层架构:

  最上游是端,包括 PC、H5 和 App。

  中间是 Web 应用。

  下面是数据存储。

  这样的架构能够适应 58 速运早期“抢时间”这一特点的快速发展模式,同时也能够支撑产品的快速迭代。

  比如 58 速运能够在接到请求之后的 5 分钟内开车过来,将您的一个家具搬到某处。

  在业务上,我们与滴滴的相同之处是:“同城、短途、及时性”;而区别则是:滴滴“带人”、我们“拉货”。

  我们当前的业务主要分为三大块:

  2 C,如:帮助大家搬家,不过客频次比较低,不属于我们主要的订单来源。

  2 小 B,如:帮助卖五金、建材、卫浴等小商户每天把货物送到客户家里,所以频次比较高。

  2 大 B,如:帮助 OFO 之类的企业客户每天将共享单车从仓库里运到各个地点。

  所以总体来说,我们采用的是一般创业型公司最常见的架构,并将业务垂直地切分为三块。

  包括:搬家的站点(Web);为小 B 叫“货的”的站点;为大 B“优配”的站点。在最底下则是统一的数据库存储。

  随着业务的持续发展,数据量的慢慢上升,我们在之后的两、三年碰到了耦合的问题。

  俗话说:历史总是惊人的相似,大家可以结合我下面的介绍,看看是否也遇到过此类问题?

  微服务之前,系统中存在的耦合问题

  为啥代码会 Copy 来 Copy 去?

  踩坑实践:如何消除微服务架构中的系统耦合

  最早期我们并没有小 B 类和大 B 类,而只有一个“货的”的系统和站点。所有用户都是统一的,并未做任何类型上的垂直切分,全部的请求也都通过“货的”的数据访问层,去访问底层数据。

  接着,我们发现 C 类的客频次比较低,因此逐渐增加了“货的”业务、“优配”业务、“货的”的站点、“货的”的数据访问、“优配”的站点、“优配”的数据访问等。

  可见,业务就这么一块、一块长出来了。但是代码可不是真正一行、一行写出来的。

  在早期组织架构中,我们只有 5 个人负责“货的”的前端、后端,直至运维的全部。

  后来我们增加了 3 个人负责“优配”业务,又增加了 10 个人从事“货的”业务。

  可见,早期为了提高效率,几个人就这么粗犷地把研发到测试全干了。而后期就算有业务的新增,我们同样需要用到之前业务中对于用户数据的“增、删、查、改”。

  而此时,我们的团队并不会从头将代码重写一遍,而是从同事那里将以前现成的代码复制、粘贴过来,再结合自己的业务特性稍作修改,并保持大部分代码的一致。

  众所周知,代码复制会存在许多潜在的问题。因此在同一个模块、以及同一个工程里,我们不允许通过复制、粘贴而产生重复代码的函数;而在跨工程、跨业务、跨系统时,代码复制同样是被禁止的。

  因为,如果原来的那套代码出现了问题,或是在用户数据表需要升级的时候,我们会面临许多地方需要修改的痛点。这正是跨系统、跨业务所带来的耦合问题。

  踩坑实践:如何消除微服务架构中的系统耦合

  从架构层面来说,通过对服务层进行抽象,能够缓解由于业务日趋复杂和重复代码的日益增多所带来的各种隐患。

  因此,我们将用于访问“搬家”、“货的”、“优配”的用户数据的那部分代码抽象出来,变成一个通用的 user-service。

  就像调用本地函数那样,业务方通过一行代码,传递一个 UID 过去,以获得 UID 的实例。

  而具体如何拼装 SQL 语句,则被 DAO 层放到了 user-service 的微服务中,从而向上游屏蔽了底层的 SQL 拼装过程。

  在抽象 Service 的过程中,我们所遵循的原则是:公共的部分下沉,而个性化的部分则由每个业务线来承担。

  我们籍此减少了由于代码的反复拷贝所导致的耦合问题。可见,微服务是一种对于创业性公司业务增长的潜在解决方案。

  为啥总是被迫联动升级?

  踩坑实践:如何消除微服务架构中的系统耦合

  随着我们数据量和访问量的上涨,系统的不同部分难免会出现不同的问题,最明显的就是:读取吞吐量的增大。

  对于创业性公司的绝大部分业务场景来说,最先出现的都是由于读多写少所带来的数据库瓶颈问题。

  所以一般来说我们不用去修改代码,而直接将数据库做出集群,以主从同步、和从多个服务器上读取数据的方式来提升读的性能。

  同时我们也可以增加缓存,以降低数据库和磁盘 I/O 的压力。这都是常见的优化手段。

  在增加了缓存之后,你会发现读取数据的流程和访问数据的代码也会相继发生了变化。

  即:从直接访问数据库变成了先访问缓存,如果在缓存里命中、则直接返回;如果未命中、再访问读库、将数据取出后放入缓存中。

  与此同时,数据的写入也会发生类似的变化。即:从直接操作写入数据库变成了需要考虑缓存的一致性,你必须得把缓存淘汰掉,才能修改数据库内容。

  由于速运有着多块垂直的业务和不同的用户分类,因此引入缓存的复杂性会扩散到整个业务线上。

  例如:由于用户的访问量巨大,我们增加了缓存,那么各个产品系统,包括“搬家”、“货的”、“优配”等流程就需要做相应的升级。

  而其中“优配”的负责人会觉得:“是因为底层的复杂性扩散到我这里,我是被迫进行技术改进和升级的。”

  那么随着数据量的增大,我们通过综合运用上述方法,采取了水平切分的方式来优化整体架构的性能。

  例如:我们会将单个用户库或用户表转化为多个实例、多个库、多个表,以降低单实例、单库、单表的数据量,从而提升整体的容量。这也是互联网架构中十分常见的技术优化手段。

  在过去单库的模式下,你只需要将 SQL 语句发往该数据库便可;而变成多个库之后,则会涉及到集函数、求最大/最小、Join 等方面。

  由于数据库被水平切分,业务侧的代码需要做相应的改动。而当你有多个上游的时候,你会发现底层的复杂性会迅速扩散到所有的上游业务方那里。

  上述提到的上游业务方所必须关注的缓存复杂性和切分复杂性,只是两个最典型的例子。

  我们 58 同城还曾出现过:底层的存储引擎由 MySQL 变更为 MongoDB 的情况。

(编辑:辽源站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读