I'm using a Microservice architecture, where one service calls multiple services at a time with servers on nodejs
I was planning to use HTTP2 for API calls from one service to another, as it makes use of just one TCP connection with header compression.
However, HTTP2 needs TLS support, which implies a TLS handshake for every API call made by service to others, adding overhead roundtrips.
Although TLS1.3 takes only one round trip, still it adds up some extra overhead time.
My question is, Is it a good idea to use HTTP2 in the first place for API calls from one service to another, or it's better to continue with HTTP1.1
CodePudding user response:
HTTP2 most likely won't be more performant than ordinary HTTP1.1. It's only faster when you compare them in the context of HTTPS and parallel requests. HTTP2 allows to re-use the same TLS handshake, as well as use the same connection for multiple parallel requests (multiplex).
This is the reason you wouldn't set up HTTP2 between nginx and your app server - as you usually don't need TLS between them. So unless a) you need a secure connection between your services and b) you're planning to issue parallel requests - it doesn't seem to make sense to use HTTP2 for service-to-service communication.
CodePudding user response:
HTTP/2 does not require TLS support.
It just so happen that all browser vendors (and only them) decided to not support clear-text HTTP/2, but other clients such as curl, or Java clients, etc. do support clear-text HTTP/2.
However, for server-to-server communication, it is possible to use clear-text HTTP/2, and in fact this is a very common deployment.
It is also unfortunate that popular servers that are used as reverse-proxies or load balancers do not support invoking the back-end using HTTP/2, but that's just an implementation limitation.
HAProxy, for example, allows to offload TLS and then invoke the back-end with clear-text HTTP/2.
If you receive many multiplexed requests on the front-end, you can leverage HTTP/2 multiplexing towards the back-end, saving a lot of resources. A web page that requests say 30 multiplexed resources to the front-end will need to open or otherwise use 30 different connections to the back-end when using HTTP/1 (or less connections and be less efficient), versus using just 1 when using HTTP/2. When using HTTP/2 towards the back-end, you are not limited to just 1 connection, exactly like you are not limited to use only 6 connections when using HTTP/1 (these are just browser limits and do not apply to server-to-server communication).
Furthermore, back-end applications that use HTTP/2 features such as HTTP/2 push (albeit now being phased out) would work transparently using pure HTTP/2 communication, while won't be able to use the HTTP/2 features when using HTTP/1 communication towards the back-end. This is true for any other HTTP/2 feature such as PING frames, SETTINGS frames, etc. all of which are lost when communicating to the back-end application when using HTTP/1.
From the resources point of view, a smart reverse-proxy or load balancer can just offload TLS, and then blindly forward the HTTP/2 clear-text bytes to the back-end -- no need to interpret the bytes in either direction. There would be no need to parse the HTTP/2 request, convert it to the HTTP/1 format and viceversa when receiving the HTTP/1 response (from HTTP/1 to HTTP/2). This causes unnecessary CPU burning and TCP connection usage.
So, in principles HTTP/2 towards the back-end is very desirable.
I have worked with clustered systems where HTTP/2 for server-to-server communication was a huge benefit just for the many less resources used across the whole cluster.
The reality, however, is that the most popular front-end servers do not support HTTP/2 towards the back-end (mostly for non-technical reasons), so most of the times you just have to give up and deploy sub-optimal systems.
