高并发系统架构设计之微服务篇19: 微服务拆分

article/2025/10/2 23:05:03

文章目录

    • 引言
    • 一、一体化架构的痛点
      • 1. 技术层面数据库连接数成为系统瓶颈
      • 2. 一体化架构增加了研发的成本,抑制了研发效率
      • 3. 一体化架构对于系统的运维也会有很大的影响。
    • 二、如何解决这些痛点
    • 小结


引言

通过前面几个篇章的内容,你已经从数据库、缓存和消息队列的角度对自己的垂直电商系统在性能、可用性和扩展性上做了优化。现在,你的系统运行稳定,好评不断,每天高峰期的流量,已经达到了 10000/s 请求,DAU 也涨到了几十万。CEO 非常高兴,打算继续完善产品功能,以便进行新一轮的运营推广,争取在下个双十一可以将 DAU 冲击过百万。

在这里插入图片描述

目前来看,工程的部署方式还是采用一体化架构,也就是说所有的功能模块,比方说电商系统中的订单模块、用户模块、支付模块、物流模块等等,都被打包到一个大的 Web 工程中,然后部署在应用服务器上。

你隐约觉得这样的部署方式可能存在问题,于是,你 Google 了一下,发现当系统发展到一定阶段,都要做微服务化的拆分,你也看到淘宝的“五彩石”项目,对于淘宝整体架构的扩展性,带来的巨大影响。这一切让你心驰神往。但是有一个问题一直萦绕在你的心里:究竟是什么促使我们将一体化架构,拆分成微服务化架构?是不是说系统的整体 QPS 到了 1 万,或者到了 2 万,就一定要做微服务化拆分呢?

一、一体化架构的痛点

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

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

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

1. 技术层面数据库连接数成为系统瓶颈

数据库的连接是比较重的一类资源,不仅连接过程比较耗时,而且连接 MySQL 的客户端数量有限制,最多可以设置为 16384(在实际的项目中,可以依据实际业务来调整)。这个数字看着很大,但是因为你的系统是按照一体化架构部署的,在部署结构上没有分层,应用服务器直接连接数据库,那么当前端请求量增加,部署的应用服务器扩容,数据库的连接数也会大增,给你举个例子。

我之前维护的一个系统中,数据库的最大连接数设置为 8000,应用服务器部署在虚拟机上,数量大概是 50 个,每个服务器会和数据库建立 30 个连接,但是数据库的连接数,却远远大于 30 * 50 = 1500。因为你不仅要支撑来自客户端的外网流量,还要部署单独的应用服务,支撑来自其它部门的内网调用,也要部署队列处理机,处理来自消息队列的消息,这些服务也都是与数据库直接连接的,林林总总加起来,在高峰期的时候,数据库的连接数要接近 3400。所以,一旦遇到一些大的运营推广活动,服务器就要扩容,数据库连接数也随之增加,基本上就会处在最大连接数的边缘。这就像一颗定时炸弹,随时都会影响服务的稳定。

2. 一体化架构增加了研发的成本,抑制了研发效率

《人月神话》中曾经提到:一个团队内部沟通成本,和人员数量 n 有关,约等于 n(n-1)/2,也就是说随着团队人员的增加,沟通的成本呈指数级增长,一个 100 人的团队,需要沟通的渠道大概是 100(100-1)/2 = 4950。那么为了减少沟通成本,我们一般会把团队拆分成若干个小团队,每个小团队 5~7 人,负责一部分功能模块的开发和维护。比方说,你的垂直电商系统团队就会被拆分为用户组、订单组、支付组、商品组等等。当如此多的小团队共同维护一套代码,和一个系统时,在配合时就会出现问题。不同的团队之间沟通少,假如一个团队需要一个发送短信的功能,那么有的研发同学会认为最快的方式,不是询问其他团队是否有现成的,而是自己写一套,但是这种想法是不合适的,这样一来就会造成功能服务的重复开发。由于代码部署在一起,每个人都向同一个代码库提交代码,代码冲突无法避免;同时,功能之间耦合严重,可能你只是更改了很小的逻辑,却导致其它功能不可用,从而在测试时需要对整体功能回归,延长了交付时间。模块之间互相依赖,一个小团队中的成员犯了一个错误,就可能会影响到,其它团队维护的服务,对于整体系统稳定性影响很大

3. 一体化架构对于系统的运维也会有很大的影响。

