This is a mirror of official site: http://jasper-net.blogspot.com/

What They Didn’t Tell You About Creating Scalable HTTP Web Services

| Monday, April 11, 2011
Important (performance) factors to keep in mind when creating HTTP web services (with or without libSXE):

1. Accept()ing new sockets is an expensive and generally single-threaded kernel operation. Therefore it’s important to consider having as many long-lived ‘keep-alive’ HTTP 1.1 connections as possible. For example, your multi-threaded HTTP server might be able to have 500,000 simultaneous HTTP connections and perform at 250,000 keep-alive requests per second, but the server will still only be able to accept() new connections at a rate of 30,000 per second.

2. Parsing HTTP headers can be done with the sub-library lib-sxe-http. However, parsing the key/value structured headers is (unnecessarily) slow. Why slow? Because it’s necessary for the parser to loop over and examine each and every character in the headers in order to determine e.g. whether it’s an end of line character, or whether it’s one of the end of header characters etc. Although such a loop seems simple and fast, when we loop over, say, 250,000 or more headers per second then all that looping adds up into a lot of CPU instructions. Why unnecessarily slow? If you have control over the peer sending the HTTP request — e.g. because the peer is another of your servers or your javascript library etc — then it’s possible to build the never ‘pipelined’ requests and/or responses in such a way that it’s not necessary for your HTTP server to parse the headers. For simple GET requests, your server only needs to examine the last characters read in order to determine if they are the end of header characters. For POST requests and responses, the ‘content-length’ header is useful but in order to avoid parsing the headers then we can embed this info at the end of our body at a fixed, known location. And this technique works even if third-party HTTP proxies manipulate the headers en-route. Conclusion: Avoid parsing HTTP headers if possible. This blog post shows how parsing HTTP headers using node.js causes node.js to more than halve in perfermance: Node.Js Versus SXE “Hello World”; Node.Js Performance Revisited

3. The general rule of thumb is that the HTTP server nearly never has to close() a socket. The close() function is not as slow at the accept() function but it’s not for free either. Using close() might just lead to a malicious peer to connect again causing an expensive accept(). So assuming your server has a lot of memory then it’s probably a better trade off to just keep a badly behaving HTTP peer connection, and maybe even ‘tar pit’ it etc. The idea is that a little bit of memory for the peer buffers is a lesser evil than the potentially expensive close()/accept() bottleneck.

Read more: SIMONHF'S BLOG

Posted via email from Jasper-net

0 comments: