博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
02-Twisted 构建 Web Server 的 Socket 长链接问题 | 07.杂项 | Python
阅读量:6894 次
发布时间:2019-06-27

本文共 2844 字,大约阅读时间需要 9 分钟。

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文档库:讲述异步服务器编程; 介绍编写Web服务的高级技术; 用 Woven 模板实现动态Web服务器;第 4 部分讲述如何利用 SSH。或者。

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

当用此 Web Server 接收 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 最多是512个,而在 Linux 下这个限制为 32767 ,如果超过这个限制值,就会出现类似上面的异常。

我们暂且不管这个问题牵涉到 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 设置

类的初始化函数有一个可选参数 timeout ,它的默认值是 60*60*12 ,应该就是12小时。

这个 timeout 值经由 的初始化函数赋值给 twisted.internet.protocol 的 timeOut 属性,从而能够在底层 HTTP 协议发现连接闲置超时后交由 TimeoutMixin 处理。

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

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

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.』
有人回复说, 可以让 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
另一个样例参见:

参考资源:

1、?

2、参考 的文档 《》:

 
from twisted.web.resource import Resourcefrom twisted.web import serverfrom twisted.internet import reactorfrom twisted.python.util import printlnclass 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_YETresource = ExampleResource()

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

3、 ;

4、 ;

5、 ;

6、 。

转载地址:http://lcudl.baihongyu.com/

你可能感兴趣的文章
Sass函数:Sass Maps的函数-map-get($map,$key)
查看>>
HDU 1230 火星A+B
查看>>
C# foreach 为什么循环使用Foreach 效率要高
查看>>
oracle创建透明网关出现的问题
查看>>
对象和类
查看>>
分布式事务
查看>>
udp,select超时和recvfrom收不到数据原因
查看>>
将任意程序(如.bat文件)作为Windows服务运行
查看>>
【ElasticSearch篇】--ElasticSearch从初识到安装和应用
查看>>
Java命令参数说明大全
查看>>
PIE SDK创建掩膜
查看>>
(四)springmvc+mybatis+dubbo+zookeeper分布式架构 整合 - maven代码结构
查看>>
SQL查询到的数据放到DataSet中
查看>>
mybatis的selectOne和selectList没有数据返回时的问题
查看>>
批处理+组策略 实现规定时间段无法开机and定时关机
查看>>
我的升级
查看>>
centos 6.4 server 安装nginx
查看>>
JS OOP -04 JS中的公有成员,私有成员和静态成员
查看>>
Elevator
查看>>
nx-admin 引入Ueditor
查看>>