面试问题:如何实现软件可扩展性

article/2025/8/4 6:44:56

网站的可扩展性架构设计,能够在对现有系统影响最小的情况下,系统功能可以可持续扩展及提升的能力。

在此,对容易混为一谈的 “扩展性” 和 “伸缩性” 的概念进行详细说明:

扩展性

表现为:基础设施不需要经常变更,应用之间较少依赖或耦合,可以对需求变更快速响应。它对扩展开放,对修改关闭。架构设计会考虑到未来功能的可扩展性,所以当系统增加新功能时,不需要对现有系统的结构和代码进行修改。

伸缩性

是指系统通过增加(或减少)自身资源规模的方式增强(或减少)处理业务的能力。如果这种增减是成比例的,就可以称之为线性伸缩性。通常是利用集群的方式增加服务器的数量,以提高系统整体业务吞吐能力。

1 构建可扩展的网站架构

度量一个开发框架、设计模式或编程语言优劣的一个重要尺度就是它是否能够让软件开发过程和软件产品更加低耦合。

因为低耦合的系统更容易扩展,也更容易被复用,而且也会让开发过程和维护变得更加容易。但如何分解系统的各个模块、如何定义各个模块的接口、如何复用、组合不同模块构造一个完整的系统,这是软件设计中最具挑战性的部分。

软件架构师的最大价值,就在于把一个大系统分解为 N 个低耦合的子模块的能力,这些子模块包含横向的业务模块与纵向的基础技术模块。这种能力来源于专业技术能力与经验、业务场景的理解、对人性的把握以及对世界的认知。

构建可扩展的网站架构的核心思想是模块化,并在此基础上,降低模块之间的耦合性,提高模块的复用性。

可以利用分层与分割的方式,把软件分割为若干个低耦合、独立的组件模块,然后在这些组件模块之间以消息传递或依赖调用的方式聚合成一个完整的系统。

这些模块可以通过分布式部署的方式,部署在独立的服务器上。这种从物理上分离模块之间的耦合关系,可以进一步降低耦合性。

模块的分布式部署后的聚合方式有: 
* 分布式消息队列。 
* 分布式服务。

1 使用分布式消息队列降低耦合性

如果模块之间不存在直接调用关系,那么新增或修改模块对其他部分的影响最小,这样的扩展性自然更好。

1.1 事件驱动架构

事件驱动架构指的是:在低耦合的模块之间传输事件消息,保持模块之间的松散耦合,通过事件消息来完成模块之间的通信。 事件驱动架构最常见的实现方式就是使用分布式消息队列。

基于消息队列的事件驱动架构

消息队列基于发布——订阅模式工作,消息发送者发布消息,一个或多个消息接收者订阅消息。消息发送者把消息发送至分布式消息队列后就处理完毕,然后由消息订阅者从消息队列中获取消息进行处理。对于新增的业务,只要对某个消息感兴趣,就可以订阅该消息,而这对原有的系统和业务没有任何影响,从而实现系统的可扩展性设计。

消息接收者还可以对收到的消息再构造,定义出一个新的消息类型,然后再把消息发送给订阅了这一新消息类型的接收者。所以基于消息对象的事件驱动架构可以是一系列的流程。

因为消息发送者无须等待就可以返回,所以系统具有更好的响应时间;而且在访问高峰,消息可以暂存于消息队列中,从而减轻了数据库的存储负载压力。

1.2 分布式消息队列

队列是一种先进先出的数据结构,我们可以把消息队列部署到独立的服务器中。应用通过远程访问接口使用消息队列,进行消息的存取操作,从而实现分布式的异步调用:

分布式消息队列原理

目前较为流行的分布式消息队列是 Apache ActiveMQ。

因为消息队列服务器上的数据可以看做是即时处理的,所以在伸缩性上,我们把新服务器加入分布式消息队列集群后,只需要通知生产者服务器更改消息队列的服务器列表就好啦O(∩_∩)O~

可用性上,如果内存队列满了,要将消息写入磁盘,这样当消息推送模块把内存队列中的消息处理完毕后,就会把磁盘中的消息加载到队列中继续处理。

为了避免消息队列服务器宕机造成消息丢失,会把消息存储在消息的生产者服务器上,这样等消息确实被消息消费者服务器处理后才会删除。如果消息队列服务器宕机,生产者服务器会选择分布式消息队列服务器集群内的其他服务器发布消息。

分布式消息队列可以很复杂,比如支持 ESB(企业服务总线)和 SOA(面向服务的架构)等。也可以很简单,比如使用 MySQL 作为分布式消息队列:消息的生产者把消息作为记录写入数据库,消费者查询数据库(按记录写入库表的时间戳排序),这就是一个分布式消息队列啦。再配上成熟的 MySQL 运维手段,也可以达到一个较高的可用性和性能指标哦O(∩_∩)O~

