跳至主要内容

在尝试解决应用程序性能问题时,人们通常会低估通信层延迟的影响,但若想将精力集中在切实可行的解决方案上,正确理解这一点至关重要。

首先,我所说的通信层延迟是指数据包从本地系统传输到远程系统并返回所需的时间。通信层延迟的最大影响因素是距离——至少对于地理位置分散的主机而言是如此。另一个主要因素是本地主机与远程主机之间处理数据包的设备数量,其中包括路由器和防火墙等设备。 链路的带宽虽有影响,但其作用并不像大多数人想象的那样显著。带宽主要影响插入延迟——即数据包进入传输线路所需的时间,但传输线路上的信号传播速度取决于传输介质,而非带宽。在接下来的讨论中,我将直接使用“延迟”一词来指代通信层延迟。

为了说明延迟如何影响您的应用程序,假设您在客户端应用程序中输入一些数据并按下回车键。客户端应用程序会向服务器应用程序发送一条消息,等待响应,然后发送另一条消息,再次等待响应,如此循环往复,共进行 N 次“轮次”。在完成 N 次轮次后,客户端应用程序将结果呈现给您。

假设需要进行10次往返,且服务器应用程序处理客户端消息并返回响应需要1毫秒。 在1毫秒的延迟下,响应时间为10 * (1毫秒 + 1毫秒),即20毫秒。现在,如果你坐飞机前往芝加哥,而服务器仍位于波士顿,那么延迟将增加到50毫秒,响应时间变为10 * (50毫秒 + 1毫秒),即550毫秒。这种延迟虽然足以被察觉,但还不至于令人痛苦。 若将迭代次数增加到 100 次,响应时间将达到令人痛苦的 5.5 秒。你可能认为 100 次迭代过于夸张,但某些复杂的数据库查询或需要填写复杂表单的应用程序确实会产生如此多的迭代。 你知道你的应用程序需要多少个轮次吗?
通过 OSL 执行 copy_file 操作也会表现出这种行为。OSL 会以 4K 事务为单位发送文件。每个事务都需要响应,因此一个 1,000,000 字节的文件将需要 1,000,000 / 4,096 = 245 个事务,或者按照上一段的术语来说,需要 245 个轮次。 同样,假设处理每个事务需要 1 毫秒且延迟为 1 毫秒,则 copy_file 操作将耗时 490 毫秒。若将延迟增加至 50 毫秒,则耗时将延长至 12.495 秒。 若将文件大小增至1,000,000,000字节,则需要244,141次事务;对应的耗时为:延迟1毫秒时为488.282秒,延迟50毫秒时为12,451.191秒,即近3.5小时。

测量延迟最简单的方法是使用ping命令。

ping 192.168.200.197
Pinging host 192.168.200.197 : 192.168.200.197
ICMP Echo Reply:TTL 53 time = 84 ms
ICMP Echo Reply:TTL 53 time = 80 ms
ICMP Echo Reply:TTL 53 time = 81 ms
ICMP Echo Reply:TTL 53 time = 96 ms
Host 192.168.200.197 replied to all 4 of the 4 pings

 

遗憾的是,网络阻断 ping 数据包或主机忽略这些数据包的情况正变得越来越普遍,您甚至可以指示 STCP 忽略它们(从 15.3、16.2 和 17x 版本开始)。如果无法使用 ping,您可以使用 packet_monitor 来测量连接请求获得响应所需的时间。例如,使用以下命令启动 packet_monitor:start_process 'packet_monitor -numeric -time_stamp -filter -host A.B.C.D -port NNN' -privileged”。然后输入命令“telnet A.B.C.D NNN”。你应该建立多次连接并计算平均值。请注意,我连接的是远程主机上一个未使用的端口。这样可以减少跟踪中的数据包数量,但如果防火墙正在阻塞该端口,你可能需要使用一个已启用的端口。

 

