Ho bisogno di un server Python TCP in grado di gestire almeno decine di migliaia di connessioni socket simultanee. Stavo cercando di testare le funzionalità del pacchetto Python SocketServer in entrambe le modalità multiprocessore e multithread, ma entrambe erano lontane dalle prestazioni desiderate.Python socket stress simultity
In un primo momento, descriverò il client, perché è comune per entrambi i casi.
client.py server di
import socket
import sys
import threading
import time
SOCKET_AMOUNT = 10000
HOST, PORT = "localhost", 9999
data = " ".join(sys.argv[1:])
def client(ip, port, message):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
while 1:
sock.sendall(message)
time.sleep(1)
sock.close()
for i in range(SOCKET_AMOUNT):
msg = "test message"
client_thread = threading.Thread(target=client, args=(HOST, PORT, msg))
client_thread.start()
multiprocessore:
foked_server.py
import os
import SocketServer
class ForkedTCPRequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
cur_process = os.getpid()
print "launching a new socket handler, pid = {}".format(cur_process)
while 1:
self.request.recv(4096)
class ForkedTCPServer(SocketServer.ForkingMixIn, SocketServer.TCPServer):
pass
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = ForkedTCPServer((HOST, PORT), ForkedTCPRequestHandler)
print "Starting Forked Server"
server.serve_forever()
del server multithread:
threaded_server.py
import threading
import SocketServer
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
cur_thread = threading.current_thread()
print "launching a new socket handler, thread = {}".format(cur_thread)
while 1:
self.request.recv(4096)
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = ThreadedTCPServer((HOST, PORT), ForkedTCPRequestHandler)
print "Starting Threaded Server"
server.serve_forever()
Nel primo caso, con forked_server.py, solo 40 processi vengono creati e circa il 20 di quelli iniziano rompere in tanto con il seguente errore:
error: [Errno 104] Connection reset by peer
su un lato client.
versione filettata è molto più resistente e ospita oltre 4000 connessioni, ma alla fine inizia a mostrare
gaierror: [Errno -5] No address associated with hostname
Le prove sono state effettuate sulla mia macchina locale, Kubuntu 14.04 x64 su kernel v3.13.0-32. Questi sono i passi che ho fatto per aumentare le prestazioni generali del sistema: limite del kernel
- Sollevare il handle di file:
sysctl -w fs.file-max=10000000
- Aumentare l'arretrato di connessione,
sysctl -w net.core.netdev_max_backlog = 2500
- Alzare le connessioni massime,
sysctl -w net.core.somaxconn = 250000
Quindi, le domande sono:
- Wer e le prove corrette, posso contare su quei risultati? Sono nuovo di tutto questo materiale di Network/Socket, quindi per favore correggimi nelle mie conclusioni.
- È davvero l'approccio multiprocessore/multithreading non utilizzabile in sistemi con carichi elevati?
- Se sì, quali opzioni ci sono rimaste? Approccio asincrono? Quadri Tornado/Twisted/Gevent?
Per lo sfondo, google "* C10K *" e "* C10K Python *". –