2 使用分布式服务构建可复用的业务平台

分布式服务可以通过接口降低系统的耦合性,不同的子系统之间通过相同的接口描述调用服务。

随着网站功能的日益复杂,系统会逐渐发展成为一个巨无霸,里面聚合了大量的应用和服务组件,这样的一个系统会给开发、维护、部署带来巨大的麻烦: 
* 编译、部署困难。 
* 代码分支管理困难:复用的代码模块由多个团队共同维护修改,所以在代码合并时总会发生冲突。 
* 耗尽数据库连接:假设一个应用设定了 10 个数据库连接,那么一个拥有数百台服务器集群的应用就会在数据库上创建数千个连接。 
* 新增业务困难。在这样一个剪不断、理还乱的系统中新增业务?开玩笑吧O(∩_∩)O~

所以我们要做拆分,把模块独立部署,降低系统的耦合性: 
* 纵向拆分 - 把一个大应用拆分为多个小应用。如果新增的业务较为独立,就直接将其设计并部署为一个独立的 Web 应用。 
* 横向拆分 - 把复用的业务拆分出来,独立部署为分布式服务,新增的业务只需要调用这些分布式的服务,就可以快速搭建出一个应用系统。即使模块内的业务逻辑发生变化,只要保持接口一致,就不会影响其他模块。

分布式服务架构

纵向拆分较简单,通过梳理业务,把关联较少的业务剥离,使其成为独立的 Web 应用。而横向拆分不仅需要识别出可复用的业务、设计服务接口以及规范服务之间的依赖关系,而且还需要一个完善的分布式服务管理框架。

2.1 Web Service 分布式服务

Web Service 曾经是企业应用系统在开发领域中最时髦的词汇之一,它用于整合异构系统以及构建分布式系统:

Web Service 原理

服务提供者通过 WSDL(Web Services Description Language,Web 服务描述语言)向注册中心(Service Broker)描述自身所能提供的服务接口内容,然后注册中心使用 UDDI(Universal Description, Discovery, and Integration,统一描述、发现和集成)发布服务提供者提供的服务。服务请求者从注册中心检索到服务后,通过 SOAP(Simple Object Access Protocol ,简单对象访问协议)与服务提供者通信,使用该服务。

Web Service 虽然有成熟的技术规范和实现,但有如下缺点: 
1. 臃肿的注册、发现机制。 
2. 低效的 XML 序列化手段。 
3. 开销较高的 HTTP 远程通信。 
4. 复杂的部署与维护手段。

这些问题导致 Web Service 难以满足大型网站对高性能、高可用、易部署与易维护的要求。

2.2 大型网站分布式服务的要求

分布式服务框架需要能够支持以下特性: 
* 负载均衡 - 对于服务请求者能够使用可配置的负载均衡算法来访问热门服务(比如登录或商品服务,这些服务被部署在一个集群上)。 
*失效转移 - 可复用的服务被多个应用调用,一旦服务不可用,就会影响到很多应用的可用性。所以即使是很少访问的服务,也需要集群部署。分布式服务框架检测到某个服务不可用时,就会切换到其他服务实例上,保证整体高可用。 
* 高效的远程通信 
* 整合异构系统 
* 对应用最小侵入 - 分布式服务框架支持服务(服务模块需要即支持集中式部署,也支持分布式部署)的渐进式演化和反复。 
* 版本管理 - 网站服务不可中断,所以分布式服务框架需要支持服务的多版本发布,服务提供者升级发布接口新版本的同时,还会继续支持旧版本的服务,直到请求者调用的接口升级后,才会关闭旧版本的服务。 
* 实时监控 - 监控服务提供者和调用者的各项指标,提供运维与运营的支持。

2.3 分布式服务框架设计

大型网站需要更简单、更高效的分布式服务框架构建其 SOA(Service Oriented Architecture ,面向服务的体系结构)。目前国内有较多成功实施案例的开源分布式服务框架是阿里巴巴的 Dubbo。

Dubbo 架构

服务消费者通过接口使用服务,接口通过代理加载具体服务,可以是本地的代码,也可以是远程的服务,因此对应用侵入较小。

客户端模块通过服务注册中心加载服务提供者列表(服务提供者启动后自动向服务注册中心注册自己可以提供的服务接口列表),然后根据配置的负载均衡策略把服务调用请求发送到某台服务提供者的服务器。如果服务调用失败,客户端模块会自动从服务提供者列表中选择一个可以提供同样服务的服务器重新请求,即自动失效转移,保证服务的高可用。