start_process 'packet_monitor -numeric -time_stamp -filter -host 192.168.200.197
+ -port 6666' -privileged
ready 09:12:42
telnet 192.168.200.197 6666
Trying...
telnet: Unable to connect to remote host: The connection was refused.
ready 09:12:53
telnet 192.168.200.197 6666
Trying...
telnet: Unable to connect to remote host: The connection was refused.
ready 09:12:56
telnet 192.168.200.197 6666
Trying...
telnet: Unable to connect to remote host: The connection was refused.
ready 09:12:58
telnet 192.168.200.197 6666
Trying...
telnet: Unable to connect to remote host: The connection was refused.
ready 09:12:58
stop_process packet_monitor -no_ask
Stopping Noah_Davids.CAC (packet_monitor).
ready 09:13:07
d packet_monitor.out
%phx_vos#m16_mas>SysAdmin>Noah_Davids>packet_monitor.out 09-11-13 09:13:17 mst
Noah_Davids.CAC logged in on %phx_vos#m16 at 09-11-13 09:12:42 mst.
packet_monitor -numeric -time_stamp -filter -host 192.168.200.197 -port 6666
***********************************************************
WARNING: failure to specify a specific interface will cause
packet_monitor to bind to ALL interfaces on the module,
greatly increasing the amount of Streams memory used!!!
***********************************************************
dir                                                 icmp type
+     tcp
hh:mm:ss.ttt    len proto source             destination         src port dst p
+ort type
9:12:52.984 T 0004 TCP 172.16.77.128       192.168.200.197           62515
+ 6666 S
9:12:53.067 R 0000 TCP 192.168.200.197     172.16.77.128              6666
+ 62515 RA
9:12:56.643 T 0004 TCP 172.16.77.128       192.168.200.197           62516
+ 6666 S
9:12:56.724 R 0000 TCP 192.168.200.197     172.16.77.128              6666
+ 62516 RA
9:12:58.003 T 0004 TCP 172.16.77.128       192.168.200.197           62517
+ 6666 S
9:12:58.086 R 0000 TCP 192.168.200.197     172.16.77.128              6666
+ 62517 RA
9:12:58.805 T 0004 TCP 172.16.77.128       192.168.200.197           62518
+ 6666 S
9:12:58.887 R 0000 TCP 192.168.200.197     172.16.77.128              6666
+ 62518 RA
ready 09:13:07
Process finished.
Terminating Noah_Davids.CAC (packet_monitor). Process stopped by Noah_Davids.CA
+C.

 

Latency times:   58.887 - 58.805 = 0.082 == 82ms
58.086 - 58.003 = 0.083 == 83ms
56.724 - 56.643 = 0.081 == 81ms
53.067 - 52.984 = 0.083 == 83ms

您也可以使用我编写的一个程序,该程序无需使用 packet_monitor 即可计时连接。请参见 http://members.cox.net/ndav1/self_published/stcp_tping.doc。stcp_tping 命令要求您连接到远程主机上的一个活动端口。在此示例中,我使用的是 23 号端口(telnet),但任何活动端口均可使用。 命令末尾的数字 1 表示每秒发送一次请求。

stcp_tping 192.168.200.197 23 1
tping 192.168.200.197 23 1
Success/Tries=Percent    min/average/max success times
1/1=100.000%             83.284/83.284/83.284     Connection in 83.284 ms
2/2=100.000%             81.697/82.490/83.284     Connection in 81.697 ms
3/3=100.000%             80.858/81.946/83.284     Connection in 80.858 ms
4/4=100.000%             80.858/81.895/83.284     Connection in 81.743 ms
^C

 

如果没有现成的测量系统,该如何估算延迟呢?最简单的方法是找到同一地理区域内的某个系统,并测量到该系统的延迟。这样可以得到一个非常粗略的估计值。我通常喜欢选择高校作为参考,因为我知道它们的具体位置,而且它们很可能在校园内部署了自己的系统,至少规模较大的大学通常拥有高带宽的互联网连接。该网站 http://www.utexas.edu/world/univ/state/ 按州列出了许多大学的网站。网站 http://www.bulter.nl/universities/ 则按国家列出了世界各地大学的网站。请注意,通过企业VPN通信与通过互联网通信之间可能存在显著差异。

 

如何解决这个问题?恐怕无法解决。你或许可以控制部分链路的带宽,也可能对某些网络设备有所掌控,但距离显然是无法改变的。你能做的,就是修改应用程序,通过减少所需的传输轮次,使其对延迟的敏感度降低。

 

如果你打算使用 OSL 传输大文件到远距离,我只能说:别这么做。根据文件类型,你可以尝试使用 FTP、SFTP 或 SCP。 如果不行Stratus 站点上有一个名为tcp_save的应用程序(stratus),它允许你通过TCP有效地复制文件,而无需使用OSL。虽然需要一些配置,但可以显著缩短大文件的复制时间。