02-Twisted 构建 Web Server 的 Socket 长链接问题 | 07.杂项 | Python

本文介绍了使用Twisted构建WebServer时遇到的Socket长链接问题及解决方案。通过调整Site类的timeout参数来减少ESTABLISHED状态的连接积累,避免了因文件描述符限制导致的服务异常。

02-Twisted 构建 Web Server 的 Socket 长链接问题

郑昀 201005 隶属于《07.杂项》

背景

利用几句简单代码可以构建一个 Web Server:

from twisted.internet import reactor
from twisted.web.server import Site
from my_webhandler import *
reactor.listenTCP(8080, Site(MyWebResource.setup()))

更复杂的运用参见IBM文档库:第 1 部分讲述异步服务器编程; 第 2 部分介绍编写Web服务的高级技术; 第 3 部分用 Woven 模板实现动态Web服务器;第 4 部分讲述如何利用 SSH。或者Configuring and Using the Twisted.Web Server

 

有时易造成 Socket 连接打开过多

当用此 Web Server 接收 PubSubHubbub Hub Server 发送过来的各种请求时,遇到了一个大问题:

随着时间推移,处于 ESTABLISHED 状态的 Socket 连接越来越多,慢慢抵达500多个,

TCP    X.X.X.X:8080     72.14.192.68:55693     ESTABLISHED
TCP    X.X.X.X:8080     74.125.126.80:59064    ESTABLISHED

最终导致服务爆出异常“too many file descriptors in select”,当此异常发生时,已无法挽救,只能重启服务。

这里的知识点是 Windows 下 select module 文件描述符(file descriptor)最多是512个,而在 Linux 下这个限制为 32767 ,如果超过这个限制值,就会出现类似上面的异常。

 

我们暂且不管这个问题牵涉到 PubSubHubbub Hub 喜欢保持长链接(Hubs MAY leave their TCP connections open and reuse them to make HTTP requests for freshly published events)并maybe重用连接的习惯。

既然 Server 端(指我们的 WebServer)无法保证总能断开闲置连接,那么可以通过设置闲置超时来解决这个问题。

 

twisted.web.server.Site 的 timeout 设置

twisted.web.server.Site 类的初始化函数有一个可选参数 timeout ,它的默认值是 60*60*12 ,应该就是12小时。
这个 timeout 值经由 twisted.web.http.HTTPFactory 的初始化函数赋值给 twisted.internet.protocol 的 timeOut 属性,从而能够在底层 HTTP 协议发现连接闲置超时后交由 TimeoutMixin 处理。


12小时太长。所以才会有许多处于 ESTABLISHED 状态的 Socket Connections 积累。所以我们缩短为 15分钟。So,我们只需要在开始执行:
reactor.listenTCP(8080, Site(MyWebResource.setup(),timeout=60*15))
即可。

这样,当 Socket 接收完数据后(此时调用self.resetTimeout()重置)连接闲置时间超时,将默认调用 twisted.protocols.policies.TimeoutMixin.timeoutConnection 函数,它的定义是:

def timeoutConnection(self):
        """Called when the connection times out.
        Override to define behavior other than dropping the connection.
        """
        self.transport.loseConnection()

也就是关闭连接。此时,会有输出提示的:

Timing out client: IPv4Address(TCP, '72.14.192.68', 43949)

经过实践,确实可以让Web Server 占用的 Socket 连接大为减少。

 

何为 TimeoutMixin

有人和我一样抱怨 Twisted 的这个问题:
『Client will not close the connect unit it disconnects itself. But the server can't control the connect. In some critical environment, the server has to maintain a lot of connect which maybe is idle.』
有人回复说, twisted.protocols.policies.TimeoutMixin 可以让 Server 主动断开连接:
class TimeoutTester(protocol.Protocol, policies.TimeoutMixin):
    timeOut  = 3
    timedOut = 0

    def connectionMade(self):
        self.setTimeout(self.timeOut)

    def dataReceived(self, data):
        self.resetTimeout()
        protocol.Protocol.dataReceived(self, data)

    def connectionLost(self, reason=None):
        self.setTimeout(None)

    def timeoutConnection(self):
        self.timedOut = 1
另一个样例参见:
http://code.google.com/p/proxy65/source/browse/trunk/proxy65/socks5.py

 

参考资源:

1、How to set client timeout with reactor.listenTCP?

2、参考 twisted 的文档 《Knowing When We're Not Wanted》:

Sometimes it is useful to know when the other side has broken the connection. Here is an example which does that:

from twisted.web.resource import Resource
from twisted.web import server
from twisted.internet import reactor
from twisted.python.util import println

class ExampleResource(Resource):

def render_GET(self, request):
request.write("hello world")
d = request.notifyFinish()
d.addCallback(lambda _: println("finished normally"))
d.addErrback(println, "error")
reactor.callLater(10, request.finish)
return server.NOT_DONE_YET

resource = ExampleResource()

This will allow us to run statistics on the log-file to see how many users are frustrated after merely 10 seconds.

3、关于Windows频繁打开关闭端口时出现的问题

4、Choosing a TCP Port for a Network Service

5、02-Twisted 构建 Web Server 的 Socket 长链接问题 | 07.杂项 | Python

6、Windows频繁打开和关闭端口可能引发的问题 | 07.杂项

转载于:https://www.cnblogs.com/zhengyun_ustc/archive/2010/05/26/1744298.html

<think>好的,用户的问题是关于如何在Linux中使用apt-get安装python-pyasn1和python-twisted-conch这两个包。我需要先回忆一下相关的安装命令,同时查看用户提供的引用内容,看看有没有相关的信息可以引用。 首先,用户提供的引用中有几个提到了使用apt-get安装Python相关的包。比如引用[3]中提到:“sudo apt-get install python-pymodbus sudo apt-get install python-pyasn1 python-twisted-conch”,这直接给出了安装这两个包的命令。看起来用户可能已经看到过这个命令,但需要确认是否正确。 接下来,我需要确保这些包在Ubuntu的仓库中存在。通常,Python的库包在Ubuntu中会以python-开头的形式存在。比如python-pyasn1和python-twisted-conch。不过需要注意,不同的Ubuntu版本可能会影响包的可用性。如果用户使用的是较新的Ubuntu版本,比如20.04或更高,可能需要使用python3-前缀的包,但根据引用中的示例,用户可能还在使用Python 2的版本,或者这些包仍然存在于旧版系统中。 另外,用户提到的引用[2]提到有些安装是不需要的,比如python-setuptools、python-dev、python-twisted,但这里用户需要的是python-twisted-conch,而python-twisted-conch可能属于Twisted框架的一部分,所以需要确认是否需要安装整个python-twisted包,还是单独安装conch部分。 根据引用[3]中的命令,直接安装python-pyasn1和python-twisted-conch即可。因此,正确的步骤应该是使用sudo apt-get install加上这两个包名。同时,需要提醒用户确保已经更新了软件包列表,避免找不到包的情况。如果遇到找不到包的问题,可能需要检查仓库源是否正确,或者尝试更新系统。 此外,用户可能遇到的问题包括依赖关系或包名变更。例如,在较新的系统中,可能包名已经改为python3-pyasn1,但用户提供的引用中使用的仍然是python-前缀,所以需要根据系统版本来调整。但根据用户的问题描述,他们明确要求使用apt-get安装,因此应优先按照引用中的命令进行指导。 总结回答步骤: 1. 更新软件包列表:sudo apt-get update 2. 安装两个包:sudo apt-get install python-pyasn1 python-twisted-conch 3. 验证安装是否成功。 4. 处理可能出现的错误,如包未找到时建议检查拼写或仓库源。 同时,需要注意用户提供的引用[3]中的命令已经包含这两个包,因此可以直接引用,并提示用户参考引用[3]中的步骤。</think>在Linux系统中使用`apt-get`安装`python-pyasn1`和`python-twisted-conch`的步骤如下: 1. **更新软件包列表**(确保获取最新版本信息): ```bash sudo apt-get update ``` 2. **执行安装命令**: ```bash sudo apt-get install python-pyasn1 python-twisted-conch ``` 此命令会同时安装两个包及其依赖项[^3]。如果遇到依赖冲突或包未找到的问题,可以尝试以下方法: - 检查包名拼写,确认系统支持`apt`仓库中的对应版本。 - 对于较新的Ubuntu版本,可能需要改用`python3-`前缀的包(例如`python3-pyasn1`)。 - 若提示缺少其他依赖,可按照提示补充安装。 --- ### 相关问题 1. 如何验证`python-pyasn1`是否安装成功? 2. `python-twisted-conch`的主要功能是什么? 3. 在CentOS系统中如何安装这两个包? 4. 如果`apt-get`提示找不到包,有哪些替代安装方法?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值