首页 > 其他分享 >高并发系统设计——系统架构的微服务化选型

高并发系统设计——系统架构的微服务化选型

时间:2023-04-04 13:33:23浏览次数:34  
标签:调用 架构 服务化 系统 选型 拆分 服务


摘要

现在,你的系统运行稳定,好评不断,每天高峰期的流量,已经达到了 10000/s 请求,DAU 也涨到了几十万。CEO 非常高兴,打算继续完善产品功能,以便进行新一轮的运营推广,争取在下个双十一可以将 DAU 冲击过百万。这时,你开始考虑,怎么通过技术上的优化改造,来支撑更高的并发流量,比如支撑过百万的 DAU。于是,你重新审视了自己的系统架构,分析系统中有哪些可以优化的点。

高并发系统设计——系统架构的微服务化选型_连接数

目前来看,工程的部署方式还是采用一体化架构,也就是说所有的功能模块,比方说电商系统中的订单模块、用户模块、支付模块、物流模块等等,都被打包到一个大的 Web 工程中,然后部署在应用服务器上。你隐约觉得这样的部署方式可能存在问题,于是,你 Google 了一下,发现当系统发展到一定阶段,都要做微服务化的拆分,你也看到淘宝的“五彩石”项目,对于淘宝整体架构的扩展性,带来的巨大影响。这一切让你心驰神往。但是有一个问题一直萦绕在你的心里:究竟是什么促使我们将一体化架构,拆分成微服务化架构?是不是说系统的整体 QPS 到了 1 万,或者到了 2 万,就一定要做微服务化拆分呢?

一、一体化架构的技术选型

在系统开发的初期,这种架构确实给你的开发运维,带来了很大的便捷,主要体现在:

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

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

1.1 在技术层面上,数据库连接数可能成为系统的瓶颈。

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

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

1.2 一体化架构增加了研发的成本,抑制了研发效率的提升。

比方说,你的垂直电商系统团队就会被拆分为用户组、订单组、支付组、商品组等等。当如此多的小团队共同维护一套代码,和一个系统时,在配合时就会出现问题。不同的团队之间沟通少,假如一个团队需要一个发送短信的功能,那么有的研发同学会认为最快的方式,不是询问其他团队是否有现成的,而是自己写一套,但是这种想法是不合适的,这样一来就会造成功能服务的重复开发。由于代码部署在一起,每个人都向同一个代码库提交代码,代码冲突无法避免;同时,功能之间耦合严重,可能你只是更改了很小的逻辑,却导致其它功能不可用,从而在测试时需要对整体功能回归,延长了交付时间。模块之间互相依赖,一个小团队中的成员犯了一个错误,就可能会影响到,其它团队维护的服务,对于整体系统稳定性影响很大。

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

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

二、系统架构的微服务化

之前,我在做一个社区业务的时候,开始采用的架构也是一体化的架构,数据库已经做了垂直分库,分出了用户库、内容库和互动库,并且已经将工程拆分了业务池,拆分成了用户池、内容池和互动池。

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

高并发系统设计——系统架构的微服务化选型_系统架构_02

其实,可以把与用户相关的逻辑,部署成一个单独的服务,其它无论是用户池、内容池还是互动池,都连接这个服务来获取和更改用户信息,那么也就是说,只有这个服务可以连接用户库,其它的业务池都不直连用户库获取数据。

由于这个服务只处理和用户相关的逻辑,所以,不需要部署太多的实例就可以承担流量,这样就可以有效地控制用户库的连接数,提升了系统的可扩展性。那么如此一来,我们也可以将内容和互动相关的逻辑,都独立出来,形成内容服务和互动服务,这样,我们就通过按照业务做横向拆分的方式,解决了数据库层面的扩展性问题。

高并发系统设计——系统架构的微服务化选型_微服务_03

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

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

当然,微服务化之后,原有单一系统被拆分成多个子服务,无论在开发,还是运维上都会引入额外的问题,

单体架构向微服务化架构演进的原因,你应该了解到,当系统依赖资源的扩展性出现问题,或者是一体化架构带来的研发成本、部署成本变得难以接受时,我们会考虑对整体系统,做微服务化拆分。微服务化之后,垂直电商系统的架构会将变成下面这样:

高并发系统设计——系统架构的微服务化选型_微服务_04

在这个架构中,我们将用户、订单和商品相关的逻辑,抽取成服务独立的部署,原本的 Web 工程和队列处理程序,将不再直接依赖缓存和数据库,而是通过调用服务接口,查询存储中的信息。有了构思和期望之后,为了将服务化拆分尽快落地,你们决定抽调主力研发同学,共同制定拆分计划。但是细致讨论后发现,虽然对服务拆分有了大致的方向,可还是有很多疑问,比如:

2.1 微服务拆分的原则