想象一下,在项目初期,你的代码可能只有几千行,构建一次只需要一分钟,那么你可以很敏捷灵活地频繁上线变更修复问题。但是当你的系统扩充到几十万行,甚至上百万行代码的时候,一次构建的过程,包括编译、单元测试、打包和上传到正式环境,花费的时间可能达到十几分钟,并且,任何小的修改,都需要构建整个项目,上线变更的过程非常不灵活。而我说的这些问题,都可以通过微服务化拆分来解决。

二、如何解决这些痛点

之前,我在做一个社区业务的时候,开始采用的架构也是一体化的架构,数据库已经做了垂直分库,分出了用户库、内容库和互动库,并且已经将工程拆分了业务池,拆分成了用户池、内容池和互动池。当前端的请求量越来越大时,我们发现,无论哪个业务池子,用户模块都是请求量最大的模块儿,用户库也是请求量最大的数据库。这很好理解,无论是内容还是互动,都会查询用户库获取用户数据,所以,即使我们做了业务池的拆分,但实际上,每一个业务池子都需要连接用户库,并且请求量都很大,这就造成了用户库的连接数比其它都要多一些,容易成为系统的瓶颈。那么我们怎么解决这个问题呢?

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

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

按照以上两种拆分方式将系统拆分之后,每一个服务的功能内聚,维护人员职责明确,增加了新的功能只需要测试自己的服务就可以了,而一旦服务出了问题,也可以通过服务熔断、降级的方式减少对于其他服务的影响。另外,由于每个服务都只是原有系统的子集,代码行数相比原有系统要小很多,构建速度上也会有比较大的提升。

当然,微服务化之后,原有单一系统被拆分成多个子服务,无论在开发,还是运维上都会引入额外的问题,那么这些问题是什么? 我们将如何解决呢?下一节课,我会带你来了解。

小结

本节我们了解了,实际业务中会基于什么样的考虑,对系统做微服务化拆分,其实,系统的 QPS 并不是决定性的因素。影响的因素,我归纳为以下几点:

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

从中你应该有所感悟:在架构演进的初期和中期,性能、可用性、可扩展性是我们追求的主要目标,高性能和高可用给用户带来更好的使用体验,扩展性可以方便我们支撑更大量级的并发。但是当系统做的越来越大,团队成员越来越多,我们就不得不考虑成本了。这里面的“成本”有着复杂的含义,它不仅代表购买服务器的费用,还包括研发团队,内部的开发成本,沟通成本以及运维成本等等,甚至有些时候,成本会成为架构设计中的决定性因素。

比方说,你做一个直播系统,在架构设计时除了要关注起播速度,还需要关注 CDN 成本;再比如作为团队 Leader,你在日常开发中除了要推进正常的功能需求开发,也要考虑完善工具链建设,提高工程师的研发效率,降低研发成本。这很好理解,如果在一个 100 个人的团队中,你的工具为每个人每天节省了 10 分钟,那么加起来就是接近 17 小时,差不多增加了 2 个人工作时间。而正是基于提升扩展性和降低成本的考虑,我们最终走上了微服务化的道路。


http://chatgpt.dhexx.cn/article/T0p6UoAH.shtml

相关文章

理解分布式系统中的垂直拆分和水平拆分

概念 水平拆分简单字面意思是:水平方向上由一个拆分为多个。垂直拆分简单字面意思是:垂直方向上由一个拆分为多个。 1,垂直拆分 垂直拆分指按照功能进行拆分,秉着“专业的人干专业的事”的原则,把一个复杂的功能拆分…

垂直拆分和水平拆分

概念介绍 垂直拆分   垂直拆分就是要把表按模块划分到不同数据库表中(当然原则还是不破坏第三范式),这种拆分在大型网站的演变过程中是很常见的。当一个网站还在很小的时候,只有小量的人来开发和维护,各模块和表都在…

软件架构设计之系统耦合性拆分

软件架构设计之系统模块的拆分 基本概念功能模块循环依赖问题 模块拆分原则高内聚性低耦合性 模块拆分方式模块拆分示例业务需求业务分析项目原始代码需求重构项目代码重构 总结 基本概念 功能模块拆分: 全面了解业务需求后,以寻找大量内聚性调用确定模块边界为目的,以寻求应用…

浅谈系统拆分

今晚好冷啊,回去的路上,我突然想到一件关于系统拆分的事情。举的例子很极端,仅供参考,不一定有实际的意义 我感觉拆分系统,和拆分代码,本质上是一样的。小到一个方法,大到几个系统,都…

分布式AKF拆分原则

