Node.js is one good solution. It uses only one thread for your server and everything runs within it. When the requests come flying in, Node.js takes them one at a time and hands them to the single function that was specified when the server is invoked. If you thought that a Java Server Page, a Java Servlet, or a PHP file was a lightweight way of building a website, you'll be impressed with the efficiency of this:
What? If you're going to point out that a JSP or PHP file may be as simple as the words "hello world," stop right there. You have to think beneath the surface and remember everything that the Java Servlet container or PHP server does for you. You may just write "hello world" in a JSP, but Java will burn 2MB of RAM creating a thread that supports the code that will eventually output the thread "hello world." The JSP might seem simple, but it's not.
Node.js does very little except grab the incoming request, call the function website, and marshal the results out the door. This single-mindedness lets it juggle all of the requests hammering at the port and dispatch them quickly.
I've seen standard-issue desktop machines easily handle thousands of requests more or less simultaneously. The data goes in and out like lightning because everything is handled in RAM and probably in the cache. Simple websites are surprisingly efficient.
But it's important to recognize that some of this lightning speed comes from leaving out other features. Running everything in one thread means everything can back up if that thread gets overloaded. All of the work that Java spends on putting clean, fresh sheets on the bed really pays off if one thread takes a long time to finish.
To make this happen, I created a simple server that takes a value "n" and adds up all of the numbers between 1 and n. This, by the way, is a purely CPU-bound operation that should use only two registers. It can't get hung up by waiting for RAM or the file system. The server was just as fast as before. I had to feed my underpowered desktop (1.83GHz Intel Core Duo) numbers like n=90000000 before it seemed to pause at all. That's a 9 with seven 0s after it. The answer had 16 digits in it.
When I fed fat numbers to the server, I found that all of the other requests would get in line behind it. When the workload is short, Node.js seems to be multitasking because it gets done with everything so quickly. But if you find an item that weighs down the server, you can lock up everything in a queue behind it.