Twisted 服务器一天后崩溃
Twisted server crashes after one day
我写了一个 Udp twisted 服务器 运行 它使用以下命令:
nohup python Udpserver2.py &
一开始还不错,1天后就报错崩溃了。 nohup.out
中的错误信息是:
Unhandled Error
Traceback (most recent call last):
File "/usr/lib64/python2.7/site-packages/Twisted-15.4.0-py2.7-linux-x86_64.egg/twisted/python/log.py", line 84, in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
File "/usr/lib64/python2.7/site-packages/Twisted-15.4.0-py2.7-linux-x86_64.egg/twisted/python/context.py", line 118, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/usr/lib64/python2.7/site-packages/Twisted-15.4.0-py2.7-linux-x86_64.egg/twisted/python/context.py", line 81, in callWithContext
return func(*args,**kw)
File "/usr/lib64/python2.7/site-packages/Twisted-15.4.0-py2.7-linux-x86_64.egg/twisted/internet/posixbase.py", line 597, in _doReadOrWrite
why = selectable.doRead()
--- <exception caught here> ---
File "/usr/lib64/python2.7/site-packages/Twisted-15.4.0-py2.7-linux-x86_64.egg/twisted/internet/udp.py", line 248, in doRead
self.protocol.datagramReceived(data, addr)
File "UdpServer2.py", line 91, in datagramReceived
self.device_echo(data, str(host), int(port))
File "UdpServer2.py", line 19, in device_echo
cur.execute(sql)
File "/usr/lib64/python2.7/site-packages/MySQLdb/cursors.py", line 174, in execute
self.errorhandler(self, exc, value)
File "/usr/lib64/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
_mysql_exceptions.OperationalError: (2006, 'MySQL server has gone away')
我的 python 代码 UdpServer2.py
的结构如下:
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
import MySQLdb as mdb
conn = mdb.connect(host='localhost', user='root', passwd='123456', db='kj')
class KjEcho(DatagramProtocol):
def device_echo(self, msg, host, port):
device_no = msg[1:7]
sql = "select did from device where device_no='%s'" % (device_no)
cur = conn.cursor(mdb.cursors.DictCursor)
cur.execute(sql) #line 19 here
if 0 == cur.rowcount:
...
else:
...
cur.close()
def startProtocol(self):
print 'kj_udp_server starting...'
def datagramReceived(self, data, (host, port)):
print "receive msg"
if(18 != len(data)):
print 'len err'
return
if('0x86' != hex(ord(data[0]))):
print '0x86 err'
return
if(0 == ord(data[15])):
print 'from device'
self.device_echo(data, str(host), int(port)) #line 91 here
else:
print 'from mobile'
self.mobile_echo(data, str(host), int(port))
reactor.listenUDP(6000, KjEcho())
reactor.run()
第91行和第19行是上面指出的原因,如何解决,谢谢。
注意:有很多机器,每台机器每20秒向服务器发送一条消息
您不能中继 mysql 连接(或与此相关的任何套接字)在未指定的时间段内保持活动状态,尤其是在没有数据流经它的情况下。因此,不要只使用一个连接来重新获取游标,而是关闭与游标的连接,然后在需要时再次打开它。
所以本质上你想为这一行添加前缀
cur = conn.cursor(mdb.cursors.DictCursor)
设置 conn
然后追加以下
cur.close()
关闭 conn
,最有可能 conn.close()
。
非常感谢 Mai 和 Tymoteusz Paul
class KjEcho(DatagramProtocol):
def device_echo(self, msg, host, port):
device_no = msg[1:7]
sql = "select did from device where device_no='%s'" % (device_no)
conn = mdb.connect(host='localhost', user='root', passwd='123456', db='kj')
cur = conn.cursor(mdb.cursors.DictCursor)
cur.execute(sql)
if 0 == cur.rowcount:
...
else:
...
cur.close()
conn.close()
我觉得应该可以,但是对于连接,经常打开关闭,是不是用连接池比较好?
我写了一个 Udp twisted 服务器 运行 它使用以下命令:
nohup python Udpserver2.py &
一开始还不错,1天后就报错崩溃了。 nohup.out
中的错误信息是:
Unhandled Error
Traceback (most recent call last):
File "/usr/lib64/python2.7/site-packages/Twisted-15.4.0-py2.7-linux-x86_64.egg/twisted/python/log.py", line 84, in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
File "/usr/lib64/python2.7/site-packages/Twisted-15.4.0-py2.7-linux-x86_64.egg/twisted/python/context.py", line 118, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/usr/lib64/python2.7/site-packages/Twisted-15.4.0-py2.7-linux-x86_64.egg/twisted/python/context.py", line 81, in callWithContext
return func(*args,**kw)
File "/usr/lib64/python2.7/site-packages/Twisted-15.4.0-py2.7-linux-x86_64.egg/twisted/internet/posixbase.py", line 597, in _doReadOrWrite
why = selectable.doRead()
--- <exception caught here> ---
File "/usr/lib64/python2.7/site-packages/Twisted-15.4.0-py2.7-linux-x86_64.egg/twisted/internet/udp.py", line 248, in doRead
self.protocol.datagramReceived(data, addr)
File "UdpServer2.py", line 91, in datagramReceived
self.device_echo(data, str(host), int(port))
File "UdpServer2.py", line 19, in device_echo
cur.execute(sql)
File "/usr/lib64/python2.7/site-packages/MySQLdb/cursors.py", line 174, in execute
self.errorhandler(self, exc, value)
File "/usr/lib64/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
_mysql_exceptions.OperationalError: (2006, 'MySQL server has gone away')
我的 python 代码 UdpServer2.py
的结构如下:
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
import MySQLdb as mdb
conn = mdb.connect(host='localhost', user='root', passwd='123456', db='kj')
class KjEcho(DatagramProtocol):
def device_echo(self, msg, host, port):
device_no = msg[1:7]
sql = "select did from device where device_no='%s'" % (device_no)
cur = conn.cursor(mdb.cursors.DictCursor)
cur.execute(sql) #line 19 here
if 0 == cur.rowcount:
...
else:
...
cur.close()
def startProtocol(self):
print 'kj_udp_server starting...'
def datagramReceived(self, data, (host, port)):
print "receive msg"
if(18 != len(data)):
print 'len err'
return
if('0x86' != hex(ord(data[0]))):
print '0x86 err'
return
if(0 == ord(data[15])):
print 'from device'
self.device_echo(data, str(host), int(port)) #line 91 here
else:
print 'from mobile'
self.mobile_echo(data, str(host), int(port))
reactor.listenUDP(6000, KjEcho())
reactor.run()
第91行和第19行是上面指出的原因,如何解决,谢谢。
注意:有很多机器,每台机器每20秒向服务器发送一条消息
您不能中继 mysql 连接(或与此相关的任何套接字)在未指定的时间段内保持活动状态,尤其是在没有数据流经它的情况下。因此,不要只使用一个连接来重新获取游标,而是关闭与游标的连接,然后在需要时再次打开它。
所以本质上你想为这一行添加前缀
cur = conn.cursor(mdb.cursors.DictCursor)
设置 conn
然后追加以下
cur.close()
关闭 conn
,最有可能 conn.close()
。
非常感谢 Mai 和 Tymoteusz Paul
class KjEcho(DatagramProtocol):
def device_echo(self, msg, host, port):
device_no = msg[1:7]
sql = "select did from device where device_no='%s'" % (device_no)
conn = mdb.connect(host='localhost', user='root', passwd='123456', db='kj')
cur = conn.cursor(mdb.cursors.DictCursor)
cur.execute(sql)
if 0 == cur.rowcount:
...
else:
...
cur.close()
conn.close()
我觉得应该可以,但是对于连接,经常打开关闭,是不是用连接池比较好?