没有合适的资源?快使用搜索试试~ 我知道了~
首页.NET分布式编程-C#版
资源详情
资源评论
资源推荐

.NET分布式编程——C#篇
今天,诸如企业编程、分布式编程、n 层和可扩展性等流行词汇出现在每一个产品的宣传中。
所以,要抓住.NET 中分布式开发的细微区别,就不能从字面上考虑这些术语,而应该考虑
这些特殊词汇的真实含义和上下文环境。而且,由于这本书主要是一本“操作指南”,所以,
清楚地理解为什么要分布应用程序以及如何设计一个分布式应用是非常重要的。在本章结尾
提出了五项原则,它们可以指导您在.NET 平台及其他平台上进行分布式开发。
最后,为了了解分布式编程的历史,本章回顾了原有的分布式开发模型,以及这些旧模型被
新模型取代的原因。如同您将要看到的,要解释清楚为什么微软创造出新的开发平台.NET
来取代 COM 需要花费很长时间。
1.1 分布式编程概述
什么是分布式编程?现在几乎很少有人再敢问这个问题。这个术语现在是如此普及,以至于
去询问它的含义会让人觉得非常尴尬。而其他人则认为没有必要再去询问这个术语的含义。
当我在按照惯例让学生定义分布式编程时,却很少能得到相同的答案。
分布式编程的特点是让几个物理上独立的组件作为一个单独的系统协同工作。在这里,“物
理上独立的组件”可能指多个 CPU,或者更普遍的是指网络中的多台计算机。分布式编程
可用于解决很多类型的问题,从预测天气到购买图书。作为分布式编程的核心,它做了如下
的假定:如果一台计算机能够在 5 秒钟内完成一项任务,那么 5 台计算机以并行的方式一起
工作时就能在 1 秒钟内完成一项任务。
当然,分布式编程不会如此简单。问题就在于“以并行方式协同工作”,很难让网络中的 5
台计算机高效协作。实际上,要达到如此高效,应用软件必须经过特殊设计。对此可以举一
个只有一匹马拉车的例子。马是强大的动物,但是从力量与重量之比来说,蚂蚁要比马强壮
很多倍(这里仅假设强壮 10 倍)。这样,如果聚集了与一匹马质量相同的一堆蚂蚁并利用它
们来工作,则可以拉动 10 倍于一匹马所能拉的物质。这是一个非常好的分布负载示例。这
种计算是合理的,但让数百万的蚂蚁身上都套着细小的缰绳去拉动货物却是不现实的。

1.1.1 应用程序的分层
通过马与蚂蚁的类比说明,分布式计算提出几台计算机协同工作的问题。这也是将应用程序
分解为几个可被分布式处理的任务的问题。幸运的是,我们可以利用从以前的应用程序中学
到的知识。经过这些年的发展,可以清楚地了解到大多数业务应用程序是由 3 个主要逻辑部
分构成:表示逻辑,业务逻辑和数据源逻辑。
● 表示逻辑。表示逻辑是应用程序的一部分,终端用户可以通过它输入订单、查找用户信息和查看业务报表。对于用户来
说,这部分逻辑就是应用程序。
● 业务逻辑。这部分是应用程序的中心,开发人员将在这里花费大部分的时间和精力。它包括定义业务运行方式的业务规
则。例如,业务逻辑规定客户何时收到折扣、如何计算运费以及订单上所必需的信息。
● 数据源逻辑。这部分逻辑用于保存将来可能用到的订单、客户信息以及其他一些信息。幸运的是,SQL Server 和 Oracl
e 等数据库产品会实现大部分工作。不过您仍然需要设计数据层以及检索数据所使用的查询。
设计任何商业应用程序的首要之处是将应用程序的各个部分逻辑划分为不同的层次。换句话
说,不能将业务逻辑代码与表示逻辑代码混在一起。然而,不要想当然地认为每一层必须运
行在单独的机器上或单独的进程中。除此之外,每一层的代码只能通过定义良好的界面与另
一层的代码进行交互。典型的情况是在独立的代码库(DLLs)中从物理上实现某些层。
1.1.2 分布式设计的 5 个原则
分层结构允许在不影响其他层的情况下修改某一层的实现。同时,它也允许将来从物理上灵
活地分隔各个层。但是,正如下面紧接着的部分中所述,不应该轻易决定在独立进程或机器
上执行每一层。如果您决定对某一层进行分布处理,那么必须对它进行特殊的分布设计。令
人迷惑的是,某些设计策略实际上与传统的面向对象原则相矛盾。为弄清这些问题,这一部
分阐述了几项用于有效分布应用程序的原则以及使用这些原则的理由。
原则 1:保守分布
对于分布式编程的书籍来说,这个原则看起来让人有些惊奇。然而,这项原则却是基于计算
中一个简单且不可否认的事实:调用不同进程上对象的方法要比调用进程内对象的方法慢数
百倍;将对象移动到网络中的另一台计算机上,这种方法调用又会慢数十倍。
那什么时候才应当进行分布式处理呢?以前的观点是只有必须进行分布时才这样做。但是您

