本章提要
通信(communication)是网络应用程序设计的基础。本章就通信设计空间(design dimension)作了领域分析(domain analysis),介绍了网络应用程序之间相互作用的规则(rule)、形式(form)和抽象层次。在本章中,我们将论及以下设计空间:
l 无连接协议与面向连接协议;
l 同步及异步消息(message)交换;
l 消息传递与共享内存。
1.1 无连接协议与面向连接协议
所谓协议(protocol),就是一组规则,用来指定“控制信息”和“数据信息”如何在通信实体(譬如,在网络计算环境内部相互作用的应用程序进程)之间交换。协议一般分为无连接(connectionless)和面向连接(connection-oriented)两种。在这一设计空间,需要权衡的地方主要涉及延迟(latency)、可伸缩性(scalability)和可靠性(reliability)。
无连接协议提供的是“面向消息的(message-oriented)”服务。其中,每一条消息都可以独立寻址和发送。无连接协议一般采用“尽力(best-effort)”发送语义。这些语义不保证某组消息会以特定次序到达目的地,甚至根本不会到达目的地!
广泛使用无连接协议的例子有:用户数据报协议(UDP,User Datagram Protocol)和网际协议(IP,Internet Protocol)。这些协议可直接被多媒体应用程序(例如,IP语音或视频流[MSK00])使用,这些应用允许一定程度的数据丢失。UDP/IP还支持不可靠的多播(multicast)[DC90]和广播(broadcast)功能,允许一个发送者和一组接收者进行通信。
面向连接协议提供的是可靠、有序、不重复的发送服务。对那些不允许数据丢失的应用程序来说,这种协议十分有用。为了提高性能并保证可靠性,“面向连接”协议在发送端和(或)接收端交换并维护状态信息。传输控制协议(TCP,Transmission Control Protocol)是一种面向连接协议,它被运用于很多“面向会话(session-oriented)”的Internet应用中,如Web服务和电子邮件。
当使用面向连接协议时,应用程序和中间件开发者还必须作出以下设计选择:
l 数据成帧策略(data framing strategies)。“面向连接”协议提供了不同种类的数据成帧策略。例如,“面向消息”发送策略为某些“面向连接”协议所支持,如TP4和XTP。相反,TCP是一种字节流(bytestream)协议,不保护应用程序消息的边界(boundaries)。因此,在TCP上,如果某一应用程序通过4个send()调用传输4条不同的消息,会有一个或多个(可能大于4个)TCP数据段(segment)被传输给接收端。所以,如果某一应用程序需要“面向消息”发送,发送端和接收端就必须执行额外的处理,以将4条“在TCP上交换”的消息分割成帧。如果消息的长度总相同,并且永远没有网络错误发生,成帧相对来说简单;否则,这会成为一个不小的问题。
l 连接多路复用策略(connection multiplexing strategies)。在“面向连接”协议上传输数据,有这样两个一般性的策略,参见图1.1的描述和下面的说明。
1. 多路复用(multiplexed)。一个进程中的多个线程发出的所有客户请求都通过一条TCP

图1.1 可选的连接多路复用策略
连接传递给一个服务器进程,如图1.1(1)所示。连接多路复用的一个优点是,节省OS的通信资源,如socket句柄和连接控制块。这个策略的缺点是,难以编程[AOS+00]、缺乏效率[CB01]、缺乏确定性[SMFGG01]。这些问题源自“同步”机制和“环境切换”机制;在多路连接上,这些机制用来将“请求”和“应答”联系起来。
2. 非多路复用(nonmultiplexed)。每一个客户都使用不同的连接和对等服务程序通信,如图1.1(2)所示。“非多路复用连接”的主要优点是,可以更好地控制通信的优先级。在“非多路复用连接”设计中,每一个连接的优先级可以单独设定。这样一来,即使其他线程之间存在大量低优先级通信任务,高优先级通信也可以快速完成。这种设计避免了优先级倒置(priority inversion)现象——即低优先级线程占用一个单独的多路连接。此外,因为连接没被共享,这个策略的同步开销很小,因为发送和接收双向请求时不需要额外的锁定工作。和“多路复用连接”策略相比,“非多路复用”策略需要使用更多的OS资源,因而,在某些环境(譬如,大容量的Internet电子商务服务器)中,其伸缩性可能不是很好。
关于连接“多路复用”策略的设计及其利弊,请参阅[SMFGG01,SSRM00]提供的其他资料。
日志服务程序 => 在网络日志服务程序的实现中,我们通过“面向连接”的TCP/IP协议将日志记录从客户应用程序传输给日志服务器。我们只建立一次连接,并在客户/服务器会话期
间保留它,从而使建立连接的开销得以缓解。连接采用的是“非多路复用”方式,每个日志客户程序分别打开一个“到日志服务器”的TCP连接。
选择了TCP,就需要在TCP字节流上实现“数据分帧”机制(副栏9就这一点作了演示)。但由于TCP的普及,这一工作不会白费,它会带来OS平台之间、数据链路层网络之间的互操作性和可移植性。此外,传输层(而非应用程序)负责流量(flow)控制和拥塞(congestion)控制,负责重新传输丢失的数据包,并保证数据以正确的顺序发送。对那些不能丢失日志记录的应用程序来说,这些能力很重要。






