There are sometimes small services which run and return very little data. Imagine a service which can return the number of users or a very simple text. This is important in the world of microservices.
So let's say you decided you want to make a service, and you discarded a non-HTTP option (which would exclude a binary protocol over websocket). Great, what next?
So I made some tests over the last days (with some help) and who or what speeds were achieved?
I used ApacheBench against loopback device, and I run against Spring-Boot to have a baseline. Apache Bench would run against Java/Spring Boot (on Windows 10) at around 5000 requests per second.
Using a very low level server using C#, I was running around 10.000 requests per second. Using Java with a raw http handler, the numbers were around 11.000.
Using JS/Node, my numbers are using the latest Node around 6000 req/s if it was using a raw low-level protocol.
Anyway, sometimes things are not so clear, so we tried running on Linux (although on a similar CPU, was not on my machine). Node was returning 12.000 req/s (but the machine had no Java numbers to compare with).
This made me suspicious and I was looking into ApacheBench and I found that AB had higher CPU usage than the server. Rewriting the web-client to be a simpler C# but with a real multithreaded client (ApacheBench works only singlethreaded), I noticed that the numbers got higher and even though the C# server and Java servers were simple raw-http handlers, they achieved on the same machine around 30K RPS on .Net, and 36.000 RPS on Java.
So what did I learn? If you have a simple server, for example for a microservice, I would discard SpringBoot, as Spring seems to be limited to around the speed of Node with Javascript. Use raw-http handlers written in .Net or Java. At least on Windows, a framework like Rapidoid had a very bad behavior, and it could be for many reasons, but it was not faster than Spring by a wide enough margin and .Net was always faster.
What should you choose between .Net and Java? I would say the line in the sand is very easy: if you like Java a lot, or .Net, there is only one choice. But if you like both (or you prefer the best on term of technology), pick .Net if you have a swarm of microservices (because a simple .Net microservice would use less memory, you can drop more services on the same VM/machine), as in 32 bit mode, the memory usage was around 10 MB (you read right, a web server with just 10MB of RAM usage, and in time of benchmark when many requests were asked, the RAM was never over 25 MB) per process, compared with Java with around 240 MB in Java case. I could say that 20% of higher performance for around 10X of memory is not a nice tradeoff.
Anyway, the code was done in a way that it has very few dependencies, so a "hello world" microservice, using around 30 MB it may not matter so much at startup, if it has to cache around 1 GB of data to respond very quicky. Though be prepared that a Java implementation would work a bit faster but in the same time it will be more taxing in memory.
No comments:
Post a Comment