[解读REST] 3.基于网络应用的架构

链接上文[解读REST] 2.REST用来干什么的?,上文中解释到什么是架构风格和应该以怎样的视角来理解REST(Web的架构风格)。本篇来介绍一组自洽的术语,用它来描述和解释软件架构;以及列举下对于基于网络的应用来说,哪些点是需要我们重点关注的。

1 软件架构

软件架构方面关注的是如何以最佳的方式划分一个系统、如何标识组件、组件之间如何通信、信息如何表达、组成系统的元素如何独立的进化,以及如何表达上述的内容。一个优秀的软件架构并非凭空靠想象得来的,每一个架构级的决策,都应该根据被设计的系统功能、行为和社交三方面的需求而作出。这是一个基本的设计原则,即“形式追随功能”,这条原则源自于建筑学领域在数百年中失败的建筑项目中获得的经验,但是却总被软件行业所忽略。“dedign-by-buzzword”的行为随处可见,出现这种行为的原因在于很多设计者在选择某一个优秀的软件架构时,不了解这个架构的适用场景是什么、背后是基于什么考量才得出的这样的架构,以及是否吻合自己的需求。下面先介绍一组自洽的术语来描述解释软件架构。

1.1 运行时抽象

软件架构是一个软件系统在其运行过程中某个阶段的运行时元素的抽象。一个系统可能会有多层抽象和多个运行阶段组成,每一个抽象和运行阶段都是自己的软件架构

软件架构的核心是抽象:通过封装来隐藏系统的一些细节,从而更好的识别其架构属性。一个复杂的系统会有着多层抽象,每一层都有自己的架构,架构代表了某个层次上系统行为的抽象。除了层次之外,系统还会有多个运行阶段,比如启动、初始化、正常运行、停止、重新初始化等,每个阶段也都有自己的架构,比如配置文件在启动的时候会作为架构的一个数据元素来处理,到了正常运行的时候,这些数据元素已经分散到了系统的各个方面,在后续的阶段中就不会再把它作为一个数据元素了。

很多时候很容易把软件的源代码的静态结构视为软件架构,其实这是不妥的。软件结构是静态的源代码的组织结构方式,而非其真正运行起来时所表现出来的功能、层次和行为等。举个小例子,比如一个接口和它的一个实现者,它们在源代码级别是归属在一个地方的,但是在运行时我们关注的通常是其接口的行为,而非它的实现者身在何处。

1.2 架构元素

软件架构是由一些架构元素(组件、连接器和数据)的配置来定义的,这些元素之间的关系受到一组约束,以获得期望的架构属性。具体的元素类型如下:

  1. 组件:组件是软件指令和内部状态的抽象单元,通过其接口提供数据的转换能力。比如执行从硬盘加载数据到内存、执行一些计算、转换为另外一种格式等。每个组件的行为是架构的一部分,能够被其他组件观察到或者识别出来(即由某个组件为其他组件提供的接口和服务来定义该组件,而不是由该组件内部的实现来定义)。具体的例子有浏览器,网关,Web服务器(apache,ngnix.,iis)等。
  2. 连接器:对于组件之间的通信、配合或者协作进行中间周旋的一种抽象机制。区分连接器和组件的最佳方式是看其对数据的处理方式,连接器是把数据从一个接口移交到另外一个接口而不改变数据,以此来支持组件之间的通信。在连接器的内部,可能是由多个组件组成的子系统,为了移交的目的而对数据进行某种转换、执行移交然后做想法的转换并交付与原始数据相同的结果。然而在架构所能捕获的外部行为抽象中,可以忽略这些细节。具体的例子有缓存,SSL/TLS等等这类。
  3. 数据:数据是组件通过连接器接收或发送的信息元素。在基于网络应用的结构中,数据元素的特性往往会决定某一种架构风格是否适用,比如是直接的和组件进行交互,还是把组件转换为数据元素,通过网络移交该元素,然后再对该数据元素做相反的转换,得到一个能够在本地与之交互的组件。具体的数据例子有二进制数据,json,HTML文档,图片等。

