题目:论软件系统架构风格 #
软件体系结构风格是描述某一特定应用领域中系统组织方式的惯用模式。体系结构风格定义一个系统家族,即一个体系结构定义一个词汇表和一组约束。词汇表中包含一些构件和连接件类型,而这组约束指出系统是如何将这些构件和连接件组合起来的。体系结构风格反应了领域中众多系统所共有的结构和语义特性,并指导如何将各个模块和子系统有效地组织成一个完整的系统。
请围绕"论软件架构风格’论题,依次从以下三个方面进行论述。
1、概要叙述你参与分析和设计的软件系统开发项目以及你所担任的主要工作。
2、软件系统开发中常用的软件架构风格有哪些?详细阐述每种风格的具体含义。
3、详细说明你所参与分析和设计的软件系统是采用什么软件架构风格的,并分析采用该架构风格设计的原因。
摘要 #
2021年4月,我所在的国内某头部互联网公司决定搭建一套全新的移动设备指纹分析处理平台,该项目旨在为集团各业务线提供高效、可靠的移动设备指纹分析、存储及唯一标识移动设备的能力,我有幸地担任本次系统开发的架构师,主要负责整个系统的架构设计,对项目的技术活动进行指导和协调。本文将以该项目为背景,着重介绍几种常见软件架构风格及其具体含义,同时详细探讨了调用/返回、独立构建和仓库风格如何在日活设备约2.6亿、峰值QPS达7万的项目中的实际应用。实践证明:恰当地组合使用架构风格,使得系统的开发取得了巨大的成功,目前系统已稳定运行1年多,赢得了亿级用户的一致好评。
正文 #
随着移动互联网的迅猛发展,手机等移动设备已经成为人们生活中不可或缺的一部分,为我们带来了更便捷的沟通交流方式。在此背景下,我就职的国内最大的社交媒体平台之一的公司,于2021年4月决定建设一套全新的移动设备指纹分析处理系统,旨在给集团提供全面的移动设备指纹分析、存储和唯一标识移动设备的能力,为公司的多元化的业务提供坚实的底层支持。移动设备的广泛应用使得此类系统的需求变得尤为迫切,我们面临着如何高效处理日活2.6亿的移动设备指纹的读写、以及峰值QPS达7万的高并发场景的问题。
作为这一重要项目的核心,我有幸被委以重任,担任本次系统开发的架构师,负责系统整体的架构设计,以及对项目中的技术活动进行指导和协调等。本文将深入探讨软件架构风格的实际应用。特别是,将重点介绍常见的软件架构风格及其具体含义,探讨调用/返回、独立构件、仓库风格等在日活设备约2.6亿、峰值QPS达7万的项目中的实际应用。
数据流风格包含顺序批处理和管道/过滤器子风格。顺序批处理适合于大量的整体的数据,无用户交互,典型应用有传统编译器和网络报文处理。管道/过滤器适合处理大量流式数据,弱用户交互。它们均由数据来进行驱动。
调用/返回风格有主程序/子程序、面向对象和层次架构子风格。主程序/子程序风格是结构化设计,逐步细化的系统架构。面向对象风格将系统看做对象集合,在对象中封装数据和操作,对象之间通过函数调用来交互,具备封装、继承和多态特性。层次架构风格将信息系统分层,这样做的好处在于将一个复杂的问题分解到各层去解决,保证了系统优良的可维护性和可扩展性。
独立构件风格包含进程通讯和隐式调用子风格。进程通讯风格将进程间的通信视为一种服务,可以通过共享内存、消息传递、远程过程调用等方式实现。隐式调用风格区别于调用返回风格,它的核心思想是通过事件的触发和处理来驱动系统的行为和交互。独立构建风格拥有较低的耦合性,强调通信的可靠性、安全性和效率性,同时还要考虑系统的可扩展性和可维护性,缺点在于放弃了对子程序的控制。
虚拟机风格包含解释器和规则系统子风格。解释器风格的软件通常包括解释引擎、存储源代码的区域、记录工作状态的数据结构以及记录执行进度的数据结构。这种风格的软件使用虚拟机来模拟硬件执行过程和关键应用。其缺点在于执行效率较低。规则系统风格则是在解释器风格上引入规则或者经验,典型的应用有专家系统。
仓库风格包含数据库系统和黑板系统两种子风格。它的软件元素分为资源库(中央数据单元)和相互依赖的构件组,构件组能够操作中央数据单元。信息可以在中央数据单元和构件之间进行交换,这是实现数据共享结构的技术基础。根据控制策略,数据共享结构可分为传统数据库风格和黑板风格。传统数据库风格适用于事件驱动的信息处理,结果存储在中央数据单元,而黑板风格则由中央数据单元的当前状态来驱动系统运行。
我权衡了各种架构风格的优缺点及适用场景,根据项目的实际情况,选择了调用/返回架构风格,独立构建风格,仓库风格的混合使用作为该系统的整体架构风格。下面讲述我选择这几种架构风格的原因。
调用/返回风格在项目中应用是为了系统的可修改性、可重用性和可扩展性。为了实现这一目标,我们将该系统整体分成了4层的B/S和C/S架构,分别是表示层、控制层、业务逻辑处理层、数据持久层;表示层通常负责接收用户的请求,对用户的输入、系统的输出进行检查与控制,它包括页面跳转、向用户呈现最终的结果信息等功能;控制层主要负责接收请求、处理跨域问题、验签、鉴权、IP限制、日志追踪以及返回数据等任务,它扮演着连接用户请求和业务逻辑处理层的桥梁角色;业务逻辑处理层是对业务功能的抽象,它把具体的业务功能抽象成控制层可调用、可加工的资源,这类资源通常来自于数据库的多个相关联的表,为了提高数据查询速度,一些高频数据会被保存在缓存数据库中,业务逻辑处理层负责管理这些数据;数据持久层主要使用Gorm和Redisgo来完成对数据的增、删、改和查操作。它的主要功能是为业务逻辑层提供透明的数据访问和持久化能力。数据持久层的设计原则是单一职责的,确保对数据的操作具有清晰的界限。整体架构中,底层为上层提供服务,上层为底层提供驱动,修改当前层最多只会影响逻辑上紧邻的上下两层,从而很好地实现了系统的可修改性和可扩展性。
独立构件风格在项目中的应用主要体现在数据传输和消息通讯方面,该风格具有以下优点:降低系统的耦合度,提高系统的可扩展性和可重用性,并且能够有效地进行系统流量的削峰填谷,使得系统即使在日活约2.6亿的移动设备指纹、以及峰值QPS达7万的高并发场景下也能稳定运行。在我们的系统中,独立构建风格主要体现在消息中间件kafka上,它通常会涉及到2类角色:生产者和消费者;在本系统中,生产者又称为设备指纹上行服务,它由golang的web应用框架gin和谷歌的远程过程调用Grpc组成,设备上行服务负责将设备SDK采集的经个人信息保户法和用户授权的273项脱敏的设备指纹信息写入到分布式的kafka集群中;而消费者又称为设备指纹落地服务,它是一个基于golang的高性能协程池,设备指纹落地服务的主要任务是从kafka集群中消费指定topic的设备指纹数据,并将其写入到分布式的mysql、redis中,以供各业务线使用。整体架构中,独立构件风格在系统中扮演了非常重要的角色,它不仅提高了系统的可扩展性和可重用性,还能够有效地处理系统流量,确保系统在高并发场景下的稳定运行。
仓库风格在项目中主要体现在数据库系统方面。仓库风格强调以数据为中心,构件组围绕这个中心进行信息交换。考虑到系统面临日活约2.6亿的移动设备指纹、以及峰值QPS达7万的高并发场景,我们设计了一套融合了mysql和redis技术的高性能、高可用的数据库架构;为了克服mysql数据库的I/O瓶颈,以及保持高效率的读写,我们将mysql从逻辑上分为多个实例,特别是将读写操作极大的实例进行分库和分表;此外我们将mysql的每个实例都做了读写分离,主库负责写操作,从库负责读操作,它们通过binlog实现的主从同步来保证数据的一致性;为了进一步优化该数据库系统,我们引入了分布式的redis集群,在redis集群上同样进行了读写分离和主从同步的配置,这样,使得系统能轻松处理高并发请求,减轻了系统对mysql数据库的访问压力。通过引入读写分离、主从同步的mysql和redis的分布式集群,整体架构中,仓库风格的数据库系统极大地提高了数据中心的信息交换能力,在提升系统的性能和可靠性的同时,还为未来的扩展和升级提供了更坚实的基础。
经历了一年半的开发,该项目于2022年10月成功上线,并且在过去的一年多时间里,系统架构稳定运行,实现了既定目标,赢得了过亿用户一致好评。虽然我们取得了这些成就,但也意识到了一些不足之处,特别是在自动化运维方面。这些挑战带给我们宝贵的经验和教训,为未来的工作提供了重要的参考,这正是我最大的收获。