Dubbo 使用 NIO 通信框架,因此具有较高的网络通信性能。

4 可扩展的数据结构

使用 NoSQL 数据库(如 Cassandra)的 ColumnFamily (列族)技术可以做到可扩展的数据结构设计。它是一种面向列族的稀疏矩阵的存储格式。

只需要指定 ColumnFamily 的名字,即可创建表。字段可以在写入数据时再指定,通过这种方式,一张表可以包含数百万个字段。这就使得应用的数据结构可以随意扩展。只需要指定任意字段名称和值即可查询。

5 利用开放平台建立生态圈

用户只有得到他们想要价值,才会愿意使用网站的服务,这样的网站才有存在的意义。但一个网站毕竟不能满足所有用户的需求。

用户不会为网站提供的价值买单,所以网站必须提供更多的增值服务才能赚钱。根据长尾效应,增值服务的数量越大,种类越多,盈利也就越多。但一个网站能够自己开发的增值服务也是有限的。

大型网站为了更好地服务用户、为他们开发出更多的增值服务,会把网站内部的服务封装成接口开放出去,供外部第三方开发者使用,这个平台就叫做开放平台。第三方开发者利用这些开放的接口就可以开发应用程序(如 APP)或网站,为用户提供更多的价值。网站、用户、第三方开发者 
相互依赖,形成一个生态圈。

开放平台是网站内部和外部交互的接口。外部会面对众多的第三方开发者,内部面对的是网站内众多的业务服务。下面是开放平台的架构:

开放平台的架构

  • API 接口:暴露给开发者的一组 API,可以是 RESTful、WebService、RPC 等形式。
  • 协议转换:把各种 API 的输入转换为内部服务可识别的形式,并把内部服务的返回信息封装为 API 格式。
  • 安全:除了身份识别、权限控制等手段之外,还要对访问带宽进行分级限制,保证平台资源被第三方应用合理公平地使用,也能保证网站自身的内部服务不会被外部应用拖垮。
  • 审计:监控第三方应用的访问情况并计费。
  • 路由:把开放平台的各种访问路由映射到具体的内部服务。
  • 流程:把一组松散的服务组织成一个上下文相关的新服务,对外提供接口供开发者使用。

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

相关文章

聊聊分布式的可扩展性

前言 樱花灿烂的季节,满地的绿叶攀上指尖。 春天,总是容易萌生懵懂的心理。。。这就是一堆人辞职的理由??? 团队,总会有人离开,总会有人加入。。。总会有一个leader,当服务器的数量增…

可维护性、可复用性和可扩展性的区别

三者是不同的软件质量属性。 可维护性、可复用性又被认为是两个最重要的用于衡量软件质量的属性。 在《Java设计模式》一书中对可维护性的定义为:指软件能够被理解、改正、适应及扩展的难易程度。 对可复用性的定义为:指软件能够被重复使用的难易程度。 …

八、系统架构 - 可扩展性架构设计

目录 可扩展性 可扩展性的定义 可扩展架构的核心思想 可扩展性架构的主要手段 利用分布式消息队列降低系统耦合性 事件驱动架构(Event Driven Architecture) 消息队列的优势 分布式消息队列 利用分布式服务打造可复用的业务平台 巨无霸系统及其…

后台系统可扩展性学习笔记(一)概要

文章目录 系统大致架构可扩展性负载均衡器与会话保持引入冗余增强系统可用性缓存减轻数据库压力异步处理参考 系统大致架构 当一个用户请求从客户端出发,经过网络传输,达到 Web 服务层,接着进入应用层,最后抵达数据层&#xff0c…

1.3 可扩展性

即使一个系统现在可以可靠地工作,但并不意味着未来它也一定会可靠地工作。造成退化的一个常见的原因就是日益增加的负载:系统的并发用户可能从10000增加到了100000,或者从1000000增加到10000000。可能它处理的数据量比之前大得多。可扩展性是…

七种方法增强代码可扩展性(多图详解)

1 六大原则 在设计模式中有六大设计原则: 单一职责原则:一个类只做一件事 里式替换原则:子类可以扩展父类 依赖倒置原则:面向接口编程 接口隔离原则:高内聚低耦合 迪米特法则:最少知道原则 开闭原则&#…

系统复杂度之【可扩展性】

紧接着我们来聊聊可扩展性。 可扩展性是指,软件系统具备面对未来需求变化而进行扩展的能力。系统可根据新的需求做出少量或者不需要修改,无需对整个系统进行重构或重建。 由于软件系统变化多端,新的需求不断提出,因此可扩展性非常…

php文字链接下划线怎么取消,html超链接怎么去掉下划线