1.3 配置

配置是系统在运行期间和组件、连接器和数据之间的架构关系的结构。此配置非彼配置,指的不是一个系统的各项配置参数,而是如何组织架构元素之间的关系。

1.4 架构属性

架构属性是软件架构对组件、连接器和数据的选择以及排列所产生的属性。其包含了系统的功能性属性以及非功能性属性(比如组件的可重用性、效率、扩展能力等)。架构属性是由一组架构约束产生的,而架构约束则是由在架构元素的某一个方面应用软件工程原则来驱动的。比如统一管道和过滤器架构风格通过在组件的接口上应用通用性的原则(强迫组件实现统一的接口),从而获得组件的可重用性和可配置性的架构属性。因此它的架构约束就是由通用性原则所驱动的“统一组件接口”,目的是获得上述的可重用性和和配置性这两个架构属性。举个简单的小实例,比如asp net mvc中的filter。

架构设计的目标是创建包含一组期望的架构属性的架构。这组架构属性是系统需求的一个超集,不同架构属性的在这组集合中的所占的比重取决于系统本身的需要。后面会介绍对于一个基于网络的应用来说,哪些架构属性是值得关注的。

1.5 架构风格

架构风格的定义在上一篇中已经简单的解释过了,这里更严谨的定义一下:架构风格是一组相互协作的架构约束,这些架构约束限制了架构元素的角色和功能,以及在任何一个遵循该架构风格的架构中允许存在的元素之间的关系

一个架构中即会包含功能属性又会包含非功能属性,直接比较不同类型的架构时是比较困难的。架构风格是一种对架构进行分类并且定义它们的公共特征的机制。通过比较这部分公共部分的架构约束,来识别其能获得的架构属性的差异。好比上篇文章中说到的佛教建筑和古罗马建筑,比较它们的不同之处的办法在于用其各自的特征来对比。架构风格是比软件架构更加抽象的一个层次。比如说面向对象语言如果是架构风格,则Java,C#这些具体的实现了面向对象的语言则是具体的软件架构;当我们拿C#和C对比的时候,它们的本质差异归根到底是面向对象与面向过程的差异,而并不是分别实现了面向对象的C#和面向过程的C的具体细节差异。

2 基于网络应用的架构

软件架构可以存在于软件系统的多个层次之上。而REST则是聚焦于软件架构的最高层次的抽象,即跨越网络的运行环境,这里的组件是通过网络通信来实现组件的交互的。

软件方面的研究通常是关注软件设计如何分类和设计,但是却很少能客观的评估不同的设计对于系统行为有什么影响。

网络方面的研究则聚焦于系统之间的通信细节以及如何提高通信性能,却通常忽略一个事实,有时候改变一个应用的交互风格对于性能产生的影响要比改变所使用的通信协议更大。

基于网络 VS 分布式:基于网络的架构和软件架构的区别在于,组件之间的通信仅限于消息传递或者消息传递的等价物。基于网络的系统和分布式系统之间有细微的差异,比如一个分布式系统在其消费者看来和普通的集中式系统没什么区别(只是它背后是运行在多个独立的系统之上),也就是说其背后的实现对其消费者而言是透明的。而基于网络的系统则是无需对消费者透明的,比如消费者在执行一个网络请求时,如果本地的缓存可以满足其需要,则无需执行一个真正的网络请求。可以简单的认为分布式应用属于基于网络应用的一个子集。当然也并不是说分布式系统就没有缓存,这只是一种很细微的差异。

应用软件 VS 网络软件:应用软件通常来说指的是包含系统中包含业务行为的那部分功能。而网络软件的目的通常来说是关注与如何把数据跨越网络传递到另外一个地方,其关心的是如何传输,而不关心为何要传递这些数据。应用软件是对整个系统的一个抽象,比如用户执行一个动作,这个动作中会包含如何获取数据,执行网络请求和对请求结果进行呈现,而网络传输则是其中的一个环节。

