目录:绪论,通信,进程,命名,同步,一致性和复制,容错性,安全性
第3章 进程
进程的概念源于操作系统,它定义为执行中的程序。在分布式系统中,为了有效组织客户-服务器系统,使用多线程技术更为方便,线程的主要作用就是以适当的方式来构建客户和服务器,使得通信和本地处理过程可以并行进行,从而获得性能上的提升。本章将讨论线程、代码迁移和软件代理等技术和机制。
3.1 线程
将每个进程细分为若干控制线程(thread)的形式使得构建分布式应用程序变得更加方便,可获得更好的性能。
1. 进程:一般定义为执行中的程序,也就是当前在操作系统的某个虚拟处理器上运行的一个程序。多个进程并发地共享同一个CPU以及其他硬件资源的事实是透明的,操作系统需要通过硬件支持来实现这种隔离。
2.线程:同样可以看作是程序的一部分在虚拟处理器上的执行,不同的是线程在取得高并发透明性时不会导致性能的降低。但在单个进程中防止数据遭到线程错误访问的任务完全落在应用程序开发人员身上,因此多线程应用程序的开发需要付出更多的努力。
3. 非分布式系统中的线程用法:①在同一个进程中使用至少两个控制线程,一个管理与用户之间的交互,另一个进行数据表的更新工作,从而能够避免单个线程由于等待用户请求造成的全进程阻塞。②多线程并行执行同一任务,为每一个线程分配一个CPU,同时将共享的数据存储在共享主存中。③应用在大型应用程序上下文环境中。这种应用程序一般是作为一组相互协作的程序开发出来的,其中每个程序都通过独立的进程执行。程序间协作是通过进程间通信(IPC)机制实现的,通信需要开销庞大的上下文环境切换。如果其中不同的部分都通过独立的线程来执行,各个组成部分之间的通信完全通过数据共享来处理,线程切换完全在用户空间中完成,也可以由内核来掌管线程并对它们进行调度,这样在性能上就可以得到极大的提升。④使用线程还出于纯粹的软件工程上的考虑,用一组相互协作的线程来构建应用程序常常比较简便。
4. 线程的实现:线程一般是以线程包的形式提供的,包含创建与销毁线程、互斥变量以及条件变量之类的同步化变量操作。有两种实现线程包的基本方法,一种是构造一个完全在用户模式下执行的线程库,称为用户级线程库,另一种是由内核来掌管线程并进行调度,称为内核级线程库。用户级线程创建和销毁线程的开销很小,可以通过不多的几条指令来实现线程上下文环境的切换,但对引起阻塞的系统调用的调用将会立即阻塞该线程所属的整个进程,也就阻塞了所属进程中的所有其他线程。内核级线程可以解决上述问题,但解决代价比较大,每个线程操作都必须由内核来执行,并且需要进行系统调用,线程上下文其环境切换的开销变得与进程上下文环境切换的开销一样大。另一种解决方式是采用用户级线程和内核级线程的混合形式,一般称作轻量级进程(lightweight processes,LWP)。使用LWP建立多线程应用程序时,首先要创建线程,随后为每个线程分配一个LWP,LWP执行一个调度例程寻找下一个线程来执行,如果找到一个可运行的线程,它就将上下文环境切换到该线程。另一种与轻量级进程相似的方法是使用调度激活,调度激活和LWP之间的本质区别在于,在调度激活中,当线程在系统调用中被阻塞时,内核对线程包进行上行调用,调用调度例程来选择下一个可执行的线程来执行。
5.分布式系统中的线程:利用线程不会阻塞整个进程的特点,将通信表述为同时维护多个逻辑连接的形式。
6.多线程客户:隐藏通信时间延迟的常规方法是启动通信后立即进行其他工作。例如,为了尽量隐藏通信时延,某些浏览器在接收数据的过程中就开始显示数据。以多线程客户对的模式开发浏览器可以显著的使问题得到简化,只要取得了主HTML文件,就可以激活多个独立的线程,它们分别负责取得页面的每个部分,每个线程都与服务器建立一个独立连接以获取数据。此外,在使用多线程客户的时候,可以与不同的服务器副本建立连接,这样就可以并行地进行数据传输了,使得在多副本服务器将整个Web文档完全显示出来所需的时间大大缩短。
7.多线程服务器:多线程技术不仅能够显著简化服务器代码,还能够使得应用并行技术来开发高性能的服务器变得更加容易。例如在文件服务器中,可能会偶尔由于等待磁盘操作而阻塞,文件服务器一般等待输入的文件操作请求,随后执行该请求,最后送回应答。其中一个称作分发器线程用来读取文件操作请求。在请求进行检查以后,一个空闲的工作者进程来处理请求。
3.2 客户
1. 客户的任务:大多数客户的主要任务是与个人用户和远程服务器相交互。对用户界面的支持是多数客户的关键特征。
2.X Window系统:是操作系统中负责控制终端的一部分。系统的核心由称作X内核(X kernel)的部分构成,它包括该类终端专用的全部设备驱动程序,而且对硬件有高度的依赖性。X将应用程序分为两类,普通应用程序和窗口管理器。普通应用程序一般请求在屏幕上创建窗口,随后它就可以使用该窗口来进行输入输出处理。另外,X会确保在某个应用程序窗口处于激活状态的时候,也就是鼠标指针进入该窗口的时候,将来自键盘和鼠标的所有事件都传递给该应用程序。窗口管理器是得到特殊许可来管理整个屏幕的应用程序,普通应用程序在进行屏幕操作时,必须遵守由窗口管理器制定的约束规则。X内核和X应用程序不一定要驻留在同一台机器上,X提供了X协议,该协议是一个面向网络的通信协议,通过该协议Xlib实例可以与X内核交换数据和事件。
3.复合文档:更为复杂的用户界面操作背后的关键思想是复合文档,复合文档可以定义为一组文档,这些文档的类型可以不一致,但是在用户界面层上做到了无缝集成,文档不同部分实际上是由不同应用程序来处理的事实被隐藏。
4.客户端软件:除了用户界面外,部分处理和数据级工作是在客户端执行的。嵌入式客户软件是这样一类特殊的软件。除此之外,客户端还包括一组实现分布透明性的组件,实现的透明性包括访问透明性、定位透明性、迁移透明性、重定位透明性、复制透明性、故障透明性、并发透明性、持久性透明性。
3.3 服务器
1.服务器设计上常见的重要问题
Q1:服务器的组织方式。本质上每个服务器的组织方式都一样,等待来自客户的请求,随后负责处理该请求,最后等待下一个输入的请求。几种组织结构包括重复服务器、并发服务器、多线程服务器。
Q2:客户联系服务器的地方。客户总是向服务器所在机器上的端点发送请求,端点也称作端口(port),每个服务器都监听一个特定的端口。
Q3:应该在何时以何种方式来中断服务器的工作。例如用户想要中断服务器程序,取消数据传输。一种方法是让用户立即强行退出客户应用程序(这将自动中断与服务器之间的连接),然后马上重启客户应用程序。处理这种通信中断更好的方法是在开发客户程序和服务器程序的时候考虑到对带外数据发送的支持,服务器在处理客户发送的其他所有数据之前会优先处理带外数据。
Q4:服务器时否是状态无关的。状态无关服务器不保存其客户的状态信息,而且也不将自身的状态变化告知任何客户。例如Web服务器。状态相关服务器保存客户端的信息,并对其进行维护。这种服务器的典型例子是文件服务器,它让客户保留文件的本地拷贝,并且进行更新操作。状态相关服务器的一个主要缺陷是,如果服务器崩溃,就必须恢复那些包含对条目的表,否则无法确保能够处理文件的最新版本。
Q5:某些情况下,服务器需要保留客户的活动记录,以便更加有效地响应客户的请求。一种常用的方法是让客户在发送请求的同时发送关于前一次访问的额外信息。这种信息常常由客户端浏览器透明的存储在cookie中,cookie是一小段数据,其中包含有对服务器有用的针对特定客户的信息。浏览器本身不会执行cookie,它只对cookie进行存储。
2.对象服务器:是一种为支持分布式对象而定制的服务器。一般的对象服务器与其他更为传统的服务器之间的区别在于,对象服务器本身并不真正提供特定的服务,特定的服务是由驻留在服务器中的对象实现的,本质上来说,此类服务器仅仅提供根据远程客户的请求来调用本地对象的手段。对象的状态和方法是否相互分离,以及方法实现是否由多个对象共享等问题取决于对象服务器。
3.对象服务器调用对象的不同方法:一种简单的方法是假定所有对象都相似,并且只存在一张调用对象的方法。更好的方法是让服务器支持不同策略。一种合理的策略时,在收到第一个调用请求时创建一个暂时对象,随后如果不再有客户绑定到该对象上就尽快将其销毁。另一种策略是将每个对象都放置在属于该对象自己的内存段中,对象间不共享数据,也不共享代码。还有一种让对象共享代码的方法,如果数据库含有的对象都是属于同一个类的,就可以通过将类实现一次性加载到服务器上来实现该数据库。关于线程的不同策略,最简单的方法是实现单控制线程的服务器,服务器也可以拥有多个线程,每一个线程管理一个对象,所有对该对象的调用都由与该对象相关联的线程来串行处理。另一种方法是为每一个调用请求都使用一个单独的线程,但这就要求采取措施来保护对象使其免遭并发访问。
4. 对象适配器:对如何调用对象所做的决定一般称为激活策略,对象适配器的作用是将对象根据策略进行分组。对象适配器控制一个或多个对象。由于服务器应该能够为请求不同激活策略的对象同时提供支持,其中某些适配器还可能同时驻留在同一个服务器上,当一个调用请求传送到服务器时,该请求首先被分派到适合的对象适配器。适配器的实现是独立于它为之处理调用的对象的,这样才能构建通用对象适配器并且在概念上把这些适配器放在中间件层。
3.4 代码迁移
1.概念:分布式系统中所进行的通信是传递程序(甚至可能需要传递正在执行中的程序),以简化分布式系统设计。分布式系统中的代码迁移是以进程迁移的形式进行的,整个进程被从一台机器搬到另一台机器上去。
2.动机:①如果把进程由负载较重的机器上转移到负载较轻的机器上去,就可以提升系统的整体性能。②处理数据的机器与数据就近分布,能减小数据传输压力。③代码迁移可以支持系统通过并行的使用来提升性能,而不会带来通常的并行编程具有的复杂性。④灵活性,如果代码可以在不同机器之间移动,就可以动态地配置分布式系统。一种方法是在开发客户应用程序时使用特定的协议实现客户端应用程序与服务器接口的链接。另一种更灵活的方法是,客户动态的下载程序的实现,经过某些必须的初始化步骤后调用该服务器。
3.代码迁移模型:Fugetta等人于1998年提出的框架结构中指出,进程包含3段,代码段(code segment)部分包含构成正在运行的程序的所有指令。资源段(resource segment)包含指向进程需要的外部资源的指针,这些外部资源包括文件、打印机、设备、其他进程等。执行段(execution segment)用来存储进程的当前执行状态量,包括私有数据、栈和程序计数器等。
4.可迁移性的强弱:①弱可移动性,只传输代码段以及某些初始化数据。②强可移动性,传输代码段和执行段,典型特征是可以先停止运行中的进程,然后将它搬到另一台机器上去,再从刚才中断的位置继续执行。
5.迁移的发起者:由发送者启动和由接收者启动。在发送者启动的迁移中,代码当前驻留在哪台机器上或者正在哪台机器上执行,就由该机器来启动迁移。在接收者启动的迁移中,代码迁移的主动权掌握在目标机器手中。如果是接收者启动的迁移,代码下载工作一般可以匿名进行。
6.迁移后的执行方式:迁移过去的代码是否由目标进程执行,还是重新启动一个单独的进程来执行。比如Java小程序可以简单由Web浏览器下载之后再浏览器的地址空间中执行。这种方法的好处是不需要启动单独的线程,也就避免了与目标机器进行通信,主要缺陷是目标进程必须得到保护,以免在迁移来的代码的执行过程中受到有意无意的侵害。
7.远程克隆:与进程迁移不同,克隆将制作一份与原始进程完全相同的拷贝,但运行在不同的机器上。
8.迁移与本地资源:资源段的难迁移性是造成代码迁移如此困难的主要原因之一。进程对资源的绑定方式分为三类,分别是按标识符绑定(引用资源)、按值绑定、按类型绑定。建立全局引用并不仅仅是使用URL,而且使用这种引用额开销有时候昂贵的无法接受。资源可以分为三类,分别是未连接资源(可以方便地在机器之间移动)、附着连接资源(可以进行复制或移动,但是开销相对较大)、紧固连接资源(这种资源紧密的绑定到特定的机器或者环境,无法进行移动)。
9.对紧固连接资源的处理方法:①在进程迁移之后,在进程所在源机器上建立一个单独的进程并由迁移后的进程建立连往源机器的连接,由单独的进程负责将所有传入消息通过连接转发给迁移后的进程。②让与迁移进程通信的所有进程都改变它们的全局引用,将消息都发送到目标机器上的新的通信终点。
10.异构系统中的代码迁移:在操作系统和机器体系结构都不同的异构系统中,实现代码段能够在所有平台上执行(也可能要对原始的代码重新编译),同时,必须确保在所有平台上执行段都能够正确表示。只涉及弱可移动性,可以对源代码进行重编译,生成不同代码段,分别用于不同的目标平台。要支持强可移动性,需要解决的主要问题在于执行段的传输,问题是执行段是高度依赖于执行进程的平台的。一种针对C或Java之类的过程性语言的解决方法是只在程序执行过程中特定的执行点允许进行代码迁移。运行时系统负责维护自身的程序栈拷贝,称为迁移栈,在调用子例程时或者执行权从子例程返回时对迁移栈进行更新。迁移时将全局数据编组后与迁移栈一同传输到目的机器。目的机器根据自己机器的体系结构和操作系统加载代码段,属于执行段的编组数据被解除编组,并对迁移栈解除编组以建立新的运行时栈。
11.实例:D’Agents:是一种支持多种形式的代码迁移的中间件平台,正式名称是Agent Tel,建立在代理的概念上。代理是一个程序,可以在异构系统中的机器间迁移,由运行语言解释器的进程来执行,通过三种方式支持可迁移性,分别是发送者启动的弱可移动性、进程迁移所代表的强可移动性,以及进程克隆所代表的强可移动性。
3.5 软件代理
1.概念:软件代理是一些独立的单元,能够与其他代理进行协作,一同执行任务。定义为能够对环境中的变化作出反应,并且启动这种变化的自治进程,而且可能与用户代理或者其他代理协同。代理区别于一般进程的特征是它能够对自己执行操作,还必须能够与其他代理协作。分布式系统中的代理有合作代理、移动代理、接口代理、信息代理。
2.代理技术:如何将分布式系统中的通用代理组件隔离开来并将这类组件嵌入到中间件等系统中去。应开发出智能物理代理基础作为软件代理的通用模型。代理平台包括管理组件(负责跟踪相关平台的代理)、目录服务(用于代理进行查询平台其他代理的服务)、代理通信通道ACC(负责平台与平台之间的通信)。可以简单地用一个服务器来实现ACC,该服务器监听到达某个特定端口的消息,并将该消息转发给其他服务器或者代理平台上的代理。
3.代理通信语言:代理间通信是使用应用程序级通信协议进行的,这种协议也称作代理通信语言(agent communication language,ACL)。ACL把消息的用途与消息的内容区分开来,ACL最基本的要求就是进行发送的代理和进行接收的代理至少要就消息的用途达成共识。