html超链接怎么去掉下划线? 可以用css的text-decoration:none来取消连接的下划线 这是一个链接 扩展资料: 超级文本标记语言是标准通用标记语言下的一个应用,也是一种规范,一种标准,它通过标记符号来标记要显示的网页中…

html去除超链接标记,html超链接去掉下划线的方法

html超链接去掉下划线的方法 发布时间:2020-04-03 15:16:00 来源:亿速云 阅读:59 作者:小新 今天小编给大家分享的是html超链接去掉下划线的方法,很多人都不太了解,今天小编为了让大家更加了解html超链接去…

<el-tabs>改变样式(去掉下划线及其他样式)

elemen-ui官方文档中给的标签页是蓝色的&#xff0c;长这样 我想要的样子&#xff1a; 这里重点是去掉原来的下划线以及鼠标悬停时的背景颜色&#xff0c;话不多说直接上代码&#xff1a; <div class"leftTabs"><el-tabs v-model"activeName" c…

html怎么消除链接字体,CSS去掉超链接下划线

div css之去掉A超链接下划线样式 一、去掉字体下划线装饰CSS属性样式代码 text-decoration:none 解释&#xff1a; CSS下划线样式单词&#xff1a;text-decoration 不显示下划线(去掉字体下划线样式)&#xff1a;none 二、div css网页重构前初始化去掉超链接下划线 由于有的浏览…

html更改超链接下划线颜色,超链接去掉下划线_WORD中不取消超链接,只改超链接的颜色和去掉下划线...

ppt超链接去掉下划线 1、首先打开PPT。2、“插入”“文本框”“横排文本框”,在空白处写字,调整字的大小等。3、插入”“超链接”,会出现“插入超链接”对话框,在这里选择需要链接到的位置,点击确定。4、这时出现的超链接字体就会有下划线。 5、我们在这里选中超链接字体右…

html超链接下划线改虚线_html超链接去掉下划线 html去除取消超链接下划线

大多时候我们知道&#xff1a;text-decoration:underline &#xfffd;?strong>显示下划&#xfffd;?/strong>&#xfffd;?/p> html中去除去&#xfffd;?a href"//www.css5.com.cn/html/989.shtml">A标签超链接下划线代码&#xfffd;?br /> …

php中超链接怎么去下划线的,html如何去掉超链接下划线?html超链接去掉下划线的方法介绍...

前端网页的开发中总是不可避免会使用到超链接&#xff0c;但是使用超链接时下面都会有一条下划线&#xff0c;这在网页中有时会显得很突兀&#xff0c;不合适也不美观&#xff0c;所以我们就需要将超链接下的这条下划线给去掉&#xff0c;接下来的这篇文章就来给大家介绍html下…

html5中链接去除下划线,html超链接去掉下划线 html去除取消超链接下划线

html a超链接标签&#xff0c;默认有的涉猎器表现有下划线&#xff0c;有的不有下划线&#xff0c;大多锚文本超链接A标签内字体是有下划线的&#xff0c;怎么去除超链接下划线&#xff1f;html 超链接去除下划线怎么样做&#xff1f; 去掉去除超链接锚文本的下划线需要CSS花样…

html如何取消表格的横线,怎么去掉下划线样式?

怎么去掉超链接下划线?下面本篇文章给大家介绍一下在html网页和word文档中去掉下划线样式的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 html代码中去掉超链接的下划线 前端网页的开发中总是不可避免会使用到超链接,但是使用超链接时下面都会有…

word里边页眉下面的下划线怎么去掉

原创作品&#xff0c;出自 “深蓝的blog” 博客&#xff0c;欢迎转载&#xff0c;转载时请务必注明以下出处&#xff0c;否则追究版权法律责任。 深蓝的blog&#xff1a;http://blog.csdn.net/huangyanlong/article/details/43762599 今日在使用word编辑统计表时&#xff0c;添…

为什么电流镜的复制电路是二极管结构?

左图是电流镜的概念图&#xff0c;复制电路偏置在IREF&#xff0c;为右边的管子提供一个偏压VGS。右图是最典型的电流镜结构&#xff0c;今天的问题是为什么复制电路结构用二极管连接结构&#xff0c;不用CS&#xff0c;CD或者CG中的一种呢&#xff1f; 首先我们得明确复制电路…

电流镜电路公式推导

最近复习了硬件笔试题。碰到了这个题&#xff0c;遂写一下自己的推导过程。 电流镜原理图&#xff08;假设三个管子的是参数理想一致的情况&#xff09; 基于 KCL 公式 -->>> Ie1 Ib2 Ib3 基于 BJT放大关系 -->>> Ie1 Ib1 *(1β)基于 KCL 公式 -->…