解答如下:QPS:每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准(即每秒的响应请求数,也即是最大吞吐能力)
QPS = 请求数/秒
案例:一个典型的上班签到系统,早上8点上班,7:50至8:00这10分钟的时间里用户会登录签到系统进行签到。公司员工为6w人,平均每个员上登录签到系统的时长为5分钟。可以用下面的方法计算。
QPS = 60000/(10*60) 事务/秒 = 100 (相当于100/s 请求数量)
拆分微服务的目的**

  • 快速迭代、持续交付
  • 降本增效

其实系统的 QPS 并不是微服务化的决定性因素或者说直接因素。影响的因素我归纳为以下几点:

  • 系统中使用的资源出现扩展性问题,尤其是数据库的连接数出现瓶颈;
  • 大团队共同维护一套代码,带来研发效率的降低和研发成本的提升;
  • 系统部署成本越来越高。

    单体架构存在的局限性

    首先先想下你当初为什么选用了单体架构。在项目刚刚启动的时候,你只是希望能够尽量快地将项目搭建起来,方便将产品更早地投放市场快速完成验证。
    在系统开发的初期,这种架构确实给你的开发运维带来了很大的便捷,主要体现在:

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

但随着功能越来越复杂,开发团队规模越来越大,你慢慢感受到了单体架构的一些缺陷,这主要体现在以下几个方面。

  • 在技术层面上,数据库连接数可能成为系统的瓶颈。
    • 数据库的连接是比较重的一类资源,不仅连接过程比较耗时而且连接 MySQL 的客户端数量有限制,最多可以设置为 16384(在实际的项目中,可以依据实际业务来调整)。
    • 这个数字看着很大,但是因为你的系统是按照单体架构部署的,在部署结构上没有分层,应用服务器直接连接数据库,那么当前端请求量增加,部署的应用服务器扩容,数据库的连接数也会大增。
  • 单体架构增加了研发的成本抑制了研发效率的提升。
    • 一个团队内部沟通成本和人员数量 n 有关,约等于 n(n-1)/2,也就是说随着团队人员的增加,沟通的成本呈指数级增长,一个 100 人的团队需要沟通的渠道大概是 100(100-1)/2 = 4950。为了减少沟通成本,我们一般会把团队拆分成若干个小团队,每个小团队 5~7 人负责一部分功能模块的开发和维护。
    • 比如你的垂直电商系统团队就会被拆分为用户组、订单组、支付组、商品组等等。当如此多的小团队共同维护一套代码和一个系统时,在配合的过程中就会出现问题。
    • 由于代码部署在一起,每个人都向同一个代码库提交代码,代码冲突无法避免;同时功能之间耦合严重,可能你只是更改了很小的逻辑却导致其它功能不可用,从而在测试时需要对整体功能回归,延长了交付时间。模块之间互相依赖,一个小团队中的成员犯了一个错误,就可能会影响到其它团队维护的服务,对于整体系统稳定性影响很大。
  • 单体架构对于系统的运维也会有很大的影响
    • 如在项目初期你的代码可能只有几千行,构建一次只需要一分钟,那么你可以很敏捷灵活地频繁上线变更修复问题。但是当你的系统扩充到几十万行甚至上百万行代码的时候,一次构建的过程包括编译、单元测试、打包和上传到正式环境,花费的时间可能达到十几分钟,并且任何小的修改,都需要构建整个项目,上线变更的过程非常不灵活。

综上所述:我所说的这些问题都可以通过微服务化拆分来解决。

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

之前我在做一个社区业务的时候,开始采用的架构也是单体架构,数据库已经做了垂直分库,分出了用户库、内容库和互动库,并且已经将工程拆分了业务池,拆分成了用户池、内容池和互动池。当前端的请求量越来越大时,我们发现无论哪个业务池子用户模块都是请求量最大的模块儿,用户库也是请求量最大的数据库。这很好理解,无论是内容还是互动都会查询用户库获取用户数据,所以虽然我们做了业务池的拆分,但实际上每一个业务池子都需要连接用户库并且请求量都很大,这就造成了用户库的连接数比其它都要多一些,容易成为系统的瓶颈。
那么我们怎么解决这个问题呢?
其实可以把与用户相关的逻辑部署成一个单独的服务,其它无论是用户池、内容池还是互动池都连接这个服务来获取和更改用户信息,也就是说只有这个服务可以连接用户库,其它的业务池都不直连用户库获取数据。
由于这个服务只处理和用户相关的逻辑,所以不需要部署太多的实例就可以承担流量,这样就可以有效地控制用户库的连接数,提升了系统的可扩展性。那么如此一来,我们也可以将内容和互动相关的逻辑都独立出来,形成内容服务和互动服务,这样我们就通过按照业务做横向拆分的方式解决了数据库层面的扩展性问题。

再比如,我们在做社区业务的时候,会有多个模块需要使用地理位置服务,将 IP 信息或者经纬度信息转换为城市信息。比如推荐内容的时候,可以结合用户的城市信息做附近内容的推荐;展示内容信息的时候也需要展示城市信息等等。
那么如果每一个模块都实现这么一套逻辑就会导致代码不够重用。因此我们可以把将 IP 信息或者经纬度信息转换为城市信息,包装成单独的服务供其它模块调用,也就是我们可以将与业务无关的公用服务抽取出来,下沉成单独的服务。

按照以上两种拆分方式将系统拆分之后,每一个服务的功能内聚,维护人员职责明确,增加了新的功能只需要测试自己的服务就可以了,而一旦服务出了问题,也可以通过服务熔断、降级的方式减少对于其他服务的影响

另外由于每个服务都只是原有系统的子集,代码行数相比原有系统要小很多,构建速度上也会有比较大的提升。**

微服务化之后,原有单一系统被拆分成多个子服务,无论在开发还是运维上都会引入额外的问题,那么这些问题是什么? 我们将如何解决呢?
请听下回继续分解

  1. # 学习感悟
  2. 在架构演进的初期和中期,性能、可用性、可扩展性是我们追求的主要目标,高性能和高可用给用户带来更好的使用体验,扩展性可以方便我们支撑更大
  3. 量级的并发。
  4. 但是当系统做的越来越大,团队成员越来越多,我们就不得不考虑成本了。
  5. `业务情况/人力情况/时间成本/运维能力`
  6. 这里面的“成本”有着复杂的含义,它不仅代表购买服务器的费用,还包括研发团队,内部的开发成本,沟通成本以及运维成本等等,甚至有些时候,成本
  7. 会成为架构设计中的决定性因素。
  8. 比方说,你做一个直播系统,在架构设计时除了要关注起播速度还需要关注 CDN 成本;再比如作为团队 Leader,你在日常开发中除了要推进正常的功能
  9. 需求开发,也要考虑完善工具链建设提高工程师的研发效率,降低研发成本。
  10. 这很好理解,如果在一个 100 个人的团队中,你的工具为每个人每天节省了 10 分钟,那么加起来就是接近 17 小时,差不多增加了 2 个人工作时间。
  11. 而正是基于提升扩展性和降低成本的考虑,我们最终走上了微服务化的道路。

综上所述总结

  1. QPS低于100不适合使用微服务架构
  2. QPS高于100具体看业务场景分析是否使用微服务架构
  3. 考虑维度: 业务复杂度/数据规模大小/人员技术研发能力/时间成本/运维能力
  4. 架构都是各方面折中(Balance)的结果(降本增效)