经济文库 - 千万精品文档,你想要的都能搜到,下载即用。

part 1- 微服务与云计算概述(1) 2020.pdf

〆Nancy ゛╮゛105 页 2.594 MB 访问 612.97下载文档
part 1- 微服务与云计算概述(1) 2020.pdfpart 1- 微服务与云计算概述(1) 2020.pdfpart 1- 微服务与云计算概述(1) 2020.pdfpart 1- 微服务与云计算概述(1) 2020.pdfpart 1- 微服务与云计算概述(1) 2020.pdfpart 1- 微服务与云计算概述(1) 2020.pdf
当前文档共105页 2.97
下载后继续阅读

part 1- 微服务与云计算概述(1) 2020.pdf

MicroService and Cloud Computing 微服务与云计算 信息科学与工程学院 软件工程系 杨金民 2020/09 1 1. 时代背景 —— 滚滚向前 IT迅猛发展,节奏飞快,连马云都感叹:“大家还没搞清PC 时代的时候,移动互联网来了;还没搞清移动互联网的时候, 大数据时代又来了;还没搞清大数据的时候,AI时代又来了” 2 时代背景 —— 战线漫长 专业知识的学习,战线快速拉长,啃起来艰难困苦; l 操作系统,编译原理,程序语言/设计,数据库,计算机网络; l 分布式,WEB,Cluster, 超算,云计算,大数据,AI l 架构,模式,算法,软件集成,微服务,容器; l 高性能,安全性,可用性,可扩展性,低成本性,敏捷开发性 听到和看到的,越来越笼统、抽象、泛化,给人萌萌的感觉,有 那么点意思,又啥都落不到实处 3 2. 软件技能门槛不断攀升 大数据 AI Container Integration Database Pattern Testing 云计算 Architecture 程序语言 数据结构 算法 Object-Oriented Modeling Configuration 4 概率与统计 3、软件的原著特性:函数调用 函数实现:由服务方程序员开发math.c文件。 math.c: bool __declspec(dllexport) __cdecl sin (double angle) double result; result = ......; return result; } 编译,链接,生成math.dll { 库函数的发布 函数定义:以头文件math.h 方式发布给客户; math.h 文件: bool __declspec(dllimport) __cdecl sin ( double angle); math.dll 客户程序:调用别人提供的函数 client.c Client.c: include “math.h” main( ) { double angle =3.14/ 5; double value = sin(angle); return value; } 编译,并和math.dll 链接,生成client.exe 应用程序的加载执行 在桌面双击一个可执行文件(exe文件)时, 就执行事件处理函数: 创建(fork)一个进程,即得到了一个虚拟地址空间,随后的工作就 是由加载器Loader把exe文件从磁盘加载到进程虚拟地址空间,然 后检查exe文件的import table部分,看它依赖于哪些dll文件,然 后加载这些dll文件,以此类推,直至所有需要的dll文件都加载完 毕。然后去找到main函数的地址,调用它,把执行交给应用程序。 4、 理解软件 —— 逻辑与物理(1) l 编程是基于逻辑概念,表达逻辑关系,千万不要引入物理概念; l 软件因实例而生,但设计开发要超越实例,实现通用,超越专 用;设计开发 与 部署安装; l 只有软件运行时,即安装部署时,才考虑物理概念; l 类(概念)与实例,抽象与具体,逻辑与物理,归纳与分析; l 程序中最好不要出现常量,常量都要变成配置参数; 9 举例:对URI的认识 URI,例如,湖南大学教务系统的登录界面是: www.hun.edu.cn/jwxt/login.php; 其实,这个URI包含了物理概念和逻辑概念两个方面, www.hun.edu.cn/jwxt/表达的是物理概念,即位置; 而login.php表达的是逻辑概念,表达的登录这一逻辑功能; 程序代码: HttpRequest('www.hun.edu.cn/jwxt/login.php', name, password); HttpRequest('login.php', name, password); 哪个好? 10 编程的一个重要方面 编程的水平体现在:能否识别出物理概念和逻辑概念。如果不做分 离,编写出来的程序就是硬硬邦邦的,没有适应性; 如果做了分离处理,那么程序表达的是逻辑概念,具有通用性。物 理概念变成了运行时的配置参数,在安装部署时设定。于是程序开 发出现了分化,分离成了逻辑(编程设计)和物理(安装部署)两个部 门; 一个应用程序要卖给多个用户。同一个应用程序,不同的用户有不 同的使用场景。为用户安装部署一个应用程序,要基于它的使用场 景来进行配置参数设定。 11 物理概念和逻辑概念的区分例子 微信小程序/小游戏/公众号在逻辑概念和物理概念的识别上, 处理得非常好。物理概念都变成了应用程序的配置参数,放 在项目的.json文件中; 程序只表达逻辑,例如: HttpRequest('login.php', name, password); 12 理解软件 —— 语法 + API(2) 在函数中调用函数,体现出:C/S性,迭代性,牵扯交织性; 函数B 函数A 函数C 问题:会出现环吗? 13 理解软件 —— 模块/组件化(3)   β B A A 同类相似产品 应用于不同场景 14 可组装性。想想哪些东东是可组装的?哪些是整体性的? 组装是开发问题?还是安装部署问题? 模块的可嵌插性 逻辑与物理的分离: α调用I 1 ,链接时与A.dll链接。 B同样提供I 1 ,因此,安装部 署时,可偷梁换柱,用B替换  A  I1 B A 掉A。只须把B.dll改名为A.dll。 为防止名字冲突,B在链接时, 将A.dll改名为C.dll, B在链接 时改成与C.dll链接。 15 可嵌入性 理解软件 —— 归纳共性/抽象化和重定向(4) 打印时, 可输出到: l 打印机; l PDF pI1 pI2 A B I l 传真机; l 打印预览; 文件,网络,画布等等, 都是call API: 保存时也可重定向; 16 HANDLE CreateFile(); 协议栈 SOAP SMTP POP FTP HTTP UDP 可组装性 同级产品 TCP IP Mobile 蓝牙 WLAN LAN 17 从编程角度来看,操作系统是什么? 操作系统就是操作系统厂商给定的一套API,及库文件; 操作系统API API1 API2 kernel32.DLL API3 APIn user32.DLL gui32.DLL 每种操作系统都有一套自己的API,彼此不同; 基于操作系统API编写的应用程序,没有通用性; 于是提出了POSIX 18 什么是基础平台?Windows平台为例 Web service .NET library MSCorEE.DLL COM library OLE32.DLL MFC library Mfc**.DLL C runtime library mscrt40.DLL OS API kernel32.DLL user32.DLL gui32.DLL 5. 微服务例子 20 微服务例子(cont. No.1: 扩展) 21 微服务例子(cont. No.2: 提取共性) 22 微服务例子(cont. No.3: 整理) 23 微服务例子(cont. No.4:自动化运维) 24 从其它行业来联想云计算 l 每个村子都打一口深井,给全村各户供水; l 有了管道技术,用水管把各村的水井联接起来; l 把水井改成水库,用管道按级,以树状结构辐射到家家户户; l 水库之间也用管道联接起来,建立供水联盟; 25 从其它行业来联想云计算(2) l 每家买个柴油发电机,要用电就启动,给自家供电; l 有了电线输电技术,用电缆把整个村子联接起来,供电; l 把柴油发电机改成发电厂,用电缆按级,以树状结构辐射到家 家户户; l 发电厂之间用电网联接起来,形成电网供电; 经济性,方便性(随时随地),可靠性,稳定性 标准性,专业性,辐射性 26 云计算 大系统:属于特定企业,面向客户,提供业务服务。展示出的特 性:利用群聚和聚约效应,取得高性能,高安全,高可用,高吞 吐量,可扩展,低成本,自适应。 大系统:自动化控制十分关键。例如,轮船,大飞机,电网,电 站; 特点:庞大:体量,容量,吞吐量,客户量,不间断服务,安全, 可靠,低成本。对客户而言,只有逻辑概念,无物理概念; 27 对群体规模的再认识 乡村公交 vs 市内公交: l 发车频率: 小时级 vs 分钟级; l 价格: 贵 vs 便宜; l 车上乘客: 时多时少,波动大 vs 多,波动小; 基数和密度 : 随机性  稳定性 28 个体活动规律特征 对于学生: l 天天去教学楼,食堂,宿舍; 校内交通; l 约一个星期,去一趟市内; 市内交通; l 约一个学期,来一次国内长途旅行; 长途交通; l 约几年,来一次国际旅行; 国际交通; 正因为如此,学校就成了组织模块,也就是说,把频繁联系/关系 非常紧密的东西临近部署构成 模块。市内交通,长途交通则又是 另外的模块; 29 个体与群体 —— 量变到质变 l 对于一个人来说,一年当中,都只偶尔去两三趟火车站 vs 但 是无论你什么时候去火车站,都会发现那里旅客人山人海; l 尽管坐公交的频度高,但关闭一个市内公交站,影响很小;尽 管坐火车的频度低,但关闭一个火车站,影响则很大;  大型服务器,其可靠性/可用性非常重要; 30 对大型服务的认识 组织与结构,非常重要; 原则: 把关系紧密的东西临近部署:内聚; 模块/微服务之间,则相互独立,但又可交互协同; 又是辩证法:内聚 vs 独立 对于腾讯会议,它具有什么特征?该如何组织?该采取 怎样的结构?如何来设置? 31 服务器 vs 桌面机 l 高性能,不间断在线 vs 用时才开机; l 无人机接口 vs 有人机接口(显示器,键盘,鼠标); l 服务程序 vs 人机交互程序; l 并发多任务/服务 vs 人机交互多应用,单任务; l 用户因时而异 vs 用户不变; l 执行的任务因时而异 vs office/browser/专业软件; l 要求因时而异 vs 要求不变;指安全性、性能,资源; 32 6. 软件集成,实例之一 微信中的”发送位置”功能,如图所示。 将地图功能集成在微信中; 可在微信中操作地图: 获取位置,放大,移动; 特点:在微信开发时进行集成。 33 软件集成,实例之二 WPS中打开文件和保存文 件时,打开的对话框中,集 成了“云文档”的打开和保存 功能,如图所示。 特点:对已有的软件进行集 成。即插件。 34 软件集成,实例之三 在浏览器中打开一 个含视频的网页时, 在浏览器中播放视 频; 特点:浏览器中集 成播放器。实时集 成,即下载插件, 然后安装使用。 35 软件集成,实例之四 在浏览器中,集成富文本编辑控件; 36 软件集成,实例之五 在浏览器中打开的某个网页中,点击“上传文件”,打开的界面 如上图所示。这些界面其实是Windows中的控件,被集成到了 浏览器中; 37 什么叫软件系统集成:三种表现形式 l 对新软件开发,在开发时进行集成,采用构件组装模式来开发。 调用构件提供的接口进行操作。 l 对已有的软件,可补装插件来扩充功能:并不须要在源程序级来 作修改;而是对二进制可执行应用程序补装二进制可执行插件; l 软件自动化:例如web应用编程中生成word,excel文件; 38 7. 应用程序的类别 企业给其用户(员工,客户)使用的业务软件。例如,word和 excel,教务系统,电商系统,QQ和微信,新闻网; 分类: l 数据私有:例如word和excel。个人使用,处理个人数据; l 数据共享:员工系统,例如,教务系统;特点:用户标识/登录 客户系统,从业务特性,分浏览性客户和实体性客户 浏览性客户:例如新闻网,目标:赚取知名度和影响力; 实体性客户:为了特定的业务,例如电商系统,订票系统; 39 应用程序的类别(cont.) 对于企业员工使用的业务系统,例如教务系统,并不须要基于微 信来开发。因为基于微信的开发,主要是想要借助微信传播,触 及潜在客户。对于面向员工的业务系统,员工知道并经常要使用。 这种业务系统,通常在企业的内部局域网中使用,使用http访问。 因为没有加密传输,为了安全起见,在企业出口网关的防火墙中 设置,拦截从外部对业务系统的访问。 当要扩展成基于互联网使用时,外部用户要么通过VPN访问,以 穿透防火墙。要么改造web服务器,支持https访问。这两种方式 其目标都是安全传输。 40 经典类应用程序:APP类(第一类) l APP: 某种机器和操作系统下面的二进制可执行文件; 操作系统: windows 32, 64,,Linux,Andriod,MacOS; l 优点:安装在用户机器上,可离线运行。用户体验好; l 缺点:开发、更新、升级都复杂,成本高; 基于操作系统无关的编程:使用高级程序语言和国际标准API编写 应用程序,一次性编程,然后为不同的操作系统,分别编译链接, 生成相应二进制可执行文件; 基于操作系统相关的编程:使用高级程序语言和操作系统专有的 API编写应用程序。对每种操作系统都要编程一次。比如对 Andriod的开发,对Apple的开发; 41 APP类应用程序 lAPP适应于那些用户使用频率高的应用,例如, office, 开发工具,浏览器,编辑器,媒体播放 器,这些应用程序通常采用APP这种方式开发。 42 WEB类应用程序(第二类) (前提是有WEB标准) • 优点: 与用户的机器和操作系统无关,一次性开发;因此,开 发、更新、升级简单,只要修改服务器一处即可; • 缺点:用户每次使用,都要从服务器上去实时读取,依赖网络, 时延大,常出现白屏等待现象,用户体验差; 适应于那些用户不常使用,但须要随处使用的应用,以及数据 需要集中管理和共享的应用,如,信息管理系统,订票系统。 另一优点: 能跟踪和控制用户,于是也能刻画用户;还能刻画 所有用户,对其分类,服务于决策分析; 43 微信小程序在现有基础上所做的创新 • 对于移动环境,WEB应用的用户体验问题变得非常突出,起因 是网络的可用性,带宽和时延; • 特点: 试图综合APP类和WEB类的优点,克服它俩的缺点; • 动机:将WEB页面分离成构成轮廓和数据两个部分。构成轮廓 部分像APP一样放在用户机器上,对数据部分,即可放本地, 也可放服务器;这样,对构成轮廓部分,用户每次使用就不须 要从服务器下载了; • 对于移动通讯,费用是按流量计算的,于是也就能节省流量。 44 创新例子:微信客户端与浏览器的关系 • 微信客户端是腾讯公司对开源浏览器(chrome)进行改造后, 得出的一个衍生APP软件; • 浏览器chrome的核心就是WEBVIEW。WEBVIEW的核心就是 将HTML和CSS文件翻译成js文件,再加上下载的js文件,然后 提交给javascript引擎执行,得出显示结果; • 从外观上来看,微信客户端取消了浏览器的标题栏,网址栏,菜 单,工具条,以及下面的状态条。 45 微信客户端 • 浏览器对每次打开的URI都从WEB服务器去下载,当然,HTML 5新增了本地缓存功能。 • 微信客户端非常强调本地缓存,主要以列表方式按时间顺序显示, 因此还强调增量更新。显示最新的,老的要用户前滚页面时才会 显示出来。 • 用户每次打开微信客户端,第一个网页,即缺省网页,就是微信 界面。因此,可以说,微信既是一个WEB应用,也是一个APP; 46 微信对浏览器的第二个创新性改造 • 将WebView的单线程,改成了双线程:渲染线程,逻辑线程; 将页面划分成了轮廓和数据。 • 当在微信客户端中打开一个Web网页时,等于是在浏览器中 打开一个网页,经常有闪屏和卡滞现象,其原因就是因为是单 线程处理。而打开微信页面或者小程序时,体验则非常流畅。 原因是双线程。 47 双线程改造带来的问题 • 双线程模式下,要求将HTML区分成轮廓部分和数据部分。遗 憾的是:HTML中轮廓和数据混在一起,HTML并没有Schema, XML才有Schema,解析HTML时,难以区分其中哪些是数据 哪些是轮廓。因此,小程序的开发不能用HTML,要另起炉灶, 搞WXML。这也是取名“小程序”的另一重要原因。 • 微信的传播能力,实现了业务应用以微信形式出现; 48 互联网应用的关键问题 • 业务信息如何让用户知晓 ? • 业务信息如何让用户相信和认可? • 广告; • 电商平台: 1) 用户通过查询来知晓; 2) 用户通过对比来选择,例如成交量,价格 • 社交平台: 1)好友推荐,推送 2)? 49 腾讯公司为什么要搞微信小程序/小游戏/ 公众号 • 微信服务提供了基础设施,例如支付,消息触及客户,使得微 小企业构建自己的业务系统非常简单; • 低门槛:微小企业只须要基于微信小程序构建自己的业务系统, 其它事情(例如运维,数据存储,WEB服务器)全交给腾讯公 司; 50 腾讯公司为什么要搞微信小程序/小游戏/ 公众号(cont.) • 微小企业只要有自己的业务idea就够了。用微信语言表达。其 它的事情,腾讯全包了。 • 微小企业不须要网络,不须要服务器,不须要任何软件和硬件, 不须要任何IT专业员工; • 微小企业在起步阶段,腾讯不收费。当有业务流量,赚钱时, 就要给腾讯交费。 51 微信小程序/游戏/公众号的云开发 • 对于WEB应用,在浏览器中打开一个网页,就是调用一个函数。 后端就是要实现这个函数。函数的物理位置,只有在程序安装部 署时,通过配置参数给定。程序本身只表达了逻辑概念; • 微信小程序的云开发,就是用JS写后端函数。前端来调用它,得 到页面所要的数据。后端函数被称为云函数。写好的云函数在项 目发布时,会上传到云服务器,在Web云服务器上的Node.js环 境下执行。在云函数中可以调用存储接口(文件访问接口,数据 库访问接口)。 • 因此,云开发与原有传统开发方式完全一致,完全兼容; 52 微信小程序/小游戏/公众号中”小”的内含 l “小”意味着面向微小企业甚至个体户,使得它们具有搭建自 己的,基于互联网的业务系统的能力:低成本,低门槛,简单; 为它们基于微信来扩展客户群体提供平台; l “小”意味着前端实现的简单,宣示实力,无须复杂的框架。 例如,采用flex布局,引入rpx(responsive pixel)尺寸单位,以 适配不同宽度的手机屏幕。 l “小”意味着是WEB的子集; l “小”意味着是对WEB的补充;补充了页面中的交互式控件; 补充了和微信的集成,即调用微信的功能函数; 53 微信小程序/小游戏/公众号中”小”的内含 (cont.) • 取名“小程序”,“小游戏”,拿中国文化来说,联想起改革 开放总设计师邓小平,取名为“小平”。名为“小”,实为 ” 高、大”,”了不起“。 54 8. 编程模式——同步操作和异步操作 日常工作和生活中,打电话是同步操作,须当面解决;发短信, 微信,QQ,邮件是异步操作; 对异步操作,请求者会期盼被请求者对请求做出响应,回应执行 进度/结果; 对异步操作,被请求者,按照习俗,要反馈执行进度/结果; 在编程中,被请求者把执行进度/结果,打包成消息,回送给请求 者,请求者则以调用回调函数的形式来处理进度/结果; 在高节奏和忙碌社会,异步操作越来越受欢迎,流行55 基于异步操作的应用程序框架:消息队列 while(1) { WaitForMessage( ); FetchMessageFromQueue(msg); FunList = GetHookedFunList(msg.Token); while(Fun = FunList.Next( ) ) Fun(msg); } token 消息队列 消息队列中的消息有三类: 1)异步操作的进度和结果事件:fail/success/complete; 2)用户操作的行为事件;click/select; 56 3)对象/组件的状态变化事件: show/hide/activate/terminate 请求任务的原子性和非原子性 当访问某一个服务,提交一个请求时,请求的任务可能是原子 性任务,也可能是非原子性任务。 例如,向文件服务器请求读取一个文件时,文件服务器可能会将文 件分成多个段,一段一段地发送给请求者,这就是一个非原子性请 求任务。当向银行发送一个转账请求任务时,这就是一个原子性请 求任务。 对于非原子性请求任务,就有一个执行进度问题。整个响应会 由多个消息组成。每个消息都带有状态标记。对每个消息,回调函 数都会被调用一次。 第一类消息:回调消息 对异步操作中回调函数的理解 (1) while(1) { WaitForMessage( ); FetchMessageFromQueue(msg); if(msg.class == callback ) msg.Fun(msg.parameter); } 回调消息 消息队列 异步操作:例如文件访问操作,网络请求操作; wx.request(url, MIME, OnComplete, OnSuccess,OnFail); 其 中,OnComplete, OnSuccess,OnFail叫回调函数; 因此,对同一类的多个请求操作,不能连着请求。必须第一个请求 之后,在其OnSuccess中执行第二个操作请求; 58 实现对同一异步操作的并发性多次调用 异步操作:例如文件访问操作,网络请求操作; wx.request(url1, MIME1, OnComplete1, OnSuccess1,OnFail1); wx.request(url2, MIME2, OnComplete2, OnSuccess2,OnFail2); wx.request(url3, MIME3, OnComplete3, OnSuccess3,OnFail3); 并发多个请求,但是回调函数不同; 还有一种处理方式,在响应结果中带上了请求id; 59 基于回调的异步操作中,思考四个问题 wx.request(url, MIME, OnComplete, OnSuccess,OnFail);其 中,OnComplete, OnSuccess,OnFail叫回调函数; 注意:从函数调用来看,在这里传递的OnComplete, OnSuccess, OnFail是函数变量的值。 问题: 1)谁来定义回调函数?谁来实现回调函数? 2)谁给请求者发送回调消息? 3)被请求者怎么知道要给哪个线程的消息队列发送回调消息? 4)回调消息的内容:是否要指明函数,以及参数? 60 基于回调的异步操作中,能否将序列操作 改为并发操作? 例如: wx.request('./images/picture1.jpg', MIME, OnComplete, OnSuccess,OnFail); 回调消息 wx.request('./images/picture2.jpg', MIME, OnComplete, OnSuccess,OnFail); 消息队列 wx.request('./images/picture3.jpg', MIME, OnComplete, OnSuccess,OnFail); l 那么,被请求者就要在回调消息的定义中,定义一个参数,指 明请求内容的id; l 另外一种方案是:每个请求都有自己的回调函数; 第二类消息:用户操作行为事件消息 while(1) { WaitForMessage( ); FetchMessageFromQueue(msg); if(msg.class == user_behavier ) msg.Fun(msg.parameter); } 行为消息 消息队列 Btn1_OnClick(message msg ) { HttpRequest(TextBox. text, OnSucess, OnFail, OnComplete); } 问题: 1)谁来定义事件处理函数?谁来实现事件处理函数? 2)谁在发送消息? 62 第三类消息:对象/组件状态变化事件 while(1) { WaitForMessage( ); FetchMessageFromQueue(msg); if(msg.class == user_behavier ) msg.Fun(msg.parameter); } 状态变化消息 消息队列 App( { onLaunch: function(options) { }, onShow: function(options) { }, onHide: function() { }, onError: function(msg) { } }) 问题: 1)谁来定义事件处理函数?谁来实现事件处理函数? 2)谁在发送消息? 63 理解基于事件驱动的编程框架 三类消息: 1)异步操作的请求/响应事件:是请求者线程给被请求者线程发 送请求消息;然后是被请求者线程给请求者线程发送响应消息; 2)用户操作的行为事件:是应用程序管理程序单向发送给应用 程序的消息; 3)对象/组件的状态变化事件:具有从属关系的线程之间发送对 象/组件状态变化消息,或者自己也可给自己发送消息; 64 谁是消息的发送者? 对异步操作:被请求者通常是系统服务,系统服务通常在开机时 就启动,例如文件管理服务,内存管理服务,网络管理服务; 应用程序管理器是系统服务,负责所有应用程序的启动运行。它 跟踪应用程序视窗在显示屏上Z轴方向的顺序;它知道每个视窗 在显示屏上的位置和状态(是否为当前活动视窗);当然也知道 每个视窗中的每个控件在视窗中的位置和状态(是否为当前聚焦 组件)。因此,当收到鼠标/键盘事件时,它能推算出是哪个视 窗中的哪个控件被点击;从而知道给哪个应用程序的线程发送用 户操作行为消息,或者对象/组件状态变化消息; 65 请求者如何知道被请求者 有两种情况: l 操作系统为每种系统服务都提供有访问它的API,应用程序调用 API来访问系统服务; l 进程/线程A调用操作系统API来创建进程/线程B,返回值为进 程/线程B的id,于是可给进程/线程B发送消息。 66 用户操作行为事件与对象/组件状态变化事件 l 这两类消息具有单向性,是由应用程序管理器单向发送给应用 程序,例如,指鼠标和键盘操作事件。应用程序并不给管理器 发送消息。这两类消息的结构是事先定义好了的。编写应用程 序时,只须要针对交互式控件,实现消息处理函数,并将其注 册(SetHandler)到挂钩Hook上; 例如: Btn1_OnClick(message msg ) { HttpRequest(TextBox. text, OnSucess, OnFail, OnComplete); } 67 基于事件驱动的编程框架特性 对彼此独立的操作和序列化的操作都能很好地处理: l 对彼此独立的操作,例如录入,查询,报表,导入/导出,对这 些事情,用户可随选,以人机交互来执行; l 对序列化的操作,例如打开网页,先是调用异步函数 HttpRequest,然后在其回调函数OnSuccess中将得到的响应 结果( HTML )翻译成JS,再解释执行; 68 进一步理解基于事件驱动的编程 消息结构体的定义,由服务方提供。对于消息队列,以及回调消 息的处理框架,通常是由操作系统厂家提供。操作系统提供有API 来完成: l 回调函数往挂钩(Hook)上注册:SetHandler l 消息发送;PostMessage(异步),SendMessage(同步); l 从消息队列中取出消息:FectchMessage; 69 消息队列的特性 每个线程都拥有自己的消息队列,线程A要给线程B发送消息,就 调用操作系统提供的API函数postMessage( )来完成;其前提是 线程A要知道线程B的id。 线程A要从其消息队列中取出消息,外部则要往其中添加消息。因 此,消息队列为多线程共享对象,存在管理问题; l务必小心:切忌调用同步函数!例如Sleep, 为什么? 70 9. 编译模式的演进经历了三代 高级程序语言 编译 链接 高级程序语言 二进制可执行文件; 中间字节码 VM 编译 脚本语言 引擎 解释执行 解释执行; 71 实现高级语言源程序的通用性 高级程序语言库函数 Map 1 Map 2 Map 3 字节码 JVM 操作系统API UNIX 操作系统API Windows 操作系统API Apple Mac 操作系统 这样,就使得用高级程序语言编写的应用程序与操作系统及机 器无关,实现了源程序的通用性,一个应用程序只需要编程一遍 ,便能满足在任何一个机器和操作系统上运行的需要。 72 高级语言到API到操作系统API的映射例子 Ø C语言中的库函数:malloc(size_t size); Ø Ø //分配内存 在Windows中的Map实现: malloc(size_t size) { HANDLE h = GetProcessHeap( ); Return HeapAlloc(h, 0, size); } 在Unix/Linux 中的Map实现: malloc(size_t size) { return sbrk(size); } 73 高级程序语言实现的通用性特征 注意:这是在源程序一级实现的通用性,并没有在二进制可执 行程序一级实现通用性,因为对于特定的机器和操作系统,都 需要使用与其对应的高级程序语言函数的映射实现库,加上与 其对应的编译器和连接器把源程序编译成能在其上运行的二进 制可执行程序。 PC机Linux下的C++ + 编译器和链接器 用C++语言编 写的应用程序 Linux 下C++库函 数的映射实现 二进制可 执行程序 PC机Windows下的 Windows下 C++库 + 函数的映射实现 C++编译器和链接器 二进制可 执行程序 + Mac 下C++库函数 二进制可 执行程序 74 Apple Mac下的C++ 编译器和链接器 的映射实现 趋势1:程序语言和机型都在不断增多 C++语言 C语言 不同平台 前端 Fortran语言 pascal语言 Cobol语言 X86, Windows X86, Linux Java语言 Basic语言 后端 中间代码 Apple 手机, Andriod IBM Cray, Unix 75 趋势2:同一机型的版本也在不断增多 C++语言 C语言 X86机型的不同版本 前端 Fortran语言 pascal语言 Cobol语言 8086 80286 Java语言 Basic语言 后端 中间代码 80386 兼 容 80586 .... 76 就同一机型,不同版本而言,思考如下问题 对于老版本,已经编译好的,遗留下来的应用程序: 尽管新版本对其兼容,执行没有问题,但是新版本的新特性,根本 利用不上。导致新特性完全浪费掉了。例如,新版本增加了寄存器, 新增加了流水线处理,新增加多核; 看得见的现象:买了一台新机器,但还是慢吞吞的; 解决:1)机器一则做工作,对原有指令解释执行。增加硬件(价 格贵了,耗电多了;2)编译器一则做工作,对老的目标代码进行 改造,形成新版本应用程序; 77 两种方案各有什么问题?选哪一个?为什么安装Windows很慢? 因此,第一代编译方式已经过时 由源程序开发方来执行编译和链接,生成可执行的目标机器代码, 然后分发给用户,在用户的机器上运行: 优点:不须要分发源程序,保护了知识产权。 缺点1:要为每种机型,每种操作系统,都编译一次,生成对应的 可执行文件;分发时要考虑机型和操作系统; 缺点2:同一机型,会有很多版本,向前兼容。编译时为了使可执 行文件在尽量多的版本上都能执行,只好按照低版本来保守编译。 当程序执行在高版本上时,高版本的新特性都没有利用上,白白 78 地浪费了机器资源。例如,新版本的寄存器就比旧版本多得多。 第二代编译方式 l 前端:谁提供高级程序语言,谁就提供前端。程序开发 方只须编译一次,得到一个中间代码即可。大大简化了 程序开发方的产品维护工作的复杂度。 l 后端:由操作系统的厂家来提供。变成操作系统的一部 分,在每台机器上都配备,例如JAVA虚拟机。于是, 当程序运行在用户的机器上时,基于机器版本进行即时 编译,机器的特性就能充分利用上。 l 在中间代码上达成共识,建立国际标准; 79 第二代编程中出现的问题,面临的新情况 以JAVA为代表的面向对象编程,导致了不断地继承,带来的问题 是:对于一个外部的软件包,只要用其中的一点点,就要把整个软 件包导入,导致软件非常臃肿。一个“hello world”程序,编译 后就有几十兆。 面向对象编程只图实现上的简单方便,只顾拿来,不顾程序的体积。 出现的变化:软件使用变成了免费,赚钱只能靠数据和服务。软件 开源变成了主流,源程序产权保护不再有意义。 80 第二代向第三代的演变 面向对象编程积累的问题,解决之路在:对程序进行梳理,不断提 取共性,进行抽象,再进行专业化整理,变成面向服务的编程。 在面向服务编程中,封装的不再是对象,而是服务。策略是拆程序, 分工,而不是继承。 这就是华为老总任正非在2019年1月提出要对华为软件进行全面重 构的原因。 这就引发了第三代编程模式:面向服务的编程。代表就是Python。 Python把灵活性引入到运行时,使得源程序非常简洁,只有Java 程序长度的十分之一,甚至百分之一。 81 第二代向第三代演变恰得其时 由于互联网的高度发达,使得数据全部移向了企业服务器,大数据 处理集中在企业服务器上。客户端的PC机和手机专注于人机交互。 这种清晰的分工为软件重构提供了可行:对程序基于功能重新梳理, 不断提取共性,进行抽象,再进行专业化整理,变成面向服务的编 程。 软件重构借鉴了生物的构成特性: 生物的构成特性:细胞  组织 器官 生物体。 程序:指令 函数  模块  包  应用程序。 82 程序的分化式演变 程序包含科学计算(数值计算)部分,与协同交互两个部分。 数值计算:例如矩阵运算。数据规模大,计算密集型。关键问题: 处理性能:特点:可并行处理。要求编译器:充分挖掘并行性,充 分利用机器特性。 协同交互部分:特点:主要是逻辑判断和分支控制,基本块内的语 句数很少,可并行性也小;可优化性小; 83 程序的分化式演变(cont.) 对于数值计算,不断地提取共性,不断地抽象,不断地沉淀,形成 厚积薄发的基础服务,发挥支撑性作用,与机器型号和版本相关, 随机器成为系统软件; 越来越象生物的构成特性:细胞  组织 器官 对于协同交互,面向特定的应用,相当于生物体,具有特定功能, 个性化很强。这部分则不断地上浮,越来越脱离具体的机器,越来 越变得与机器无关; 这就脚本语言出现的原因,演变成解释执行,调用基础服务; 84 脚本语言 脚本语言的生命力,也在不断地提取共性,不断地抽象,不断地整 理,不断地归纳,不断地强化动态性。于是,程序变得越来越简洁, 短小,适应能力很强; 象python语言,用它写应用程序,其源代码量,与用Java语言写 的相比,通常只有十几分之一; 程序简洁和短小,bug和漏洞自然就少,可靠性强;可维护性也增 强了; 从理解和掌握脚本语言来看,并不比掌握Java容易; 85 问题思考 不经历高级程序语言,不经过面向过程,面向对象,面 向服务,直接跳到脚本语言编程,可行吗? 86 编译技术的演进 l 编译这项工作在膨胀,贯穿整个计算处理,从表达到实 施,从概念到实现,从抽象到具体; l 向硬件膨胀:提炼出来的有些算法,演变成用硬件来实现; l 向用户膨胀: 提炼出的概念和表达,越来越软,越抽象,适用场 景越来越广,无所不适, 例如: sc.textFile("hdfs:/ data/ paper.txt").flatMap (_.split(" ")).map((_,1)). reduceByKey(_ + _).collect( ) 87 第三代与第一、二代之间的差异 l 对于第一代和第二代开发,应用程序在开发时,就收集了所有 须要的基础支持库。将应用程序打包发布给用户时,也带上了 所有的基础支持库。因此,在用户机器上安装应用程序时,对 应用程序所须的基础支持库,安装程序会在用户机器上逐一检 查,看是否已经安装。如果没安装,便进行安装。确保在安装 时,所须的支持库都已就位。应用程序运行时,不会缺失任何 东西。 88 第三代与第一、二代之间的差异 (cont.) l 对于第三代开发,一些业务功能往往须要基础支持库。例如在网 页中,要播放一段视频,就需要视频播放支持库。但是对于打开 该网页的用户,其机器上,可能并没有安装视频播放支持库。于 是脚本程序在用户机器上不能正常运行,视频不能播放。 l 要解决该问题,安装程序的功能,不得不在脚本程序中来加以实 现。在网页中创建视频播放组件之前,先检查用户机器上是否已 经安装有视频播放支持库。如果没有,则读取用户机器的型号和 操作系统型号,然后再从服务器上下载与其对应的安装包,并在 用户机器上安装。安装好后,再在网页中创建视频播放组件。 89 4.9 提出 HTML 5的原因 l 针对上述用户机器上可能没有安装某个功能的基础支持库,例如 动画组件,VR组件,图像识别组件,地图组件, 视频播放组件。 那么网站的维护者(服务端)不得不为全世界流行的每一个机型 和操作系统,分别预备基础支持库来以供用户下载和安装。这个 事情很复杂;另外,下载安装要花时间,用户体验变差。 l HTML 5的提出,就是把一些流行的组件变成浏览器的标准配置 组件,例如地图组件,视频播放组件。这样,网站的维护者(服 务端)就不用考虑上述问题了。服务端的负担得以大大减轻。 90 浏览器的执行过程 浏览器是一个基于消息队列的应用程序; l 当用户点击工具条上的打开网页Button,调用OnClick( )函数; l 在OnClick函数中,调用异步函数HttpRequest(uri ), l 在其回调函数Sucess( )中,调用ScriptEngine(TextStream); l 在函数ScriptEngine中,把HTML翻译成JS脚本,其中用到 DOM;再执行JS脚本,得到显示界面; 浏览器中的Javascript: JS语法 + API (即DOM和 BOM); 91 脚本语言的可扩展特性 脚本语言中,和其它高级程序语言一样,所有东西都是用名字来 标识的,包括接口,函数。 每一个浏览器中的JS脚本引擎,它知道的原始API就是WEB中定义 的DOM和BOM。 不过浏览器厂家也原始会增加自己的API,例如微软的IE中,就增 加了一个CreateObject函数,用于获取一个接口实例。该函数的 一个参数就是名字。即根据名字来获得一个接口的实例。如果获 取成功,就可调用该接口中包含的任一函数。 脚本语言的可扩展特性(cont.) 例如,在一个网页中,要播放一个视频。在网页的脚本中,就要 调用CreateObject( )来在网页中创建一个视频播放器控件,来播 放视频。 在CreateObject( )函数的实现中,先基于名字来找到对应的二进 制可执行模块的磁盘存储路径和文件名,然后调用LoadLibrary将 其加载到浏览器的进程地址空间中,再调用GetProcAddress获取 其对外部开放的初始函数,再调用它来获得初始接口指针。 客户机器上可能没有安装视频播放器,因此,脚本还要先查一下, 看宿主机是否已经安装了视频播放器。如果没安装,则先要下载 并安装,然后再来调用CreateObject( )函数; 10. 从编程角度来看应用程序的启动执行 Windows中的命令行应用程序cmd,你敲入要运行 的程序和参数,按回车键后,就运行。 main函数为什么带参数? main函数由谁定义? 10. 应用程序的启动运行(cont.) 10. cmd命令行程序中按回车键时执行的 代码 string szExeName; int numPara; string szParams; int (*pfn)( int, unsigned char *) = 0; int pid = fork( ); if (pid == 0) { HINSTANCE h = LoadLibrary ( szExeName); if (h) *(FARPROC* )&pfn = GetProcAddress ( h, “main”); if (pfn) int result = pfn(numPara, szParams); } else { ....... } 10. 应用程序的启动运行 l 开机,到操作系统启动就绪,就会启动一个系统服务,叫进程管 理器。进程管理器提供的服务包括:创建,释放,查询应用程序 进程。 l 创建(fork)一个进程,即得到了一个虚拟地址空间,随后的工作 就是调用LoadLibrary( ), 把exe文件从磁盘加载到进程虚拟地址 空间,然后检查exe文件的import table部分,看它依赖于哪些 dll文件,然后加载这些dll文件,以此类推,直至所有需要的dll 文件都加载完毕。然后调用GetProAddress(), 找到main函数的 地址,并调用它。于是,执行就交给了应用程序。 系统服务 l 操作系统启动就绪后,就启动了一些系统服务。一个系统服务是 一个进程/线程;每个系统服务管理的资源,供本机运行的应用 程序共享使用;例如网络,文件系统,内存等; l 操作系统提供API函数,供应用程序调用,来访问系统服务; l 对应用程序来说,通过系统服务访问共享资源时,不一定成功。 例如,文件系统是共享资源,当一个应用程序调用系统服务函数 openfile,以写方式打开一个文件时,可能不成功,原因是另一 个应用程序已经以写方式占用了该文件。 系统服务(cont.) l 一台机器上的所有资源,对应用程序来说,都是共享资源,都 由系统服务进行统一管理。例如,内存管理器,CPU管理,网 络管理,文件管理器,进程管理等。 l 应用程序对共享资源的访问都要通过系统服务来完成。它们之 间通过发送消息来完成请求和响应。 系统服务 vs 火车订票系统 l 当客户订票时,先查询是否有票,如果有票就可订票。从查询 到订完票要一段时间,期间要打开订票信息页面,付款操作页 面等。有的客户在查了票后,并没订票。 l 火车票是共享资源。你在订票的时候,别人也在可能在订票, 假定你查询时,还剩2张票,等你付款的时候,可能订票失败, 原因是别人已经抢在你前面订走了。 l 系统服务 vs 火车订票系统,它们的相同点和差异分别在哪里? 客户访问系统服务 l 一台机器可运行多个应用程序。这些应用程序都会访问系统服务。 l ,应用程序通过调用操作系统提供的API来给系统服务发送消息, 访问共享资源。访问的实现,采用消息队列方式; l 将其延伸,当要访问任何一种服务,包括外部机器上的服务,其 实都是采用消息队列方式。客户向服务的消息队列发送一个消息。 例如访问WEB服务,则调用HttpRequest函数。 l消息是本质,API是形式。 内存中的共享数据 l 内存中的共享数据,多个应用程序可共享读,而且是以内存页为 单元进行共享。 l 当某个应用程序对共享数据要执行写操作时,采取copy-onwrite策略。即对应用程序要执行写的内存页,就拷贝一份出来 给它来写。于是,新旧数据都有。随后,执行写操作的应用程序, 因故障或者其它原因,要撤销写操作时,就很容易处理,废弃掉 给它拷贝的内存页即可。当写成功之后,存档页就失去了存在的 意义。 Question 注意: Windows中叫系统服务,Linux中则叫子系统; l系统服务(System services)与服务器(Server) (例如,数据库服务器,邮件服务器,WEB服 务器)有什么异同? 服务的永恒性 vs 变动性 l 服务一旦发布出去了,客户就会基于服务规定,形成固定概念, 来访问服务。因此服务规定最好不要改变,一旦改变就导致客 户错乱。例如,院楼把房间号直接改了。 l 服务的变动要前向兼容,确保原有客户不受影响。前向兼容就 是只能新增,不能对原有规定做修改/删除。例如,尽管现在是 4G和5G时代,原有的旧手机依然能照常使用。 l 新的机型和操作系统,如何前向兼容旧的应用程序,例如, DOS, windows 16 ? 遗留软件的旧貌变新颜 l软件和其它东东的最大不同时,软件不会老化,不会烂掉报废。 另一方面,机型和操作系统的升级换代又非常快; l于是,遗留软件的旧貌变新颜工作非常关键。例如,一个不懂外 语的中式大厨,如何使其在国际大酒店中发挥作用。有两条路径: ü 在国外,为其建造一个中式厨房环境; ü 在国内,为其加一层外包装(服饰/翻译/故事),将其国际化 l 软件栈,为软件的旧貌变新颜提供了轻易的解决方案;

相关文章