之前,你维护的一体化架构,就像是一个大的蜘蛛网,不同功能模块,错综复杂地交织在一起,方法之间调用关系非常的复杂,导致你修复了一个 Bug,可能会引起另外多个 Bug,整体的维护成本非常高。同时,数据库较弱的扩展性,也限制了服务的扩展能力

出于上述考虑,你要对架构做拆分。但拆分并不像听上去那么简单,这其实就是将整体工程,重构甚至重写的过程。你需要将代码,拆分到若干个子工程里面,再将这些子工程,通过一些通信方式组装起来,这对架构是很大的调整,需要跨多个团队协调完成。所以在开始拆分之前,你需要明确几个拆分的原则,否则就会事倍功半,甚至对整体项目产生不利的影响。

2.1.1 原则一:做到单一服务内部功能的高内聚,和低耦合

每个服务只完成自己职责之内的任务,对于不是自己职责的功能,交给其它服务来完成。

2.1.2 原则二:你需要关注服务拆分的粒度,先粗略拆分,再逐渐细化

在服务拆分的初期,你其实很难确定,服务究竟要拆分成什么样。但是,从“微服务”这几个字来看,服务的粒度貌似应该足够小,甚至有“一方法一服务”的说法。不过,服务多了也会带来问题,像是服务个数的增加会增加运维的成本。再比如,原本一次请求只需要调用进程内的多个方法,现在则需要跨网络调用多个 RPC 服务,在性能上肯定会有所下降。

所以我推荐的做法是:拆分初期可以把服务粒度拆的粗一些,后面随着团队对于业务和微服务理解的加深,再考虑把服务粒度细化。比如说,对于一个社区系统来说,你可以先把和用户关系相关的业务逻辑,都拆分到用户关系服务中,之后,再把比如黑名单的逻辑独立成黑名单服务。

2.1.3 原则三:拆分的过程,要尽量避免影响产品的日常功能迭代

也就是说,要一边做产品功能迭代,一边完成服务化拆分。在竞品对手快速发展的时期做了服务的拆分,拆分的方式是停掉所有业务开发,全盘推翻重构,结果错失了产品发展的最佳机会,最终败给了竞争对手。因此,我们的拆分只能在现有一体化系统的基础上,不断剥离业务独立部署,剥离的顺序,你可以参考以下几点:

  • 1. 优先剥离比较独立的边界服务(比如短信服务、地理位置服务),从非核心的服务出发,减少拆分对现有业务的影响,也给团队一个练习、试错的机会;
  • 2. 当两个服务存在依赖关系时,优先拆分被依赖的服务。比方说,内容服务依赖于用户服务获取用户的基本信息,那么如果先把内容服务拆分出来,内容服务就会依赖于一体化架构中的用户模块,这样还是无法保证内容服务的快速部署能力。

所以正确的做法是,你要理清服务之间的调用关系,比如说,内容服务会依赖用户服务获取用户信息,互动服务会依赖内容服务,所以要按照先用户服务,再内容服务,最后互动服务的顺序来进行拆分。

2.1.4 原则四:服务接口的定义要具备可扩展性

服务拆分之后,由于服务是以独立进程的方式部署,所以服务之间通信,就不再是进程内部的方法调用,而是跨进程的网络通信了。在这种通信模型下需要注意,服务接口的定义要具备可扩展性,否则在服务变更时,会造成意想不到的错误。某一个微服务的接口有三个参数,在一次业务需求开发中,组内的一个同学将这个接口的参数调整为了四个,接口被调用的地方也做了修改,结果上线这个服务后,却不断报错,无奈只能回滚。想必你明白了,这是因为这个接口先上线后,参数变更成了四个,但是调用方还未变更,还是在调用三个参数的接口,那就肯定会报错了。所以,服务接口的参数类型最好是封装类,这样如果增加参数,就不必变更接口的签名,而只需要在类中添加字段即就可以了。

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

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

1. 服务接口的调用,不再是同一进程内的方法调用,而是跨进程的网络调用,这会增加接口响应时间的增加。此时,我们就要选择高效的服务调用框架,同时,接口调用方需要知道服务部署在哪些机器的哪个端口上,这些信息需要存储在一个分布式一致性的存储中,于是就需要引入服务注册中心,注册中心管理的是服务完整的生命周期,包括对于服务存活状态的检测。

2. 多个服务之间有着错综复杂的依赖关系。一个服务会依赖多个其它服务,也会被多个服务所依赖,那么一旦被依赖的服务的性能出现问题,产生大量的慢请求,就会导致依赖服务的工作线程池中的线程被占满,那么依赖的服务也会出现性能问题。接下来,问题就会沿着依赖网,逐步向上蔓延,直到整个系统出现故障为止。为了避免这种情况的发生,我们需要引入服务治理体系,针对出问题的服务,采用熔断、降级、限流、超时控制的方法,使得问题被限制在单一服务中,保护服务网络中的其它服务不受影响。