可能想了解更多的细节,所以让我们从数据层开始考虑几个示例。通常,应用的数据库运行
在独立的专用服务器上—— 换句话说,它相对于其他层是分布式的。这样做有几个很好的理
由:
● 数据库软件复杂而昂贵,而且通常需要高性能的硬件,所以分布数据库软件的多个副本将导致开销太大。
● 数据库可包含和关联由许多应用程序共享的数据。但是,只有当每个应用程序正在访问单独的数据库服务器而不是自己
的本地副本时,这种情况才可能发生。
● 数据库被设计为运行在独立的物理层上。它们提供最终的“chunky”接口:结构化查询语言(SQL)。(请参考原则 3 以获
得与 chunky 接口相关的细节。)
因此,当您决定使用数据库时,一般需要决定分布数据源逻辑。然而,决定分布表示逻辑会
更复杂一些。首先,除非所有应用程序用户都使用公共的终端(例如 AT M),否则表示层的某
些部分就必须分布到每个用户机上。但问题是分布到什么程度。当然,近来的趋势是在服务
器上执行大部分逻辑,而将简单的 HTML 发送到客户端 Web 浏览器。实际上,这正是遵守
了保守分布的原则。然而,它也需要每个用户交互都遍历服务器,从而这些用户交互才能产
生正确的响应。
在 Web 迅速发展之前,普遍的情况是在每个客户机上执行整个表示逻辑(遵守原则 2)。这样
可与用户更快地交互,因为它最小化了服务器上的遍历,但它也需要更新用户接口并被部署
到整个用户群。最后,选择使用哪一个客户机基本上与分布设计原则无关,但都与期望的用
户经验和部署问题有关。
数据逻辑几乎总是在一个独立的计算机上执行,表示层通常也是如此。现在只剩下业务逻辑,
它是整个问题组中最复杂的部分。业务层有时被部署到每个用户,而其他时候则被保存到服
务器上。在许多情况下,业务层被分解成两个或更多个组件。与用户接口交互相关的组件被
部署到客户机处,而与数据访问相关的组件则被保存到服务器上。这就遵守了下一个原则,
即相关内容本地化。
可以看到,您有许多分布选项。分布的时间、原因以及如何分布等受到很多因素的影响——
其中的许多因素又互相竞争。下面几个原则会提供进一步的指导。
原则 2:本地化相关内容
如果决定或被迫分布全部或部分业务逻辑层,那么应当保证经常交互的组件被放置在一起。
换句话说,您应当本地化相关内容。例如,参考图 1-1 所示的电子商务应用。这个应用程序
将客户组件、商品组件和购物车组件分隔到指定的服务器上,这会在表面上允许并行执行。
然而,当一件商品添加到购物车时,组件之间就会进行多次交互。每一次交互都会带来跨网
络方法调用的系统开销。因此,这种跨网络的行为会抵消掉并行处理带来的好处。再考虑到
几千用户会同时使用,可想其后果是破坏性的。如果还用前面提及的马和马车的类比,这种
情况就等同于利用马的每条腿而不是整匹马。

图 1-1 一个不成功的分布式应用例子
在本地化相关内容的同时,如何利用分布式编程(也就是并行处理)的作用呢?再买一匹马?
那就意味着复制整个应用程序并使它运行在另一台专门的服务器上。可以使用负载平衡方法
将每个客户机请求路由到特殊的服务器,即如图 1-2 所示的这种结构。基于 Web 的应用程
序经常通过在几个 Web 服务器上驻留相同的 Web 站点来使用这种模型,有时该设置被称为 We
b 场。
图 1-2 一个成功的分布式应用示例

对应用程序服务器进行复制和均衡负载可以很好地提高应用程序的容量或不伸缩性。然而,
您需要非常清楚如何管理状态。更详细的信息请参考原则 4。
原则 3:使用 Chunky 接口,而不是 chatty 接口
面向对象编程的思想之一是创建具有许多简单方法的对象,每一个方法都专注于一个特殊的
行为。考虑下面的 Customer 类。
Class Customer
{
public string FirstName()
{ get; set;}
public string LastName()
{ get; set;}
public string Email()
{ get; set;}
//etc. for Street, State, City, Zip, Phone ...
public void Create();
public void Save();
}
这种实现会受到大多数面向对象专家的肯定。但是,我的第一反应是:相对于调用代码而言
该对象在何处运行。如果直接在过程中访问 Customer 类,即使从大多数标准来看,这种设
计也是非常正确的。但是,如果这个类被执行在其他过程或机器中的代码所调用,则无论现
在或是将来,这种设计都是非常糟糕的。要了解具体原因,可考虑下面的代码,并且设想它
正运行在纽约的客户机上,而 Customer 对象运行在伦敦的服务器上。
Static void ClientCode()
{
Customer cust = new Customer();
剩余153页未读,继续阅读


















安全验证
文档复制为VIP权益,开通VIP直接复制

评论2