当前课程知识点:软件工程 >  第11章 软件系统设计 >  11.7 Web系统架构设计 >  讲授视频

返回《软件工程》慕课在线视频课程列表

讲授视频在线视频

下一节:讲授视频

返回《软件工程》慕课在线视频列表

讲授视频课程教案、知识点、字幕

我们知道近年来Web发展非常迅猛

而它的发展带来了大量机会

经过多年的检验

客户端、服务器这种

C/S结构一直是非常适用的

这个结构里面将前后端分离开来

后端,或者说服务端

现在应用最普遍的

就是HTTP服务器

为了更好地进行开发工作

后端服务器发展出了

MVC和其他架构

前端,或者说客户端

经过发展

有种浏览器一统天下的感觉

浏览器、微信之类

带浏览器的客户端

可以作为通用客户端

他们做的就是借助HTML

CSS、JS等前端手段

完成客户端的呈现和交互

因为前端的迅猛发展

也出现了前端MVC之类的

前端架构来提高前端开发的质量

此外还有现在非常流行的各种App

我们可以把它看做是专用客户端

所以我们看到

Web系统的架构

无非就分为前端和后端

那细化来说

应该怎么设计Web系统的架构呢

我们先回顾一下HTTP服务器的原理

从HTTP协议的规定来说

客户端向服务器发起请求

服务器上的服务器程序收到请求后

对请求进行解析

然后处理

完成后向客户端返回响应

当然

这个过程中的数据流传输

必须依照HTTP协议的规定

比如

我们用Python

写一个非常简单的HTTP服务器

它监听在本机的8000端口

所有的请求传递给

SimpleHttpRequestHandler去处理

数据流的解码

编码在BaseHTTPServer里面都做掉了

这个服务器程序

相当于就是把你的当前工作目录

映射到localhost的8000端口

让它可以通过HTTP请求

访问到程序的工作目录

当客户端

比如浏览器

向我们的这个服务器程序发起请求后

首先它会经过

BaseHTTPServer进行简单的解码

然后交给

SimpleHTTPRequestHandler进行处理

完成后写入数据流

就成为了这个HTTP请求的响应

所以我们看到

BaseHTTPServer里面做的就是

监听在固定的端口然后接收HTTP请求

接着对HTTP请求进行简单解码和解析

最后去调用RequestHandler

而在SimpleHttpRequestHandler里面

做的其实就是业务逻辑的实现

这个例子里面的业务逻辑

就是要读取请求的相应文件

或者目录的内容

完成业务逻辑处理后

就可以写入HTTP响应了

我们发现

其实这边做的业务逻辑是很简单的

如果业务逻辑复杂的话

该怎么办

这时候就很有必要引入服务器架构

有了服务器架构之后

开发人员就可以更好地

关注在业务逻辑的处理上

可想而知就可以更好地

处理更复杂的业务逻辑

HTTP后端服务器的架构有很多种

我们举个例子

比如MVC设计的后端

这样的架构中

HTTP请求一般会先经过router

或者说路由

它决定要把请求交给

哪个具体的Controller去处理

具体的Controller收到请求后

根据业务逻辑的需要

它可能需要与数据库进行交互

比如存取相关的数据

这些操作都交给Model层去做

这样在Model层的辅助下

Controller完成了业务逻辑的处理

它会把自己的处理结果交给View层

View层收到处理结果后

就据此向客户端以响应

为了追求便利

后端服务器的View层会去渲染模板

比如HTML模板

甚至CSS模板和JS模板

最后的HTTP响应

当然就是由View层完成的了

其实这边的View层是很有问题的

因为在这里前后端发生了耦合

这就会给开发和维护带来更多困难

前面说的View层前后端耦合的本质是

前端的代码交给后端去通过模板来渲染

要解决这个问题

我们可以让后端成为RESTful的API

因为前端的发展

如果还把前端模板放在后端服务器上

带来的困难程度远比以前高得多