3 基于网络应用的关键架构属性

REST关注的是基于网络的应用软件的架构设计,这也正是Web的诉求,Web是一个互联网规模的分布式超媒体系统,互联网规模意味着无法控制的可伸缩性和组件的独立部署。那么如何评估一个软件架构是否满足Web的需求,把它实现出来看一下?不现实吧。比较可取并且可行的办法就是利用上面所介绍到的架构属性来和Web的需求目的进行比较:首先是要满足功能性的要求,如果一个架构连基本的功能性需求都满足不了,评估对于它来说就没什么意义;其次则是非功能性的属性,这也是评估的主要关注点。下面列举下基于网络的应用的关键架构属性。

3.1 性能

性能这个话题或许是计算机行业永远也绕不开的话题。基于网络的应用的性能首先取决于应用的需求,然后是所选择的交互风格,接下来是实现的架构,最后则是每个组件的实现细节。换句话说,应用软件无法回避为了实现该软件的需求而付出的基本成本。比如说软件需要的数据位于系统A,并由系统B来处理,那么该软件就无法避免的要把数据从系统A移动到系统B(好比你要访问数据库,这部分网络开销是无论如何也绕不过去的)。无论架构怎样优秀,网络的速度再快,也不可能比直接在系统A处理要快。

  1. 用户感知的性能:用户的一个动作从发出,到其得到响应的时间,其主要有两个衡量指标,延迟和完成时间。比如打开一张图片,一边下载一边显示和等下载完后再显示,对于用户感知的性能是有明显的区别的。
  2. 网络性能:通常来讲,网络性能指的的网络传输的吞吐量以及其支撑这些吞吐量所产生的开销。
  3. 网络效率:一个有趣的现象是,最佳的应用性能通常时通过不使用网络而获得的。这也就是说,对于一个基于网络的应用来说,把对网络的使用降低到最少,才是最高效的架构风格。

3.2 可伸缩性

可伸缩性是可以通过配置来改变一个架构中的大量的组件之间的交互的能力。可以通过简化组件、去中心化、以及通过监视获得的信息来对交互进行配置和控制。

3.3 简单性

乍看之下这个架构属性有点笼统,其实也不然。比如http的无状态性特点,就使得服务器端的实现简单化,不用去保存或者恢复上一次的http请求,也使得中间的各个组件和连接器可以独立的理解单次请求的语义。通过对组件实施分离关注点原则,可以获得简单性;通过实施通用性原则,也可以提高简单性。

3.4 可修改性

可修改性指的是对于应用的架构做出改变的容易度。即使创造出了一个完全满足用户需要的系统,用户需求也总是会变化的,唯一不变的事情就是变化本身。基于网络的应用中的组件跨越了网络。比如系统中的一些组件难免的会升级为新组件,系统需要能面对新旧共存的局面等等。可修改性可以做如下更细节的划分:

  1. 可进化性:指一个组件改变了内部实现而不会对其他组件产生负面影响的程度。
  2. 可扩展性:指可以把一个新功能添加到系统中的能力。动态扩展性则是指将功能添加到一个已部署的系统中,而不会影响到系统中的其他部分。
  3. 可定制型:指临时性的规定一个架构元素的行为的能力。如果一个组件的客户端能够扩展该组件的服务,而不会对其他客户端产生影响,则该组件就是可定制的。
  4. 可重用性:指一个应用软件中的组件、连接器和数据元素能够不做修改的在其他应用重用。

3.5 可见性

可见性指的是一个组件对于其他组件之间的交互进行监视或者进行中间周旋的能力。拥有了可见性之后,就可以通过共享缓存来改善性能、通过分层来改善可伸缩性、通过允许中间件(比如防火墙)对交互做出检查来改善安全性、通过监视来改善可靠性等。

3.6 可移植性