3. 服务拆分到多个进程后,一条请求的调用链路上,涉及多个服务,那么一旦这个请求的响应时间增长,或者是出现错误,我们就很难知道,是哪一个服务出现的问题。另外,整体系统一旦出现故障,很可能外在的表现是所有服务在同一时间都出现了问题,你在问题定位时,很难确认哪一个服务是源头,这就需要引入分布式追踪工具,以及更细致的服务端监控报表。

博文参考

标签:调用,架构,服务化,系统,选型,拆分,服务
From: https://blog.51cto.com/u_13643065/6168610

相关文章

  • 高并发系统设计——RPC框架的技术选型
    摘要服务拆分单独部署后,引入的服务跨网络通信的问题;在拆分成多个小服务之后,服务如何治理的问题。如果想要解决这两方面问题,你需要了解,微服务化所需要的中间件的基本原理,和使用技巧,那么本节课,我会带你掌握,解决第一点问题的核心组件:RPC框架。你的垂直电商系统的QPS已经达到了每秒......
  • 高并发系统设计——数据库技术选型
    摘要我们用池化技术解决了数据库连接复用的问题,这时,你的垂直电商系统虽然整体架构上没有变化,但是和数据库交互的过程有了变化,在你的Web工程和数据库之间增加了数据库连接池,减少了频繁创建连接的成本,从上节课的测试来看性能上可以提升80%。现在的架构图如下所示:此时,你的数据库还......
  • 高并发系统设计——“三高”解决方案
    摘要提到互联网系统设计,你可能听到最多的词儿就是“三高”,也就是“高并发”“高性能”“高可用”,它们是互联网系统架构设计永恒的主题。在前两节课中,我带你了解了高并发系统设计的含义,意义以及分层设计原则,接下来,我想带你整体了解一下高并发系统设计的目标,然后在此基础上,进入我们今......
  • Taro、uni-app、Mpx选型对比
    选型对比框架技术栈案例微信小程序支付宝小程序百度小程序头条小程序H5AppTaroReact丰富√√√√√√uni-appVue丰富√√√√√√MpxVue少√√√√××社区生态taro官方发布了taro-ui库,awesome里三方组件不太多。uni-app官方发布了uni-ui库,还有个插件市场,里面轮子很多。mpx提供了完......
  • 内蒙古互联网医院牌照代办|互联网医院管理系统开发的好处
     内蒙古互联网医院牌照代办|互联网医院管理系统开发的好处?互联网医院一直是现在的热门行业,很多的医院已经开发了互联网医院,并且已经在良好的运行中,而有一些医院和企业正在开发中,或者打算开发互联网医院系统,其实这些企业和医院还是很有远见的,因为他们知道并了解互联网医院在未来......
  • RK3588开发板Buildroot 系统功能测试U盘测试一
    当插入U盘以后,U盘的格式必须为FAT32格式,大小在32G以下(底板上4个USB接口都可以插入U盘),如下图所示。方法一:1将U盘(U盘的格式必须为FAT32格式,大小在32G以下)插到开发板的usb接口,串口打印信息如下所示,U盘的设备节点是/dev/sda1。U盘的设备节点不是固定的,根据实......
  • 信息系统项目管理师第四版知识摘编:第17章 项目干系人管理​
    第17章项目干系人管理项目干系人管理包括识别能够影响项目或会受项目影响的人员、团体或组织,分析干系人对项目的期望和影响,制定管理策略有效调动干系人参与项目决策和执行。17.1管理基础17.1.1管理的重要性每个项目都有干系人,他们会受到项目积极或消极的影响,或者能对项目施加积极......
  • 【软考】信息系统项目管理师,考试大纲与历年考点分析,学习方法(2021版)
    序信息系统项目管理师,考试大纲与历年考点分析,学习方法(2021版)1、顺序因为内容量,考试大纲>历年考点>学习方法但是使用频率却是,学习方法>历年考点>考试大纲所以本文放置的顺序倒了一下,按照频率摆放章节。2、说明本文仅供个人学习备考期间使用,数据来源是江山老师的2021年已经考......
  • linux 系统安装 zookeeper
     下载zookeeper安装包http://mirror.bit.edu.cn/apache/zookeeper/选择3.4.14版本   上传到服务器,并解压到指定目录tar-zxvfzookeeper-3.4.14.tar.gz-C/usr/local/进入/usr/local/zookeeper/config目录1、复制文件重命名cpzoo_sample.cfg......
  • 操作系统-文件结构划分
    1.文件的逻辑结构(文件内部的逻辑结构)索引文件索引顺序文件2.文件目录结构(文件外部的逻辑结构:文件与文件之间的逻辑结构)FCB和索引节点的关系是怎样的在检索目录文件的过程中,只用到了文件名,文件的其他描述信息用不到,也不需要调入内存,所以文件描述信息就形成了一个叫索引结......