【发布时间】:2011-07-07 12:42:19
【问题描述】:
我正在尝试实现一个基本库来发出 HTTP GET 请求。我的目标是通过 socket 连接 接收数据 - 提高 性能 的简约设计 - 线程、线程池的使用。
我有一堆按它们的主机名分组的链接,所以这里有一个输入 URL 的简单演示:
hostname1.com - 500 links
hostname2.org - 350 links
hostname3.co.uk - 100 links
...
由于性能问题,我打算使用套接字。我打算使用一些保持连接的套接字(如果可能的话,通常是这样)并发出 HTTP GET 请求。这个想法来自 urllib 在连续请求上的低性能,然后我遇到了 urllib3,然后我意识到它使用了 httplib,然后我决定尝试套接字。所以这是我到目前为止所完成的:
GETSocket class, SocketPool class, ThreadPool and Worker classes
GETSocket 类是 Python 的 httplib 的缩小版“仅限 HTTP GET”。
所以,我这样使用这些类:
sp = Comm.SocketPool(host,size=self.poolsize, timeout=5)
for link in linklist:
pool.add_task(self.__get_url_by_sp, self.count, sp, link, results)
self.count += 1
pool.wait_completion()
pass
__get_url_by_sp 函数是一个包装器,它调用sp.urlopen 并将结果保存到results 列表中。我正在使用一个由 5 个线程组成的池,它有一个由 5 个 GETSocket 类组成的套接字池。
我想知道的是,有没有其他可能的方法可以提高这个系统的性能?
我已经阅读了关于 asyncore here 的信息,但我不知道如何使用与提供的 class HTTPClient(asyncore.dispatcher) 相同的套接字连接。
另外一点,我不知道我用的是阻塞还是非阻塞socket,哪个对性能更好或者如何实现哪个。
请具体说明您的经验,我不打算导入另一个库只做 HTTP GET,所以我想编写自己的小库。
任何帮助表示赞赏,谢谢。
【问题讨论】:
-
多线程并不能真正使 HTTP GET 操作更快。您需要使用多个进程。
-
我知道,我的意思是同时从列表中请求和接收 5 个链接可以更快地检索列表中的所有链接。从这个意义上说,带宽是更快完成它的上限。进程或线程——它们最终提供的不一样吗?
-
"带宽是上限" True。但是线程都共享一个 OS 进程的 I/O 资源。多个操作系统进程不共享其 I/O 资源。
-
使用多处理或线程是我的意图,我特别关注如何改进我的套接字交互。但我可以使用这个想法,你能告诉我它会改进什么吗?由于我将在获取所有数据后处理检索到的数据,共享或不共享 I/O 资源是否会成为问题?
-
我不想这么说,但是如果您遇到性能问题,那么 httplib 不太可能是问题所在,它是套接字库之上的一个非常薄的层。如果您可以提供更多关于性能问题的解释,则可能可以解决根本原因,而不是分支编写自己的 http lib。
标签: python multithreading sockets threadpool http-get