1. 前言 当我们需要分布式系统提供更强的性能时,该怎样扩展系统呢?什么时候该加机器?什么时候该重构代码?扩容时,究竟该选择哈希算法还是最小连接数算法,才能有效提升性能? 在面对 Scalabilit…

记一次业务系统拆分的数据迁移及系统切换事项

一.迁移背景 老系统使用商业化软件,同时包含模块较多,架构无法支撑,维护成本高等考虑,需要根据业务模块拆分多个系统,新系统支持水平扩缩容 ,rcp框架等,新系统基本上包含常用的技术栈&#xff…

拆分盘系统开发

转载于:https://blog.51cto.com/12916096/1925453

微服务拆分之AKF原则

AKF是指可拓展模型,有3个坐标轴,分别是x,y,z 为了更好的诠释AKF原则,下面假定有一个系统 基于x轴拓展: 这种方式只能拓展无状态服务,是通过复制系统应用到其他服务器上,再通过给集群…

拆分系统拆分盘盛出不穷,互助系统的延续走出新的路子,农场果园直销系统返利系统开始火了!

在互联网时代,互助盘已经开始落伍了,时代是在进步,现在出现了新的营销模式拆分盘系统模式。 而且非常受大家欢迎,那么什么是拆分盘系统呢? 打个比方,如果发行100分财富,你购买其中的一份财富。 …

分布式架构之系统拆分

系统拆分是单体程序向分布式系统演变的关键一步,也是很重要的一步,拆分的好坏直接关系到未来系统的扩展性、可维护性和可伸缩性等,拆分工作不难理解,但是如何正确拆分、有什么样的方法和原则能帮助我们拆分得到一个我们理想中的系…

水平拆分

水平拆分 概述水平分库示例水平拆分的优点水平拆分的缺点分片原则 概述 水平拆分指的是通过某种策略将数据分片存储,包含库内分表和分库两种,每片数据会分散到不同的MySQL表或库,达到分布式的效果,能够支持非常大的数据量。前面的…

微服务拆分策略

拆分策略可以按功能和非功能维度进行考虑,功能维度主要是划分清楚业务的边界,非功能维度主要考虑六点包括扩展性、复用性、高性能、高可用、安全性、异构性。接下来详细介绍下。 1、功能维度 功能维度主要是划分清楚业务边界,采用的主要设计…

微服务拆分

如何定义一个微服务架构?通常情况下,定义应用程序架构分三步。但是,世界上并没有一个机械化的流程可以遵守,然后指望这个流程输出一个合理的架构。这里只能介绍一个笼统的方法,现实世界中,这是一个不断迭代…

每日一题:为什么要进行系统拆分?

原文来自 GitHub 开源社区 Doocs,欢迎 Star 此项目,如果你有独到的见解,同样可以参与贡献此项目。 面试题 为什么要进行系统拆分?如何进行系统拆分?拆分后不用 dubbo 可以吗? 面试官心理分析 从这个问题开始…

个人对系统拆分的理解

在本人现在的公司和本人工作过的上一家公司,本人有幸参与并实施了公司业务系统的架构拆分,现将之前的工作总结下。 1,为什么要进行系统拆分 首先我们需要想想,到底什么样的系统需要进行拆分?并不是所有的系统都需要进…

登录+注册界面的实现(代码)

先看效果图&#xff01; 话不多说&#xff0c;直接上代码&#xff01; //布局文件&#xff1a;activity_login.xml <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android&qu…

简单WEB登录页面代码实现

longin.html&#xff1a;登录页面&#xff0c;此处action引用**/**类型的地址&#xff0c;JSP可以用${ pageContext.request.contextPath }/LS <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd&qu…

编写简单的登陆页面

1.简单登录界面&#xff08;自己设置css样式&#xff09; 代码如下 <form id"loginForm" action"#" method"post" novalidate"novalidate"><div class"login_box"><div class"login_box_left"&g…

实现网页登录代码

python 一、前言 本文通过selenium工具实现工作所用网站的自动登录&#xff0c;下图为网站登录界面。 1、运行环境 操作系统&#xff1a;Windows10 python版本&#xff1a;python3.7 2、需要的python第三方库 1、selenium 安装&#xff1a; pip install selenium selen…

【html】【一个简单的用户登录页面代码】

结果 代码 <!DOCTYPE html> <html><head><title>用户登录.html</title><meta http-equiv"keywords" content"keyword1,keyword2,keyword3"><meta http-equiv"description" content"this is my pag…