NX 的到来,第 2 部分
这是由 FreeNX 开发团队成员 Kurt Pfeifle 撰写的七部分系列文章的第二篇,
关于他参与 NX 技术的经历。同时,
他深入浅出地介绍了 NX 和
FreeNX 的内部运作原理,并概述了其未来的发展蓝图。库尔特在此描述的许多内容
都可以通过一两张最新的 Knoppix CD 进行重现和验证,
版本 3.6 或更高版本。自一年多前以来,Knoppix 现在已包含可用的 FreeNX 服务器设置和 NoMachine NX
客户端。“我如何认识 NX”系列的第一部分
在此
此处.
往返抑制对于远程 GUI 工作有多重要?为了理解
它的重要性,我们首先必须掌握 X 的一些基本机制
协议。
X 基础知识
X 协议规范了 X 服务器和 X
客户端之间的通信。X 客户端通常是一个需要 GUI 的程序
以方便用户交互。X 服务器
是一个专门的程序,它“绘制”该 GUI 以及
任何其他正在运行的程序的 GUI 到屏幕上。此外,X
服务器还处理用户发出的键盘和鼠标事件,并将
它们发送回 X 客户端程序,然后该程序根据
用户的命令执行操作。
图 1. 远程 Windows 的 NX 登录
会话。
如果 X 客户端程序需要在屏幕上绘制内容——例如一个新的
对话窗口——它会向 X 服务器发出一系列请求。大约 160
种不同类型的 X 请求,包括扩展,在
X 协议中指定。每个请求代表,例如,一个原始
图形元素——创建任何特定的窗口元素或完整窗口可能需要
一组特定的、可能很大的请求。这些
请求有时被称为操作码。如果您好奇,它们
在名为 Xproto.h 的源代码文件末尾以编程语言描述。如果您
正在运行基于 XFree86 或 X.org 的 X 服务器并安装了其源代码
头文件,则可以在您自己的硬盘上找到它。在我的 Knoppix-4.0 系统上,它位于
文件已安装。在我的 Knoppix-4.0 系统上,它位于
/usr/X11R6/include/X11/Xproto.h。
往返
X 客户端发送的一些请求也会征求来自
X 服务器的回复。X 客户端程序发出的每个请求及其
来自 X 服务器的回复,构成一次往返。往返会减慢
GUI 程序的响应速度,因为请求完成双向行程需要时间。
通常,用户不会注意到
X 往返。迄今为止,对于大多数使用 Linux 或 UNIX 的工作,
X 客户端和 X 服务器驻留在同一台机器上;也就是说,它们
在物理上很接近。这是最简单也是最
常见的 X Window 系统的使用方式。
然而,情况并非总是如此。X 客户端程序和 X 服务器可能驻留在
不同的主机上,彼此在物理上相隔遥远。它们甚至可能
相隔数千英里。X 协议并不在意:正如我们
所说,它是“网络透明的”。本地 X 服务器可以显示 GUI
远程运行的程序的输出到本地用户的屏幕上。它
还可以将本地用户的鼠标和键盘命令发送到远程 X
远处的客户端应用程序。
试试看。为此,您需要在远程 Linux 或 UNIX 上拥有一个用户帐户
机器。运行此命令
ssh -X your_username@remote_hostname xterm
稍作延迟后,这应该会在您的屏幕上显示一个新的 xterm 命令
窗口。它可能看起来与您的本地 xterm 完全一样。
唯一的区别可能是 shell 提示符显示不同的
用户名和主机。如果它对您不起作用,可能是因为
远程机器上的 SSH 设置为不允许 X 转发。然而,
这样的细节超出了本文的范围。
当应用程序启动并且它的第一个窗口显示在
屏幕上时,X 客户端/服务器往返的总量可能达到数千次。
数千次。因此请注意——显示在您
本地屏幕上的远程应用程序可能会感觉相当迟缓。
在完全本地的情况下——X 服务器和 X 客户端程序驻留在
同一主机上——这些往返不会花费太长时间来
完成。两者之间的通信通过 UNIX 域
套接字,一种自定义版本的命名管道,它们是您硬盘上的特殊文件
硬盘,用于进程间通信。因此,在
完全本地情况下发生的许多往返都相当快。
在远程情况下——X 服务器程序位于 localhost 而 X 客户端
程序位于不同的主机上——所有进程间通信
都通过 TCP/IP 网络套接字和远程网络
连接传输。这工作正常,但速度比
完全本地情况慢几个数量级。
############################################################################### +----------+ +----------+ | | --> responses <-- requests | | | | --> events | remote X | | | X --> errors X |applicat. | | local X | <---------------------------------------------------> |(or compl.| | display | many "round trips": request + response pairs) |KDE/GNOME | |(X server)| | session) | | | | | +----------+ +----------+ (c) Kurt Pfeifle, Danka Deutschland GmbH <kpfeifle at danka dot de> ###############################################################################
尽管运行在同一
机器上的 X 客户端和 X 服务器之间的通信是通过 UNIX 域套接字处理的,但本地 X 客户端和远程 X 服务器之间
的完全相同的通信是通过网络——TCP
和/或 UDP——套接字完成的。如果这是唯一的区别,仅此一项就会
导致巨大的性能差距。但还有另一个性能
阻碍因素:网络延迟。
链路延迟
任何链路的质量基本上由两个参数决定,
网络的带宽和延迟。带宽描述了每秒可以有多少字节
推入管道。另一端每秒流出的字节速率
应该相同。网络的延迟
描述了每个数据包从一端传输到
另一端需要多少时间。
通常,调制解调器链路的延迟为 200 到 500 毫秒。一个
ADSL 链路的延迟约为 50 毫秒。本地
以太网 LAN 链路的延迟,虽然如此,但小于 1 毫秒。UNIX
域套接字链路,例如上述
完全本地示例中的机器内部链路,远低于 0.1 毫秒。
图 2. NX 客户端在连接到 Windows XP
机器时,遇到 Windows 登录屏幕。
您可以使用 ping 命令测试任何网络链路的延迟。
ping 命令在您的终端窗口中显示往返时间。如果您
与您的对等方相距 4,000 公里——例如,
从加利福尼亚州到马萨诸塞州的距离——您的 ping 速度不可能
快于大约 44 毫秒。光速在真空中为每
秒 300,000 公里,通过光纤传输时速度大约慢 40%。
秒 300,000 公里,通过光纤传输时速度大约慢 40%。
如果您发送一个大的数据块,例如,需要 60 秒才能
完成单向行程,您可能不太关心链路的
延迟,即使它为总传输时间增加了一秒钟。
将往返时间减少 99.9% 并不会显着减少您的
总传输时间,就像您将延迟从
1,000 毫秒减少到 1 毫秒一样。将您的带宽增加一倍会有
更大的帮助。这样做会将您的数据
推入管道所需的时间缩短到 30 秒,接收端将在 31 秒后
确认传输完成。
如果您的数据流具有相反的
配置文件,则情况截然不同。如果您无法发送一个大的数据块,而必须发送许多
小数据块,并且如果您必须等待其中大多数的响应,
延迟会增加其对整体性能的影响。只有少量且
小数据块,例如数据包,可以在每个
毫秒周期内发送到管道中。但是您可能必须等待相对
较长的时间,大约 500 毫秒,才能获得远程端的确认或
响应。如果许多小数据块
需要确认——也就是说,如果它们导致往返——这些
物理事实确实开始影响远程 GUI 体验。
关于 X11 程序的冗长性
X 本身是一种高效的协议,乍一听可能
令人惊讶。然而,许多使用 X 的 GUI 程序
编码效率低下。透过通过调制解调器连接远程工作的用户的
眼睛来看待它们,您就能明白我的意思。
在许多领域,GUI 程序(KDE 和 GNOME 也是如此)都可以
得到改进,以使其在网络上运行得更快。
以一个简化且人为的示例作为说明。
最现代的桌面美化功能使用了大量的动画。以
下拉菜单为例:您经常会看到它以动画方式展开。
顺便说一句,我不赞同一些 UNIX 纯粹主义者的观点,他们认为
这些动画是“无用的”或“多余的”。它们可以帮助
用户理解系统。但我离题了。这种动画在 X 中是如何
表达的?X 应用程序告诉 X 服务器绘制
一次或多行像素。这通常是如何高效地完成的?
一般来说?既有低效的方式,也有优化的方式来做到这一点。
在这里,我使用一个简化的示例来突出每种情况。
在“坏”版本中,应用程序对 X 服务器说,“绘制这 10 行
像素,并在完成后报告。”X 服务器绘制并
报告。下一个请求是,“现在再绘制一行像素并
再次报告。”结果是往返又往返,直到漂亮的
菜单动画完成。
“好”版本有点不同。在这里,应用程序向
X 服务器的请求转化为:“绘制这一完整的像素
行系列,一行接一行,速度为每毫秒 1 行。报告
完成后返回。”这只需要一次往返。
如果用户仅在本地主机上使用其应用程序,则可能无法区分代码的“坏”版本和“好”版本。
版本,如果用户仅在本地主机上使用其应用程序,则可能无法区分代码的“坏”版本和“好”版本。但是,
如果在真实网络上的远程情况下运行,差异
开始变得明显:“好”版本仍然执行
流畅,而“坏”版本则缓慢且看起来不稳定。
问题是什么?
基思·帕卡德在他的“LBX 验尸”论文中这样说
X 应用程序通常是在高带宽/低延迟
环境中开发的,要么完全在一台机器内,要么可能通过
局域网。此类环境表现出超过
1MB/秒的带宽和小于 1ms 的延迟。将应用程序移动到串行
线路将带宽降低了 100 倍以上,并将
延迟增加了类似的量。
在高带宽/低延迟环境中工作的开发人员不会
注意到他的创作的低效率,如果它在其他时间
在不同的环境中运行。软件设计工程师编写
新软件的所需规范文档时,会忘记为
低带宽/高延迟测试提供规定。多年来,
整个 UNIX 和 Linux GUI 软件开发环境都偏离了
一个高度重视 X 网络透明性的范例。
图 3. 远程 Windows XP 会话正在运行
在我们的 Knoppix Linux 上的 NX 客户端中。
这种松懈的态度甚至影响了工具包。在许多方面,工具包
已成为过度往返的最大来源之一。然而,
不能责怪个别程序员。典型的 KDE 或 GNOME
开发人员可能没有意识到他编译的代码对网络性能
的影响。即使他意识到了,通常他也无能为力
。他选择了一个工具包来使用,并且他依赖于该
工具包固有的 X11 效率。
链路延迟
“但是等等”,您说。“硬件越来越好,功能也越来越强大。这难道不是来拯救我们了吗?”
“但是等等”,您说。“硬件越来越好,功能也越来越强大。这难道不是来拯救我们了吗?”
在网络计算中,带宽不如
延迟那样成为限制因素。如果带宽太低而需求太高,您可以添加一
根或两根或更多根电缆。这样做会在给定的
时间内通过电线传输更多数据。当然,购买
额外的线路需要花费更多钱,但我的意思是,没有硬性的技术限制。
此外,您可以期望未来网络带宽增加。
就带宽而言,目前
尚未看到硬性技术限制,但延迟的情况有所不同。延迟可以降低
到一定程度。您无法使信号的传播速度超过
光速,任何介质都无法做到。许多网络连接已经
在理论最佳值——光速——的 50% 以内,就
延迟而言。对于延迟,技术限制非常明显。
问题就在这里:提高带宽只能在一定程度上帮助加速远程
X11 连接。一旦达到该限制,
即使添加更多带宽也不会加快您的远程桌面
体验。在远程桌面环境中,您不会用
小数据包填充宽敞的电线,无论有多少
。在这里,任何增加的带宽都会闲置。相反,您大部分时间都花在
空管道上,等待小的往返完成。
典型的调制解调器往返需要 500 毫秒才能完成;典型的
ISDN 往返需要大约 50 毫秒。在这些条件下,
消除 X11 往返是加速远程
用户桌面交互的决定性手段。
我们将在本系列文章的第 3 部分中讨论更多关于 NX 往返抑制和流量压缩的内容,标题为“NX 如何(良好地)工作”。
我们将在本系列文章的第 3 部分中讨论更多关于 NX 往返抑制和流量压缩的内容,标题为“NX 如何(良好地)工作”。
要了解有关 FreeNX 的更多信息并亲眼目睹远程文档创建、打印和
发布的真实工作流程演示,请访问
发布的真实工作流程演示,请访问
Linuxprinting.org
展位 (#2043),参加
旧金山 LinuxWorld 会议与博览会
,时间为 2005 年 8 月 8 日至 11 日。我将在那里,
以及其他合作项目的成员。
Kurt Pfeifle 是一位系统专家,也是
Danka Deutschland GmbH 的咨询和培训网络打印小组的技术主管
,总部位于德国斯图加特。库尔特在全球开源和,
自由软件社区中以热情的 CUPS 布道者的身份而闻名;
他对 CUPS 的兴趣可以追溯到 1999 年 6 月的第一个 beta 版本。
他对 CUPS 的兴趣可以追溯到 1999 年 6 月的第一个 beta 版本。
他是《KDEPrint 手册》的作者,并为
KDEPrint 网站.
Kurt 还处理 Linuxprinting.org 的一系列事务,并为
Samba 项目编写了大部分打印文档。
Samba 项目编写了大部分打印文档。