Optimizing sockets to 1000 requests/sec? (Was: Sockets and messaging services)
Stephen
shriek at gmx.co.uk
Wed Nov 14 12:21:46 EST 2001
> >> IMHO the SMTP and POP protocols provide the same benefit (and there
> >> are Python modules for those protocols).
>
> shriek> Using a mailserver as a messaging platform for middleware ?
>
> It's not all that far-fetched. I know some people have experimented with
> XML-RPC over SMTP (which is no longer XML-RPC, but that's a nit).
OK, let me show an example where I think we need some sort
of basic message queue ~
I've been trying to benchmark socket server and can't seem
to get it past serving 200 requests per second.
Here's the test code ~
# -----------------------------------------
# SOCKET SERVER CODE - JUST SENDS A REPLY
# -----------------------------------------
#! /usr/bin/python
import SocketServer, string, socket, time
total_requests = 0
class RequestServer(SocketServer.ThreadingTCPServer):
allow_reuse_address = 1
class RequestHandler(SocketServer.StreamRequestHandler):
def handle(self):
global total_requests
# ACCEPT :
host, port = self.client_address
request = ""
while 1:
line = self.rfile.readline()
if line in (None, "\r\n", ""):
break
request = request + line
request = string.rstrip(request)
self.wfile.write("Received OK")
total_requests = total_requests + 1
if total_requests % 100 == 0 :
print "%s - %s" % (total_requests, time.time())
def main():
server = RequestServer(("127.0.0.1", 8888), RequestHandler)
print "Listening to socket [%s:%s]" % ("127.0.0.1", 8888)
server.serve_forever()
# -------------------------------------------
# CLIENT CODE FOR TESTING
# -------------------------------------------
#!/usr/local/python
test_msg = "This is just a test message"
import socket, thread, time
total_sent = 0
NUMTHREADS = 20
def send_request() :
start = time.time()
global total_sent
for i in range(0,100) :
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1", 8888))
s.send("%s\n\r\n" % test_msg)
s.recv(512)
s.close()
total_sent = total_sent + 1
if total_sent % 100 == 0 :
print "total sent = %s" % total_sent
end = time.time()
print "exiting thread. duration %s" % (end - start)
total_sent = 0
for i in range(0,NUMTHREADS) :
thread.start_new_thread(send_request, ())
Results ~
When NUMTHREADS = 2, 200 requests are handled in < 0.5 secs
When NUMTHREADS = 5, 500 requests are handled in 2.5 secs
But when NUMTHREADS = 20, half the threads die with this error :
Unhandled exception in thread:
Traceback (most recent call last):
File "<stdin>", line 6, in send_request
File "<string>", line 1, in connect
socket.error: (10061, 'Connection refused')
and it just gets worse when NUMTHREADS = 50.
I'm guessing this means that the server is max'ed out and
can't handle any more.
How should I handle this error ? Yes, with a "try/except"
but what should the "except" do, because if the server is
too busy, it's probably no point retrying immediately.
So, you see, I was looking for something more immediate than
SMTP, that also takes care of the message queueing. Writing
code to manage the queue and buffering could be horrendous.
Is there any way to get this up to say 1,000 requests/sec peak load ?
In reality, I'm going to want to put some Database query
into the RequestHandler too so it'd be even slower.
Does this sound possible ?
Am-I-asking-too-much-of-Python-ly-your's,
Stephen
More information about the Python-list
mailing list