所以

我们把前端模板从后端服务器剥离出来

这样后端就可以专注于业务逻辑的处理

RESTful的API说白了

就是充分利用具体的四种HTTP请求

包括GET、PUT、POST和DELETE

客户端向服务器端发起请求

比如GET /activity/list

以前后端服务器程序

会给客户端返回对应的网页

但在RESTful的后端服务器

返回的不是具体网页

而是特定格式的响应

比如JSON格式

XML格式之类的都可以

为了更好地

让前端反应后端的出错情况等

可以让返回的响应中增加特定的字段

比如code表示错误代码

message代表错误信息

我们前面访问的GET /activity/list

返回code=0代表没出错

实际应该返回的数据在data字段里

返回的是一个数组

每个元素都是一个object

里面有对应活动的信息

这样

实际上后端向前端返回的响应

就精简了非常多

以前需要返回整个网页

现在只需要返回前端需要的信息了

更大的好处是

可以完全把前端分离出来

也就是说

前端的开发可以先不依赖后端进行

然后用很小的代价

就可以完成前后端的衔接

有了这样RESTful API的后端

后端通信就可以在Web页面上

充分利用Ajax的特性

不仅带来更好的用户体验

还让前后端更好地分离

而且

这样的后端对App等

专用客户端也是通用的

在专用客户端发起HTTP请求

照样可以拿到需要的后端数据

真是一举多得

接下来的问题就在于

我们的Web页面服务要如何进行部署

对于Web页面而言

我们必须让前后端

能通过同一个域名的

同一个端口访问到

否则会出现跨域的问题

跨域的问题主要是说

我们不能用Ajax在一个域名的页面上

获取另一个域名

或者另一个端口提供的数据

因为这样会非常不安全

所以我们必须把前端页面

和后端的RESTful API

部署在相同域名的相同端口上

解决办法就是通过Nginx之类的

Web服务器托管我们的前端和后端

举个例子

我们把nginx绑定在服务器的80端口上

客户端请求80端口

会被nginx收到

根据请求的不同

nginx直接把前端文件内容

返回给客户端

或者通过端口转发

或者管道文件

把请求转发给我们的RESTful后端

后端响应后

nginx再把响应返回给客户端就可以了

值得一提的是

借助nginx

我们可以有多个RESTful后端

同时用同一个域名的

同一个端口提供服务

只要在nginx配置里

设置好相应的路由就可以了

我们已经通过RESTful API解决了

前后端难以分离开发的问题

同时还通过这个解决方案

带来了更好的用户体验

和更灵活的部署方式

但有时候我们会遇到这样的问题

因为HTTP请求是同步的

所以当它在服务器上响应之后

为了避免系统的复杂性

我们就不应该再做别的事了

而且浏览器

一般对HTTP请求有超时的限制

比如

假设我们开发了一个

自动根据用户上传的图片

进行人脸识别

并进行复杂分析的服务

每张图片经过优化以后

还需要处理1分钟

但一个HTTP请求

在浏览器限制30秒内必须响应

这种情况下

我们就不得不把图片的处理

变成一个异步的服务

所谓异步的服务

一般是以异步任务的方式呈现的

比如我们的服务器程序收到了一个请求

可以告诉任务的管理程序

说需要启动一个任务

管理程序说好呀

然后返回一个任务id

服务器程序就可以马上把任务id

作为响应返回给客户端了

而我们的管理程序

一般会在返回任务id之后

再去启动任务

这样

客户端程序就可以通过任务id

询问任务的进展情况

比如任务正在运行

或者任务成功了

或者任务失败了

如果任务成功了,我们也可以得到任务的响应

如果任务失败了,我们也可以得到任务的错误信息

这样就很好地

用异步的方式解决了问题

更棒的是我们可以设定一些定时器

让一些任务

可以在设定的时间自动启动

比如自动发邮件之类的

要实现异步任务

借助于现成的成熟框架

可以很容易做到

这里简单介绍

一个异步任务队列框架celery

借助于它

我们既可以实现定时任务

也可以实现异步任务

当然

定时任务

我们也可以通过操作系统的

cronjob之类的来实现

nodejs是

可以借助它本身异步的特点

来做异步任务的

但是非常非常不推荐这样做

因为自己实现的往往难以管理

而且很容易出错

借助于celery之类的

异步任务队列

不仅可以给我们

带来异步服务的好处

还为系统的规模化

提升带来了额外的增益

因为celery本身

就是一个分布式的任务队列

这样可以把异步任务

分配到服务器集群去处理

借助集群的力量

以很快的速度消化掉大量异步任务

我们知道计算机体系结构里面

划分了七个存储层级

其中网络访问是在最低层级

数据库往往是在硬盘层

要实现系统的更好性能

我们可以利用缓存的思想

把经常访问

但不经常变化的数据

放到上一层存储层级

也就是放到内存去

这样借助内存缓存

我们就可以提高Web访问的速度

为了实现内存缓存

我们可以借助内存型数据库来实现

内存型数据库

往往比传统数据库简单不少

比如redis、memcached

都是典型的Key-Value键值对存储

它们的一个用途就是作为缓存使用

比如假设我们发现

一个获取activity信息的

RESTful API的访问

平均耗时要500毫秒左右

但它在大多数情况下

返回的都是相同的结果

我们就可以把它的处理结果存入redis

再次访问的时候

直接从redis里取出结果

平均耗时就可以降低到100毫秒以内

这里需要特别注意缓存的过期机制

比如修改了activity后

记得删掉前面说的那个缓存

或者在

一些对实时性要求不那么高的场景下

我们可以直接简单粗暴

给缓存设置固定的过期时间

比如一小时或者一天

这样在系统访问频繁的时候

通过缓存可以有很好的性能表现

系统访问不频繁的时候

也可以让系统的负载适当均衡

回顾一下

我们可以通过合理的资源配置

可以让有限的机器发挥更大的价值

遵照RESTful的后端服务

能让我们前后端开发更容易配合

异步任务机制让我们能提供复杂的服务

而且可以弹性伸缩

而缓存机制

让我们的服务响应速度大大提高

而nginx

支持将请求转发至不同的端口

管道文件,甚至不同的机器

这也大大提高

我们整个软件系统的性能和扩展性

同学们可以想一想

在一些具体的应用场景下

比如我们如果要开发一个

用抢票的方式发放活动票的系统

该如何设计架构

才能在保证正确性的前提下

尽可能榨干服务器全部性能

软件工程课程列表:

第1章 初识软件工程

-1.1 软件无处不在

--讲课视频

-1.2 软件的本质特性

--讲授视频

-1.3 软件工程的产生与发展

--讲授视频

-1.4 软件工程的基本概念

--讲授视频

-1.5 软件质量实现

--讲授视频

-1.6 业界人士谈软件工程

--海芯科技创始人施侃乐访谈

-测验题--作业

-讨论题

--讨论题

-作业题

--第一张 作业题

第2章 编写高质量代码

-2.1 编程过程与规范

--讲课视频

-2.2 良好的编程实践

--讲课视频

-2.3 Python集成开发环境

--讲课视频

-2.4 代码静态检查

--讲课视频

-2.5 代码性能分析

--讲课视频

-2.6 结对编程实践

--讲课视频

-2.7 刘贺谈软件工程

--讲课视频

--讨论

-测验题--作业

-作业题

--第二章 作业题

第3章 单元测试

-3.1 单元测试概述

--讲课视频

-3.2 黑盒测试方法

--黑盒测试方法

-3.3 白盒测试方法

--基本概念

--代码覆盖标准

--基本路径测试

-3.4 单元测试工具

--单元测试工具

--html

-测验题--作业

-作业题

--第三章 作业题

--作业题附件

第4章 软件开发过程