指的是软件在不同的环境下运行的能力。比如那些将代码和代码处理的数据放在一起移动的架构风格可以获得此架构属性,比如虚拟机风格、移动代理风格,以及那些限制只能使用标准格式的数据元素的架构风格。

3.7 可靠性

从应用软件的角度来看,可靠性是在组件、连接器和数据之间出现部分故障时,一个架构受影响的程度。通过避免单点故障、增加冗余、系统监视等方法来改善可靠性。

4 总结

本篇主要介绍一组如何描述软件架构的自洽的术语,以及对于基于网络的应用来说,哪些架构属性是值得我们关注的。本篇均是笔者自己的一些理解,不免有错误之处,欢迎指正。

参考资料

理解本真的REST:http://www.infoq.com/cn/articles/understanding-restful-style/

架构风格与基于网络的软件架构设计-导读:http://www.infoq.com/cn/articles/doctor-fielding-article-review

架构风格与基于网络的软件架构设计:http://www.infoq.com/cn/minibooks/web-based-apps-archit-design

Architectural Styles and the Design of Network-based Software Architectures:https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/394052.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js判断对象还是数组

1.对于Javascript 1.8.5(ECMAScript 5),变量名字.isArray( )可以实现这个目的 var a[]; var b{}; Array.isArray(a);//true Array.isArray(b)//false 2.如果你只是用typeof来检查该变量,不论是array还是object,都将返回…

mysql 除去列名打印_sql – 使用beeline时避免在列名中打印表名

在beeline中使用hive时使用简单的select查询我想在列名中返回没有表名的表作为默认值.例数据CREATE TABLE IF NOT EXISTS employee ( eid int, name String,salary String, destination String)COMMENT Employee detailsROW FORMAT DELIMITEDFIELDS TERMINATED BY \tLINES TERM…

移动应用程序和网页应用程序_如何开发感觉像本机移动应用程序的渐进式Web应用程序...

移动应用程序和网页应用程序by Samuele Dassatti通过萨穆尔达萨蒂 如何开发感觉像本机移动应用程序的渐进式Web应用程序 (How you can develop Progressive Web Apps that feel like native mobile apps) I’m currently developing a Progressive Web App that will also ser…

leetcode1162. 地图分析(bfs)

你现在手里有一份大小为 N x N 的「地图」(网格) grid,上面的每个「区域」(单元格)都用 0 和 1 标记好了。其中 0 代表海洋,1 代表陆地,请你找出一个海洋区域,这个海洋区域到离它最近…

mysql修改root密码的方法

在 Navicat for MySQL 下面直接执行 SET PASSWORD FOR rootlocalhost PASSWORD(newpass); 就可以 方法1: 用SET PASSWORD命令 mysql -u root mysql> SET PASSWORD FOR rootlocalhost PASSWORD(newpass); 方法2:用mysqladmin mysqladmin -u root …

android 上下偏差怎么写_详解 Android 热更新升级如何突破底层结构差异?

知道了 native 替换方式兼容性问题的原因,我们是否有办法寻求一种新的方式,不依赖于 ROM 底层方法结构的实现而达到替换效果呢?我们发现,这样 native 层面替换思路,其实就是替换 ArtMethod 的所有成员。那么&#xff0…

Python3 Flask+nginx+Gunicorn部署(上)

前言:一般在本地运行flask项目通常是直接python3 文件名.py,然后打开:http://127.0.0.1:5000 查看代码结果 这次主要是记录flask在python3 环境结合nginx gunicorn在服务器上进行项目的部署 (一)运行环境:虚…

NOIP2011 铺地毯

题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯,一共有n张地毯,编号从 1 到n。现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设&…

java lock可重入_Java源码解析之可重入锁ReentrantLock

本文基于jdk1.8进行分析。ReentrantLock是一个可重入锁,在ConcurrentHashMap中使用了ReentrantLock。首先看一下源码中对ReentrantLock的介绍。如下图。ReentrantLock是一个可重入的排他锁,它和synchronized的方法和代码有着相同的行为和语义&#xff0c…

