高并发系统设计:为什么要做服务化拆分

为什么要做服务化拆分

一体化架构的痛点

在这里插入图片描述

所谓“一体化架构”就是说所有的功能模块,都被打包到一个web工程中,然后部署到应用服务器上。这种架构的优点如下:

  • 开发简单直接,代码和项目集中式管理
  • 只需要维护一个工程,节省维护系统运行的人力成本
  • 排查问题的时候,只需要排查这个应用进程就可以了,目标性强

但是随着系统规模变大,以缺陷会慢慢体现处理,比如:

  • 在技术层面上,数据库连接数可能成为系统的瓶颈
    • 数据库连接是一种比较重的资源,不仅连接过程比较耗时,而且连接MySQL的客户端数量有限制,最多可以设置为16384(在实际的项目中,可以依据实际业务来调整)。
    • 这个数字看着很大,但是因为系统是一体化架构,在部署结构上没有分层,应用服务器直接连接数据库,那么当前端请求量增加,部署的应用服务器扩容,数据库的连接数也会大增。
    • 举个例子,有个系统,其数据库最大连接数设置为8000,应用服务器部署在虚拟机上,数量大概是50个,每个服务器会和数据库建立30个连接,但是数据库的连接数,却远远大于30 * 50 = 1500。
    • 因为你不仅要支撑来自客户端的外网流量,还要部署单独的应用服务器,支撑来自其他部门的内网调用,也要部署队列处理器,处理来自消息队列的消息。
    • 所以,一旦遇到一些大型的运营推广活动,服务器就要扩容,数据库连接数也会随之增加,就会处于最大连接数的边缘。这随时会影响服务的文档
  • 一体化架构增加了研发的成本,抑制了研发效率的提升。
    • 当小团队共同维护一套代码,和一个系统时,在配合时就会出现问题。
    • 由于代码部署在一起,每个人都向同一个代码库提交代码,代码冲突无法避免;同时,功能之间耦合严重,可能你只是更改了很小的逻辑,却导致其它功能不可用,从而在测试时需要对整体功能回归,延长了交付时间。
    • 一体化架构,就像是一个大的蜘蛛网,不同功能模块,错综复杂地交织在一起,方法之间调用关系非常的复杂,导致你修复了一个 Bug,可能会引起另外多个 Bug,整体的维护成本非常高。同时,数据库较弱的扩展性,也限制了服务的扩展能力
  • 一体化架构对于系统的运维也会有很大的影响
    • 在项目初期,你的代码可能只有几千行,构建一次只需要一分钟,那么你可以很敏捷灵活地频繁上线变更修复问题。但是当你的系统扩充到几十万行,甚至上百万行代码的时候,一次构建的过程,包括编译、单元测试、打包和上传到正式环境,花费的时间可能达到十几分钟,并且,任何小的修改,都需要构建整个项目,上线变更的过程非常不灵活。

而我说的这些问题,都可以通过微服务化拆分来解决。

如何使用微服务化解决这些痛点

比如说有一个系统,采用的是一体化架构,数据库也做了垂直拆分,分出了用户库、内容库和互动库,并且已经将工程拆分了业务池,拆分成了用户池、内容池和互动池。

问题:当前端的请求量越来越大时,无论哪个业务池子,用户模块都是请求量最大的模块,用户库也是请求量最大的数据库。因为无论是内容还是互动,都会查询用户库获取用户数据。也就是说,即使我们做了业务池的拆分,但实际上,每一个业务池子都需要连接用户库,并且请求量很大,这就造成了用户库的连接数比其他都要多一些,容易成为系统的瓶颈。

在这里插入图片描述
那我们应该怎么解决这个问题呢?

  • 可以把用户相关的逻辑,部署成一个单独的服务,其他无论是用户池、内容池还是互动池,都连接这个服务来获取和更改用户信息。也就是说,只有这个服务可以连接用户库,其他的业务池都不直连用户库获取数据。
  • 由于这个服务只处理和用户相关的逻辑,所以,不需要部署太多的例子就可以承担流量,这样就可以有效的控制用户库的连接数,提升了系统的可扩展性。那么这样一来,我们也可以将内容和东湖相关的逻辑,都处理出来,形成内容服务和互动服务。这样,我们就通过按照业务做横向拆分的方式,解决了数据库层面的扩展性问题。

在这里插入图片描述

微服务化后,系统架构要如何改造

在这里插入图片描述
在这个架构中,我们将订单、用户、商品相关的逻辑,抽取成服务独立的部署,原本的web工程和队列处理程序,将不再直接依赖缓存和数据库,而是通过调用服务接口,查询存储中的信息。

也就是说做了服务拆分。但是具体应该怎样拆分呢?比如:

  • 服务拆分时要遵循哪些原则?
  • 服务的边界如何确定?服务的粒度是怎么样的呢?
  • 在服务化之后,会遇到哪些问题呢?我们又将如何来解决?