-4.1 软件过程

--讲课视频

-4.2 软件过程模型

--讲课视频

-4.3 敏捷开发过程

--讲课视频

-4.4 微软公司开发过程

--邹欣经理自我介绍

--微软开发过程之一

--微软开发过程之二

-测验题--作业

第5章 团队开发管理

-5.1 团队组织与管理

--讲课视频

-5.2 项目沟通管理

--讲课视频

-5.3 软件项目计划

--讲课视频

-5.4 软件项目估算

--讲课视频

-测验题--作业

-讨论题

--讨论

第6章 敏捷开发与配置管理

-6.1 敏捷开发之Scrum

-- 敏捷开发之Scrum

--html

-6.2 用户故事与估算

--讲课视频

-6.3 团队协作工具Tower

--Tower工具介绍(1)

--Tower工具介绍(2)

-6.4 配置管理

--讲课视频

-6.5 配置管理工具Git

--讲课视频

-测验题--作业

-作业题--作业

第7章 需求获取

-7.1 需求工程师

--讲课视频

-7.2 需求定义

--讲课视频

-7.3 需求的类型

--讲课视频

--讲课视频(2)

-7.4 需求工程过程

--讲课视频

-7.5 需求的主要来源

--讲课视频

-7.6 需求获取技术

--讲课视频

--讲课视频二

--讲课视频三

-7.7 撰写需求文档

--讲课视频

-测验题--作业

-讨论题

--讨论

第8章 用例建模

-8.1 用例建模概念

--讲课视频

-8.2 用例建模过程

--讲课视频

-8.3 用例建模精讲

--讲课视频

-8.4 建模工具介绍

--讲课视频

-8.5 微信抢票应用案例

--讲课视频

-测验题--作业

-讨论题

--讨论

第9章 面向对象分析与设计

-9.1 面向对象分析

--讲课视频

-9.2 CRC卡片分拣法

--讲课视频-1

--讲课视频-2

-9.3 面向对象设计

--讲课视频-1

--讲课视频-2

-9.4 类图建模

--讲课视频-1

--讲课视频-2

-第9章 面向对象分析与设计--测验题

-讨论题

--讨论

第10章 行为建模

-10.1 顺序图概念

--讲课视频

-10.2 顺序图建模

--讲课视频

-10.3 顺序图风格

--讲义视频

-10.4 状态建模

--讲课视频

-10.5 状态图

--讲课视频

-10.6 状态图精讲

--讲义视频

-测验题--作业

-讨论题

--讨论

第11章 软件系统设计

-11.1 软件体系结构概念

--讲授视频

-11.2 软件设计原则

--讲授视频

-11.3 软件体系结构风格(一)

--讲授视频

-11.4 软件体系结构风格(二)

--讲授视频

-11.5 软件体系结构风格(三)

--讲授视频

-11.6 软件设计过程

--讲授视频

-11.7 Web系统架构设计

--讲授视频

-11.8 数据库选择策略

--讲授视频

-测验题--作业

-作业题

--html

--html

--html

-作业题--作业

第12章 软件交互设计

-12.1 交互设计概述

--讲授视频

-12.2 交互设计目标

--讲授视频

-12.3 GUI设计原则

--讲课视频

-12.4 KLM效率模型

--Video

-12.5 Fitts定律

--讲授视频

-12.6 交互设计过程

--讲授视频

-测验题--作业

第13章 软件系统测试

-13.1 软件测试概念

--讲课视频

-13.2 软件测试类型

--讲课视频

-13.3 软件功能测试

--讲课视频

-13.4 软件性能测试

--讲课视频

-测验题--作业

第14章 软件交付与维护

-14.1 软件部署与交付

--讲课视频

-14.2 软件演化与维护

--讲课视频

-测验题--作业

第15章 期末考试与总结

-第一部分:基础知识

-第二部分:编程与测试(选做)

--编程与测试(选做)

讲授视频笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。