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

简介:

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.杂项

目录
相关文章
|
1天前
|
存储 网络协议 关系型数据库
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
|
3天前
|
XML Web App开发 测试技术
python的Web自动化测试
【4月更文挑战第16天】Python在Web自动化测试中广泛应用,借助Selenium(支持多浏览器交互)、BeautifulSoup(解析HTML/XML)、Requests(发送HTTP请求)和Unittest(测试框架)等工具。测试步骤包括环境搭建、编写测试用例、初始化浏览器、访问页面、操作元素、验证结果、关闭浏览器及运行报告。注意浏览器兼容性、动态内容处理和错误处理。这些组合能提升测试效率和质量。
11 6
|
5天前
|
机器学习/深度学习 TensorFlow 算法框架/工具
使用Python构建简单的图像识别应用
本文将介绍如何利用Python语言及其相关库来构建一个简单但功能强大的图像识别应用。通过结合OpenCV和深度学习模型,我们将展示如何实现图像的特征提取和分类,从而实现对图像中物体的自动识别和分类。无需复杂的算法知识,只需一些基本的Python编程技巧,你也可以轻松地创建自己的图像识别应用。
|
7天前
|
SQL 安全 Go
如何在 Python 中进行 Web 应用程序的安全性管理,例如防止 SQL 注入?
在Python Web开发中,确保应用安全至关重要,主要防范SQL注入、XSS和CSRF攻击。措施包括:使用参数化查询或ORM防止SQL注入;过滤与转义用户输入抵御XSS;添加CSRF令牌抵挡CSRF;启用HTTPS保障数据传输安全;实现强身份验证和授权系统;智能处理错误信息;定期更新及审计以修复漏洞;严格输入验证;并培训开发者提升安全意识。持续关注和改进是保证安全的关键。
16 0
|
9天前
|
数据采集 NoSQL 搜索推荐
五一假期畅游指南:Python技术构建的热门景点分析系统解读
五一假期畅游指南:Python技术构建的热门景点分析系统解读
|
9天前
|
机器学习/深度学习 资源调度 数据可视化
使用Python和Keras进行主成分分析、神经网络构建图像重建
使用Python和Keras进行主成分分析、神经网络构建图像重建
13 1
|
10天前
|
数据库 开发者 Python
Python中使用Flask构建简单Web应用的例子
【4月更文挑战第15天】Flask是一个轻量级的Python Web框架,它允许开发者快速搭建Web应用,同时保持代码的简洁和清晰。下面,我们将通过一个简单的例子来展示如何在Python中使用Flask创建一个基本的Web应用。
|
10天前
|
前端开发 数据挖掘 API
使用Python中的Flask框架进行Web应用开发
【4月更文挑战第15天】在Python的Web开发领域,Flask是一个备受欢迎的轻量级Web框架。它简洁、灵活且易于扩展,使得开发者能够快速地构建出高质量的Web应用。本文将深入探讨Flask框架的核心特性、使用方法以及在实际开发中的应用。
|
13天前
|
网络协议 Java API
Python网络编程基础(Socket编程)Twisted框架简介
【4月更文挑战第12天】在网络编程的实践中,除了使用基本的Socket API之外,还有许多高级的网络编程库可以帮助我们更高效地构建复杂和健壮的网络应用。这些库通常提供了异步IO、事件驱动、协议实现等高级功能,使得开发者能够专注于业务逻辑的实现,而不用过多关注底层的网络细节。
|
14天前
|
JavaScript 搜索推荐 前端开发
音乐发现平台:借助Python和Vue构建个性化音乐推荐系统
【4月更文挑战第11天】本文介绍了如何使用Python和Vue.js构建个性化音乐推荐系统。首先确保安装Python、Node.js、数据库系统和Git。后端可选择Flask或Django搭建RESTful API,处理歌曲数据。前端利用Vue.js创建用户界面,结合Vue CLI、Vuex和Vue Router实现功能丰富的SPA。通过Vuex管理状态,Axios与后端通信。这种前后端分离的架构利于协作和系统扩展,助力打造定制化音乐体验。

热门文章

最新文章