matlab的qammod函数_基于-MATLAB下的16QAM仿真.doc

1.课程设计目的随着现代通信技术的发展,特别是移动通信技术高速发展,频带利用率问题越来越被人们关注。在频谱资源非常有限的今天,传统通信系统的容量已经不能满足当前用户的要求。正交幅度调制QAM(Quadrature Amplitude Modulation)以其高频…

POJ3264 【RMQ基础题—ST-线段树】

ST算法Code&#xff1a; //#include<bits/stdc.h> #include<cstdio> #include<math.h> #include<iostream> #include<queue> #include<algorithm> #include<string.h> using namespace std; typedef long long LL;const int N5e410;…

leetcode199. 二叉树的右视图(bfs)

给定一棵二叉树&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。示例:输入: [1,2,3,null,5,null,4] 输出: [1, 3, 4] 解释:1 <---/ \ 2 3 <---\ \5 4 <---解题思…

开发人员工作周报_如何增加找到开发人员工作的机会

开发人员工作周报In a recent job as a senior developer, I helped interview and hire many of my employer’s development team members. This is a brain dump of my advice based on those interviews.在最近担任高级开发人员的工作中&#xff0c;我帮助面试和雇用了许多…

安全专家教你如何利用Uber系统漏洞无限制的免费乘坐?

本文讲的是安全专家教你如何利用Uber系统漏洞无限制的免费乘坐&#xff1f;&#xff0c;近日&#xff0c;根据外媒报道&#xff0c;美国一名安全研究人员发现Uber上存在一处安全漏洞&#xff0c;允许发现这一漏洞的任何用户在全球范围内免费享受Uber乘车服务。据悉&#xff0c;…

flume介绍

flume 1.flume是什么 Flume:** Flume是Cloudera提供的一个高可用的&#xff0c;高可靠的&#xff0c;分布式的海量日志采集、传输、聚合的系统。** Flume仅仅运行在linux环境下** flume.apache.org(Documentation--Flume User Guide) Flume体系结构(Architecture)&#xff1a; …

threadx 信号量 应用_操作系统及ThreadX简介.ppt

操作系统及ThreadX简介操作系统及ThreadX简介 软件二部 2006.09 主要内容 多任务操作系统概述 ThreadX简介 关于驱动的交流 操作系统概述 什么是操作系统 管理计算机的所有资源&#xff0c;并为应用程序提供服务的最重要的系统软件 操作系统的目的 为用户编程提供简单的接口&am…

java中同步组件_Java并发编程(自定义同步组件)

并发包结构图&#xff1a;编写一个自定义同步组件来加深对同步器的理解业务要求&#xff1a;* 编写一个自定义同步组件来加深对同步器的理解。* 设计一个同步工具&#xff1a;该工具在同一时刻&#xff0c;只允许至多两个线程同时访问&#xff0c;超过两个线程的* 访问将被阻塞…

maven学习资料

maven学习资料maven学习教程&#xff1a;What、How、Whyhttp://www.flyne.org/article/167Maven 那点事儿 https://my.oschina.net/huangyong/blog/194583项目管理工具&#xff1a;Maven教程http://www.flyne.org/article/884转载于:https://www.cnblogs.com/zhao1949/p/634641…

leetcode127. 单词接龙(bfs)

给定两个单词&#xff08;beginWord 和 endWord&#xff09;和一个字典&#xff0c;找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则&#xff1a; 每次转换只能改变一个字母。 转换过程中的中间单词必须是字典中的单词。 说明: 如果不存在这样的转换序…

算法之旅 | 快速排序法

HTML5学堂-码匠&#xff1a;前几期“算法之旅”跟大家分享了冒泡排序法和选择排序法&#xff0c;它们都属于时间复杂度为O(n^2)的“慢”排序。今天跟大家分享多种排序算法里使用较广泛&#xff0c;速度快的排序算法—— 快速排序法 [ 平均时间复杂度为O (n logn) ]。Tips 1&…