如何设计 Web 应用程序:软件架构 101
最初发布于Educative.io
你已经踏上了创业之旅,想要构建自己的 Web 应用。你的想法已经成型,但正确的架构至关重要。
在这篇文章中,我们将讨论以下关键领域:
- 什么是软件架构
- 为什么软件架构很重要
- 软件架构和软件设计之间的区别
- 软件架构模式
- 如何确定你的应用应该拥有的层数
- 水平或垂直缩放...哪种适合我的应用程序?
- 整体式架构还是微服务?
- 何时应该使用 NoSQL 或 SQL?
- 选择合适的技术
- 如何成为一名软件架构师
- 下一步该怎么做
这篇文章的目标是让你对 Web 架构、相关概念以及在设计应用时如何选择合适的架构和技术有一个扎实的理解。读完这篇文章后,当你从零开始设计应用时,你将不再茫然无措。
如果你正在寻找一门关于 Web 应用和软件架构的完整课程,我推荐你看看《Web 应用和软件架构 101》。对于任何想要增强软件架构整体知识的人来说,这门课程都非常有用。
让我们开始吧!
什么是软件架构?
系统的软件架构描述了其主要组件、它们之间的关系以及它们如何相互作用。
它本质上是一个蓝图。它提供了一种抽象来管理系统的复杂性,并在组件之间建立通信和协调。
以下是一些要点:
- 该架构有助于定义满足所有技术和操作要求的解决方案,其共同目标是优化性能和安全性。
- 架构设计涉及组织需求和开发团队需求的交汇。每个决策都会对质量、可维护性、性能等产生相当大的影响。
我最喜欢的软件架构定义之一来自《设计模式:可复用面向对象软件的元素》一书的合著者拉尔夫·约翰逊(Ralph Johnson)。他指出:
您希望在项目早期就做出正确的决定。
综上所述,让我们继续讨论软件架构为何如此重要。
为什么软件架构很重要?
成功创造任何东西的关键在于打好基础。无论是建造建筑物还是制作披萨。如果基础打不好,我们就必须重新开始;没有别的办法。
构建 Web 应用程序也一样。架构是其基础,必须经过深思熟虑,以避免日后出现任何重大的设计变更和代码重构。许多工程师会告诉你,你不想深入研究重新设计的东西。它会像黑洞一样吞噬你的时间。它可能会将你的发布日期推迟数月甚至更久。这还不包括由此造成的工程和财务资源的浪费。
这也取决于我们在开发过程的哪个阶段因为在初始设计阶段仓促做出的决定而陷入僵局。所以,在我们接触代码并开始动手之前,我们必须确保底层架构正确。
虽然软件开发是一个不断迭代和演进的过程,但我们并不总是能一次就做到完美。但这并不能成为我们不做充分准备的借口。
软件架构和软件设计之间的区别
软件设计和架构之间经常发生混淆,因此我们将对此进行分解。
软件架构用于定义系统的框架和高级组件,以及它们如何协同工作。例如,您是否需要无服务器架构,将应用程序拆分为两个组件:BaaS(后端即服务)和FaaS(函数即服务)?或者,您是否需要类似微服务架构的架构,将不同的功能/任务拆分成各自的模块/代码库?
选择架构将决定您如何处理性能、容错、可扩展性和可靠性。
软件设计负责代码层面的设计,例如每个模块的功能、类的作用域以及函数的用途等等。如果策略性地使用软件设计模式,程序员可以避免重复造轮子,而是使用他人已经完善的方法,从而显著提高效率。软件设计模式还提供了一种实用的通用语言,可以在与他人讨论或在大型团队中管理代码时,将重复出现的问题和解决方案概念化。不妨学习这门实用的课程:软件设计模式:软件开发人员的最佳实践,开始在你的代码中运用软件设计模式。
这是一篇关于理解软件设计的重要性以及开发人员经常使用的经过验证的模式的好文章:7 种最重要的软件设计模式。
软件架构模式
客户端-服务器
该架构采用请求-响应模型。客户端向服务器发送请求以获取信息,服务器进行响应。
您浏览的每个网站,无论是 Wordpress 博客还是 Facebook、Twitter 或银行应用程序等网络应用程序,都是基于客户端-服务器架构构建的。
点对点
P2P 网络是一种无需中央服务器即可相互通信的网络,其中的计算机(也称为节点)无需中央服务器即可通信。由于没有中央服务器,因此可以避免单点故障。网络中的所有计算机都拥有平等的权限。一个节点同时充当种子服务器和下载服务器。因此,即使某些计算机/节点发生故障,网络和通信仍然畅通无阻。
P2P是区块链技术的基础。
模型-视图-控制器(MVC)
MVC 架构是一种软件架构模式,它根据功能将应用程序逻辑划分为三个组件。这些组件分别称为:模型 (Model) - 表示数据在数据库中的存储方式;视图 (View) - 用户可见的组件,例如输出或 GUI;控制器 (Controller) - 充当模型和视图之间接口的组件。
MVC 架构不仅用于桌面应用程序,还用于移动和 Web 应用程序。
微服务
在微服务架构中,不同的功能/任务被分成单独的模块/代码库,它们相互协同工作,形成一个整体的大型服务。
与单片架构相比,这种特殊的架构使得应用程序维护、功能开发、测试和部署更加轻松、清晰。
事件驱动
非阻塞架构也称为反应式架构或事件驱动架构。事件驱动架构在现代 Web 应用程序开发中非常流行。
它们能够以最小的资源消耗处理大量并发连接。现代应用程序需要完全异步的模型才能扩展。这些现代 Web 框架在分布式环境中提供了更可靠的行为。
分层
此模式可用于构建可分解为多组子任务的程序,每组子任务都处于特定的抽象级别。每一层都为上一层提供服务。
以下是最常见的层:
- 表示层
- 应用层
- 业务逻辑层
- 数据访问层
六边形
该架构由三个组件组成:
- 端口
- 适配器
- 领域这种架构的重点是使应用程序的不同组件独立、松散耦合且易于测试。
该架构模式的核心是领域,也就是业务逻辑。在外部,外层包含端口和适配器。端口就像 API,充当接口。应用程序的所有输入都通过该接口进行。
如何确定你的应用应该拥有的层数
单层应用程序
优点:
- 无网络延迟
- 数据可快速、轻松地获取
- 数据不通过网络传输,确保数据安全
缺点:
- 对应用程序的控制很少;一旦发布,就很难实现新功能或代码更改
- 测试必须极其彻底,尽量减少出错的可能性
- 单层应用程序容易受到调整或逆向工程
双层应用程序
优点:
- 由于代码和 UI 位于同一台机器上,因此网络调用更少
- 数据库服务器与业务逻辑物理上接近,性能更高。
缺点:
- 由于客户端掌握了大部分应用程序逻辑,因此在控制软件版本和重新分发新版本方面出现了问题。
- 由于仅支持有限数量的用户,因此缺乏可扩展性。当多个客户端请求增加时,由于客户端需要单独的连接和 CPU 内存才能继续运行,应用程序性能可能会降低。
- 由于应用程序逻辑与客户端耦合,因此很难重用逻辑。
三层应用程序
优点:
- 由于在中间层传递的用于数据库更新的数据确保了其有效性,因此可以消除通过客户端应用程序造成的数据损坏
- 将业务逻辑放在集中式服务器上,使数据更安全
- 由于应用服务器的分布式部署,系统的可扩展性得到增强,因为不需要每个客户端单独建立连接,而只需来自少数应用服务器的连接就足够了。
缺点:
- 通常在创建 3 层应用程序时需要付出更多努力,因为通信点增加了(客户端到中间层到服务器,而不是直接从客户端到服务器),并且 Visual Basic、PowerBuilder、Delphi 等工具提高的性能将会降低。
N 层应用程序
优点:
- 三层架构的所有优点
- 由于数据库层和客户端层的卸载,性能得到了提高,使其能够适应中高容量行业
缺点:
- 由于层级的组件化,复杂的结构难以实现或维护
结论
- 当您不希望有任何网络延迟时,您应该选择单层架构
- 当您需要最小化网络延迟并且需要对应用程序内的数据进行更多控制时,请选择双层应用程序
- 当您需要控制应用程序的代码/业务逻辑并希望其安全,并且需要控制应用程序中的数据时,您应该选择三层架构。
- 当您需要应用程序扩展和处理大量数据时,您应该选择 N 层架构。
水平或垂直缩放...哪种适合我的应用程序?
如果您的应用是一个实用程序或工具,预计会接收少量持续流量,那么它可能并非任务关键型应用。例如,某个组织的内部工具或类似工具。为什么要费心将其托管在分布式环境中?单台服务器足以管理流量,因此,如果您确定流量负载不会显著增加,则可以进行垂直扩展。
如果您的应用是面向公众的社交应用,例如社交网络、健身应用或类似的应用,那么预计其流量在不久的将来会呈指数级增长。在这种情况下,高可用性和水平可扩展性对您来说都至关重要。
构建并部署到云端,从一开始就牢记横向可扩展性。这里有一个很棒的网站,可以了解更多关于可扩展性的信息。
整体式架构还是微服务?
让我们来探讨一下何时应该选择其中一个。
何时使用单体架构
单体应用最适合需求简单、流量有限的场景。例如,组织内部的税务计算应用或类似的开源工具。
在这些用例中,企业可以确定用户群和流量不会随着时间的推移呈指数级增长。
还有一些情况是,开发团队决定从单片架构开始,然后扩展到分布式微服务架构。
这有助于他们在需要时逐步处理复杂的申请。这正是 LinkedIn 所做的。
何时使用微服务架构
微服务架构最适合复杂的用例以及预计未来流量会呈指数级增长的应用程序,例如花哨的社交网络应用程序。
典型的社交网络应用程序具有各种组件,例如消息传递、实时聊天、实时视频流、图像上传、点赞、分享功能等。
在这种情况下,我建议分别开发每个组件,同时牢记单一职责和关注点分离原则。
在单个代码库中编写每个功能很快就会变得混乱。
因此,到目前为止,在单体和微服务的背景下,我们已经经历了三种方法:
- 选择单体架构
- 选择微服务架构
- 从单片架构开始,然后扩展到微服务架构。
选择单体架构还是微服务架构很大程度上取决于我们的用例。我建议,保持简单,彻底理解需求。了解情况,只在需要时构建,并持续迭代改进代码。这才是正确的做法。
何时应该使用 NoSQL 或 SQL?
何时选择 SQL 数据库?
如果您正在编写股票交易、银行业务或金融应用,或者需要存储大量关系数据(例如,编写像 Facebook 这样的社交网络应用),那么您应该选择关系数据库。原因如下:
事务和数据一致性
如果您编写的软件与金钱或数字有关,那么事务、ACID 和数据一致性对您来说至关重要。关系型数据库在事务和数据一致性方面表现出色。它们符合 ACID 规则,历史悠久,并且久经考验。
存储关系
如果你的数据有很多关系,比如你的哪些朋友住在某个城市?你的哪些朋友已经在你计划今天去的餐厅吃过饭了?等等。没有什么比关系数据库更适合存储这类数据了。
关系数据库是为了存储关系而构建的。它们已经过实践检验,并被 Facebook 等业内巨头用作面向用户的主要数据库。
流行的关系数据库:
- MySQL
- 微软 SQL 服务器
- PostgreSQL
- MariaDB
何时选择 NoSQL 数据库
以下是选择 NoSQL 数据库的几个原因:
处理大量读写操作
当您需要快速扩展时,NoSQL 数据库是您的不二之选。例如,当您的网站有大量读写操作,并且需要处理大量数据时,NoSQL 数据库是最佳选择。由于 NoSQL 数据库能够动态添加节点,因此能够以最小的延迟处理更多并发流量和海量数据。
运行数据分析
NoSQL 数据库也最适合数据分析用例,在这些用例中我们必须处理大量数据的涌入。
流行的NoSQL数据库:
- MongoDB
- Redis
- 卡桑德拉
- HBASE
如果您想尝试像 MongoDB 这样的 NoSQL 数据库,那么我强烈建议您查看 Nikola Zivkovic 的课程《MongoDB 权威指南》。
选择合适的技术
实时数据交互
如果您正在构建一个需要的应用程序:
- 与后端服务器实时交互,例如消息应用程序或音频视频流应用程序(如 Spotify、Netflix 等)。
- 客户端与服务器之间的持久连接,以及后端的非阻塞技术。
然后,一些支持您编写这些应用程序的流行技术是 NodeJS 和流行的 Python 框架Tornado。如果您在 Java 生态系统中工作,则可以研究 Spring Reactor、Play 和Akka.io。
点对点 Web 应用程序
如果您打算构建一个点对点的 Web 应用程序,例如 P2P 分布式搜索引擎或 P2P 直播电视广播服务(类似于微软的 LiveStation),那么您将需要研究 JavaScript、DAT、IPFS 等协议。不妨了解一下FreedomJS,它是一个用于构建可在现代 Web 浏览器中运行的 P2P Web 应用程序的框架。
基于CRUD的常规应用
如果您有简单的用例,例如基于常规 CRUD 的应用程序,那么您可以使用的一些技术是:Spring MVC、Python Django、Ruby on Rails、PHP Laravel、ASP .NET MVC。
简单、小规模的应用
如果您打算编写一个不太复杂的应用程序,例如博客、简单的在线表单,或者集成社交媒体并在门户网站的 IFrame 中运行的简单应用程序,那么您可以选择 PHP。立即免费学习 PHP。
您还可以考虑其他 Web 框架,例如 Spring Boot、Ruby on Rails,它们可以大幅减少代码冗长、配置复杂度和开发时间,并促进快速开发。但 PHP 托管的成本远低于其他技术,非常适合非常简单的用例。
CPU 和内存密集型应用程序
您是否需要在后端运行 CPU 密集型、内存密集型、计算量大的任务,例如大数据处理、并行处理、对大量数据运行监控和分析?
常规的 Web 框架和脚本语言并非专为数字运算而设计。业界常用的编写高性能、可扩展分布式系统的技术是 C++。它具有简化底层内存操作的功能,在编写分布式系统时为开发人员提供更强大的内存控制能力。大多数加密货币都是使用这种语言编写的。这里有一个很棒的免费学习 C++课程。
Rust 是一种类似于 C++ 的编程语言。它专为高性能和安全并发而构建。最近,它在开发者圈子里越来越受欢迎。Java、Scala 和 Erlang 也是不错的选择。大多数大型企业系统都是用 Java 编写的。
Go 是 Google 开发的一种编程语言,用于编写适用于多核机器和处理大量数据的应用程序。以下是如何开始 Go 开发的方法。
Julia 是一种动态编程语言,专为高性能、运行计算和数值分析而构建。
如何成为一名软件架构师?
如果这一切听起来很有趣,那么你可能渴望成为一名软件架构师。但是你从哪里开始呢?嗯,从软件架构师做起的人非常少见,所以大多数软件工程师在开始从事架构设计之前都会工作几年。
熟悉软件架构的最佳方法之一是设计自己的 Web 应用程序。这将迫使你仔细思考应用程序的各个方面,包括负载均衡、消息队列、流处理、缓存等等。一旦你开始理解这些概念如何融入你的应用程序,你就离成为一名软件架构师的目标又近了一步。
作为一名有抱负的软件架构师,你需要不断扩展知识,并紧跟最新的行业趋势。你可以从学习一种或多种编程语言开始,从事软件开发工作,然后逐步发展。
即使你无法在大学获得软件架构师学位,也有一些其他课程可能会对你有所帮助。“Web 应用程序和软件架构 101”是学习 Web 应用程序设计和实现最佳实践的绝佳起点。
接下来该去哪里?
虽然这篇文章涵盖了很多内容,但我们只是触及了这个主题的表面。我们还没有探索 REST API、高可用性和 CAP 定理。
如果你想深入了解软件架构,我强烈推荐《Web 应用程序和软件架构 101》。它会一步步指导你了解设计 Web 应用程序架构时涉及的不同组件和概念。
您将了解各种架构风格,例如客户端-服务器、对等分散架构、微服务、Web 应用程序中数据流的基础知识、所涉及的不同层、可扩展性、高可用性等概念等等。
此外,您还将学习如何选择合适的架构和技术栈来实现您的用例。您将逐步了解不同的用例,这将帮助您深入了解在编写 Web 应用程序时,哪种技术和架构最适合特定用例。您将逐渐理解其中涉及的技术权衡。
如果你是刚踏入软件开发领域的新手,这门课程将会对你大有裨益。它还能帮助你应对软件工程面试,尤其是全栈开发人员的职位。
学习愉快!
文章来源:https://dev.to/education/how-to-design-a-web-application-software-architecture-101-188b