One of the good things about the server performance testing that I’ve been doing recently is that I have been able to witness some rather rare failure conditions in action and seen how The Server Framework handles them.
When using IO Completion Ports for asynchronous IO you get notifications when reads and write complete. Read completions are obviously an important event, it’s where you receive incoming data. Write completions, on the other hand, are often viewed as less important.
A long time ago when I wrote my first article on high performance TCP/IP servers for Windows using IO Completion ports over on CodeProject I complained that “Also the more complicated examples, ones that used IO completion ports for example, tended to stop short of demonstrating real world usage. After all, anyone can write an echo server… “
Yet here I am, three and a half years later with a huge collection of different kinds of echo server.
For the last week or so I’ve been working on measuring and improving the performance of The Server Framework. The latest release of the free version of my asynchronous, windows, IOCP based, socket server framework can now be obtained from here at ServerFramework.com.
This week I’ve had several potential new clients asking about performance numbers for various aspects of the system and so I thought it best to do some measuring.
I’ve been spending some time pushing the limits of The Server Framework, my IO Completion Port based socket server framework, to see how many connections my servers can handle and what happens when system resources run out. Earlier postings on the subject are here and here.
This morning I fired up one of my older server boxes and ran the server on that rather than on my dev box. It effortlessly managed 64000 concurrent connections.
But mostly me. ;)
During yesterday’s investigations into handling lots (30,000+) of socket connections to a server built with The Server Framework I took a few things for granted. I should have been a bit more thorough rather than just assuming I knew what I was doing.
Today I did some more tests.
I was a little surprised that flicking the switch on my server framework so that it posted zero byte reads had no affect on the limit of connections that I could support.
I’m doing some research for a potential client. They need a TCP/IP server that handles ’lots’ of concurrent connections. Their own in-house server code currently fails at 4-6000 connections and I’m putting together a demo for them of how The Server Framework supports 30000 connections on 1GB of ram before running into non-paged pool restrictions… Whilst doing this I ran into an ‘interesting’ feature of WSAAccept() (or, perhaps, simply of an LSP that’s installed on my machine…).
I’ve been merging my UDP framework development branch back to main, building all of my example servers and running all of the “black box” server tests for The Server Framework. In doing so I’ve experienced the pain of changing virtual function signatures. This is one area where C# syntax is definitely better than the C++ syntax…
The Server Framework relies on derivation for extension and use. That wasn’t one of my brightest ideas.
I just ran my OpenSSL echo server test harness and ran the server under the deadlock tool. The results are interesting and show that the main source of lock contention on the server is for the lock that protects the buffer allocator. Every read or write requires a buffer to be allocated and released. The SSL server actually requires more than one buffer for each read and write as passing the data through the SSL connector causes further buffer allocations.
I’ve been working on The Server Framework this week. A client wanted a version of the latest framework with UDP support added. They’d taken the freely available version of the code a couple of years ago and I’d given them some hints as to how they could get it to deal with UDP. This worked well for them and they’ve built a rather large VOIP system on top and now they’re having some performance problems.
OpenSSL is an open source implementation of the SSL and TLS protocols. Unfortunately it doesn’t play well with windows style asynchronous sockets. This article, which was first published in Windows Developer Magazine and then reprinted on my company web site, provides a simple connector that enables you to use OpenSSL asynchronously.
A new posting in the blast from the past reprints area. The article is here.