慢速网页服务问题

3 投票
2 回答
552 浏览
提问于 2025-04-16 18:49

我在一台运行Linux(ubuntu)的机器上创建了一个Python网络服务:

import soaplib
import os

from soaplib.core.service import rpc, DefinitionBase, soap
from soaplib.core.model.primitive import String, Integer
from soaplib.core.server import wsgi
from soaplib.core.model.clazz import Array

def runcmd(cmd):
    fout = os.popen(cmd)
    out = fout.read()
    return out

class LinuxServices(DefinitionBase):
@soap(String, String,_returns=Array(String))
def df(self,server, user):
    L = []
    cmd = 'df -hP | grep "/"'
    output = runcmd(cmd).split('\n')
    for n in xrange(len(output)-1):
        out = output[n].split()
        L.append('%s;%s' % (out[5], out[4]))
    return L

if __name__=='__main__':
try:
    from wsgiref.simple_server import make_server
    soap_application = soaplib.core.Application([LinuxServices], 'tns')
    wsgi_application = wsgi.Application(soap_application)
    server = make_server('0.0.0.0', 7789, wsgi_application)
    server.serve_forever()
except ImportError:
    print "Error: example server code requires Python >= 2.5"

这个服务是根据这个例子做的:soaplib helloworld

然后我在Windows 7上创建了一个Silverlight项目,在这个项目里,我使用这个网络服务来获取我Linux服务器上的磁盘状态:

Silverlight项目中的服务:

public class LinuxService
{
    [OperationContract]
    public List<dfItem> df()
    {
        List<dfItem> dfItems = new List<dfItem>();

        WebReference.Application app = new WebReference.Application();

        var result = app.df(new WebReference.df()/*...*/);

        foreach (var item in result.dfResult)
        {
            string[] info = item.Split(';');

            dfItem dfItem = new dfItem()
            {
                MountPoint = info[0].ToString(),
                Usage = info[1].ToString()
            };
            dfItems.Add(dfItem);
        }
        return dfItems;
    }
    //...
}

在页面上调用服务:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    LinuxServiceClient client = new LinuxServiceClient();

    client.dfCompleted += new EventHandler<dfCompletedEventArgs>(client_dfCompleted);

    client.dfAsync();
}

void client_dfCompleted(object sender, dfCompletedEventArgs e)
{
    DG.ItemsSource = e.Result;
    DG.Visibility = System.Windows.Visibility.Visible;
}

我的问题是,当我访问这个页面时,从网络服务获取数据需要4到8秒(这个网络服务在局域网内)。

我真的怀疑网络带宽会导致这么长的等待时间……

我想问: 你们有什么建议可以让我加快这个速度吗?

系统信息:

  • UbuntuServer 11.04

  • Python: Python 2.7

  • Soaplib: soaplib 2.0.0-beta2


  • Windows: Windows 7 sp1

  • Silverlight: Silverlight 4

2 个回答

1

这里是一个简单的基准测试,使用了 suds 客户端和 soaplib 的 你好,世界 示例:

>>> def bench_soap(num):
...:     start = time.time()
...:     for i in range(num):
...:         hello_client.service.say_hello("Dave", 5)
...:     elapsed = time.time() - start
...:     print "Completed %s: ops in %.2f seconds : %.1f ops/sec" % (num, elapsed, num / elapsed)
...:     
...:     

>>> bench_soap(100)
Completed 100: ops in 0.40 seconds : 247.5 ops/sec

>>> bench_soap(1000)
Completed 1000: ops in 3.81 seconds : 262.5 ops/sec

我这边没有发现任何“延迟”或者类似的问题。Soaplib 看起来很快且反应灵敏,所以可能是 Silverlight 的问题?或者是两者之间有什么不兼容的地方?

3

我建议你使用wireshark http://www.wireshark.org/ 来“监听”网络上正在进行的对话,也就是记录(“捕获”)设备能看到的网络流量。

当你开始捕获数据时,看到的数据量可能会让你觉得有点吓人,但如果你能找到看起来像你的SOAP消息的片段(这应该很容易找到),你可以通过右键点击选择“跟踪TCP流”来快速过滤出这段对话。

这样你就能在一个弹出窗口中看到你写的SOAP服务和Silverlight客户端之间的完整对话。

如果一切看起来都正常,那就关闭这个弹出窗口。作为额外的好处,wireshark会把片段过滤成只显示这段对话的内容,并且会标注出每个片段发生的时间。你可以用这个来判断是客户端还是服务器响应慢。

如果看起来没有明显的延迟,那我建议你考虑一下,可能在请求Silverlight进行SOAP调用和它实际发起网络调用之间有相当大的延迟。

撰写回答