所谓拆分,就是将一个大工程,拆分到若干个子工程,再将这些子工程,通过一些通信方式组装起来。

在这里插入图片描述

微服务拆分的原则

  • 做到单一服务内部功能的高内聚,和低耦合:也就是说,每个服务只完成自己职责之内的任务,对于不是自己职责的功能,交给其它服务来完成
    • 有用户服务和内容服务,用户信息中有“是否为认证用户”字段。
    • 但是内容服务里有这么一段逻辑:如果用户认证字段等于 1,代表是认证用户,那么就把内容权重提升。
    • 问题是,判断用户是否为认证用户的逻辑,应该内聚在用户服务内部,而不应该由内容服务判断,否则认证的逻辑一旦变更,内容服务也需要一同跟着变更,这就不满足高内聚、低耦合的要求了。
  • 关注服务拆分的粒度,先粗略拆分,然后逐渐细化
    • 比如说,对于一个社区系统来说,你可以先把和用户关系相关的业务逻辑,都拆分到用户关系服务中,之后,再把比如黑名单的逻辑独立成黑名单服务。
  • 拆分的过程,要尽量避免影响产品的日常功能迭代。也就是说,要一边做产品功能迭代,一边完成服务器拆分。即,我们的拆分只能在现有一体化系统的基础上,不断剥离业务独立部署。剥离的顺序,可以如下:
    • 优先剥离比较独立的边界服务(比如短信服务、地理位置服务),从非核心的服务出发,减少拆分对现有业务的影响
    • 当两个服务存在依赖关系时,优先拆分被依赖的服务
      • 比方说,内容服务依赖于用户服务获取用户的基本信息,那么如果先把内容服务拆分出来,内容服务就会依赖于一体化架构中的用户模块,这样还是无法保证内容服务的快速部署能力
      • 所以正确的做法是,你要理清服务之间的调用关系,比如说,内容服务会依赖用户服务获取用户信息,互动服务会依赖内容服务,所以要按照先用户服务,再内容服务,最后互动服务的顺序来进行拆分。
  • 服务接口的定义要具备可扩展性
    • 服务拆分之后,由于服务是以独立进程的方式部署,所以服务之间的通信,就不再是进程内部的方法调用,而是跨进程的网络通信了。在这种通信模式下需要注意,服务接口的定义要具备可扩展性,否则在服务变更时,会造成意想不到的错误。
    • 比如,服务接口的参数类型最好是封装类,这样如果增加参数,就不必变更参数的签名,只需要在类中添加字段就可以了

微服务化带来的问题和解决思路

那么,依据这些原则,将系统做微服务拆分之后,是不是就可以一劳永逸,解决所有问题了呢?当然不是。

微服务化只是一种架构手段,有效拆分后,可以帮助实现服务的敏捷开发和部署。但是,由于将原本一体化架构的应用,拆分成了,多个通过网络通信的分布式服务,为了在分布式环境下,协调多个服务正常运行,就必然引入一定的复杂度,这些复杂度主要体现在以下这几个方面。

(1)服务接口的调用,不再是同一进程内的方法调用,而是跨进程的网络调用,这会增加接口响应时间

  • 此时,我们就要选择高效的服务调用框架,同时,接口调用方需要知道服务部署在哪些机器的哪个端口上,这些信息需要存储在一个分布式一致性的存储中,于是就需要引入服务注册中心
  • 注册中心管理的是服务完整的生命周期,包括对于服务存活状态的检测

(2)多个服务之间有着错综复杂的依赖关系

  • 一个服务会依赖多个其他服务,也会被多个服务所依赖,那么一旦被依赖的服务的性能出现问题,产生大量的慢请求,就会导致依赖服务的工作线程池中的线程被占满,那么依赖的服务也会出现性能问题。接下来,问题会沿着依赖网,逐步向上蔓延,直到整个系统出现故障为止。

  • 为了避免这种情况的发生,我们需要引入服务治理体系,针对出问题的服务,采用熔断、降级、限流、超时控制的方法,使得问题被限制在单一服务中,保护服务网络中的其他服务不受影响。

(3)服务拆分到多个进程后,一条请求的调用链路上,涉及多个服务,

  • 因此,一旦这个请求的响应时间增长,或者是出现错误,我们就很难知道,是哪一个服务出现的问题。
  • 另外,整体系统一旦出现故障,很可能外在的表现就是所有服务在同一时间都出现了问题,问题定位时很难确认哪一个服务是源头。这就需要引入分布式追踪工具,以及更细致的服务端监控报表
  • 监控报表关注的是,依赖服务和资源的宏观性能表现;分布式追踪关注的是,单一慢请求中的性能瓶颈分析,两者需要结合起来才能排查出问题

总的来说,微服务化是一个很大的话题,在微服务开发和维护时,你也许会在很短时间就把微服务拆分完成,但是你可能会花相当长的时间来完善服务治理体系

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值