我使用以下代码连接Redis服务器。 我看到TIME_WAIT状态的巨大连接。可能有什么不对?
root@ubuntu:~$ netstat | grep :6479 | grep TIME_WAIT |wc -l
9061
root@ubuntu:~$ netstat | grep :6479 | grep ESTABLISHED |wc -l
7
我想过使用下面的代码完成Redis服务器的操作后关闭连接。但是我得到了这个错误。
@staticmethod
def disconnectRedisConnection(r_server):
if r_server is not None and r_server:
r_server.connection.disconnect()
我收到以下错误,
r_server.connection.disconnect()
AttributeError: 'Redis' object has no attribute 'connection'
关于巨大的TIME_WAIT连接的任何想法/在使用Redis完成操作后关闭连接? 代码:
import threading
from time import sleep
import time, datetime
import traceback
import CACHE_CONST
import json
import os
import MySQLdb
import redis
# Static methods to interact with the Redis cache server
class CacheUtil(object):
# Log Errors
@staticmethod
def log_message(msg):
log_file = None
log_file = open (os.path.abspath(CACHE_CONST.REDIS_LOG_FILE), "a")
print(msg)
if (log_file):
message = time.strftime("%d-%m-%Y %H:%M:%S")
message += " :: " + str(msg)
log_file.write(message + "\n")
@staticmethod
def saveToCache(hashName, hashValue):
r_server = CacheUtil.getRedisConnection()
r_server.hmset(hashName, hashValue)
CacheUtil.disconnectRedisConnection(r_server)
@staticmethod
def getTrackerDetailsByID(trackerId):
trackerDetail = None
r_server = None
hashName = "tDetails:" + str(trackerId)
try:
if trackerId is not None:
print("getTrackerDetailsByID ")
r_server = CacheUtil.getRedisConnection()
trackerDetail = r_server.hgetall(hashName)
else:
CacheUtil.log_message("getDetailsByID failed with empty trackerId ")
except:
CacheUtil.log_message("getDetailsByID failed, ll fetch from DB " + str(traceback.format_exc()))
finally:
CacheUtil.disconnectRedisConnection(r_server)
return trackerDetail
@staticmethod
def getRedisConnection():
print("Get Redis Connection on Util ")
r_server = redis.Redis(host=CACHE_CONST.REDIS_SERVER_URL, port=CACHE_CONST.REDIS_SERVER_PORT, db=0, password=CACHE_CONST.REDIS_PASS_PHRASE, socket_connect_timeout=2, socket_timeout=2)
return r_server;
@staticmethod
def disconnectRedisConnection(r_server):
if r_server is not None and r_server:
r_server.connection.disconnect()
答案 0 :(得分:2)
实际上,当你拨打import threading
from time import sleep
import time, datetime
import traceback
import CACHE_CONST
import json
import os
import MySQLdb
import redis
r_server = redis.Redis(host=CACHE_CONST.REDIS_SERVER_URL, port=CACHE_CONST.REDIS_SERVER_PORT, db=0, password=CACHE_CONST.REDIS_PASS_PHRASE, socket_connect_timeout=2, socket_timeout=2)
# Static methods to interact with the Redis cache server
class CacheUtil(object):
# Log Errors
@staticmethod
def log_message(msg):
log_file = None
log_file = open (os.path.abspath(CACHE_CONST.REDIS_LOG_FILE), "a")
print(msg)
if (log_file):
message = time.strftime("%d-%m-%Y %H:%M:%S")
message += " :: " + str(msg)
log_file.write(message + "\n")
@staticmethod
def saveToCache(hashName, hashValue):
r_server.hmset(hashName, hashValue)
@staticmethod
def getTrackerDetailsByID(trackerId):
hashName = "tDetails:" + str(trackerId)
try:
if trackerId is not None:
print("getTrackerDetailsByID ")
trackerDetail = r_server.hgetall(hashName)
else:
CacheUtil.log_message("getDetailsByID failed with empty trackerId ")
except:
CacheUtil.log_message("getDetailsByID failed, ll fetch from DB " + str(traceback.format_exc()))
return trackerDetail
时,它会创建"客户端"对于你有连接池,而不仅仅是一个连接。
每次发送redis.set()或其他命令时,它都会从其连接池中检索连接,并使用此连接发送此命令并等待回复。请求完成后,它会将连接重新连接到连接池以便重用。所以你不需要自己管理连接。查看此https://github.com/andymccurdy/redis-py了解更多信息。
就像这样:
# COMMAND EXECUTION AND PROTOCOL PARSING
def execute_command(self, *args, **options):
"Execute a command and return a parsed response"
pool = self.connection_pool
command_name = args[0]
connection = pool.get_connection(command_name, **options)
try:
connection.send_command(*args)
return self.parse_response(connection, command_name, **options)
except (ConnectionError, TimeoutError) as e:
connection.disconnect()
if not connection.retry_on_timeout and isinstance(e, TimeoutError):
raise
connection.send_command(*args)
return self.parse_response(connection, command_name, **options)
finally:
pool.release(connection)
<强>更新强>
每次使用redis instance send命令时,都会调用此方法:
for j in $(seq 2 10)
do
printf "#!/bin/csh
set cnt = ${j}
set cnt2 = ${j}+1 > "prod_${j}.ll"
done
关于巨大的TIME_WAIT连接的任何想法/使用Redis完成操作后关闭连接
这是关于TCP连接终止过程的图像。当客户端(发起者)为服务器(接收者)FIN发送ACK时,它进入Time_WAIT状态。
TCP / IP引用的文字说明了第1卷:
当TCP执行主动关闭并发送时 最后的ACK,该连接必须保持TIME_WAIT状态两倍的MSL。这让TCP 如果丢失,则重新发送最终的ACK。重新发送最终ACK不是因为TCP重新发送ACK (它们不消耗序列号而不是由TCP重传),而是因为另一方 将重新传输其FIN(消耗序列号)。实际上,TCP将始终重新传输 FIN直到收到最终的ACK。
因此它将处于TIME_WAIT状态四分钟,之后,它将自动关闭连接。因为您打开新的tcp连接并经常关闭它,所以许多已关闭的连接将处于TIME_WAIT状态。
的更详细的文章