4 ms·
Apart from the fact that you can do bidirectional data transfers with both, they are quite different: - grpc and HTTP/2 have a fixed paradigm (RPC plus streami
by Matthias247 8y ago
Apart from the fact that you can do bidirectional data transfers with both, they are quite different:
- grpc and HTTP/2 have a fixed paradigm (RPC plus streaming), whereas websockets are lower level and just describe how packets are transferred in each direction. For PRC you have to build something on top (e.g. following the WAMP conventions).
- grpc on top of HTTP/2 features per stream flow. Doing something like transferring a 4GB file on top of websockets without loading everything in memory is not as easy, since flow control is somewhere between basic and missing there.
- They have different ordering guarantees. grpc doesn't gurantee ordering between different requests, websockets guarantees it between messages.
- grpc comes with an interface definition language (protobuf) and code generators, which makes it much easier to build interoperable and backwards compatible services.
- gprc is proxyable per request, since each stream contains all relevant information (endpoint, parameters, auth, etc.). In total grpc and HTTP/2 are more stateless than a websocket connection, which could contain any kind of data.
- websockets work out of the box in browsers. The original grpc specification not, due to relying on features that are not exposed in browser APIs.
- techsin101 8y agoyou can't proxy websocket? i agree having contract for apis make it easier, but that could have been implemented over websocket instead of http2 just wondering? guaranteeing order, isn't that a good thing? transferring 4gb file over websocket, hmm... i actually never looked into it so i'll take the word here. .... I guess my overall question is why not gRPC over websocket instead of Http/2
- Matthias247 8y ago> you can't proxy websocket? You can proxy the whole connection. But not a single request/stream inside it, since there is no notion of such a thing in websockets. Compared to that grpc is basically built on standard HTTP/2 requests, where the method is denoted in the path. So you can use a standard HTTP/2 capable proxy or load balancer to route requests based on the method.
- notheguyouthink 8y agoSince you brought it up, what are your (or anyone in-the-know's) opinions on transferring large (~GB) files via gRPC? I recently implemented my first gRPC service and while it went nicely, I ended up writing a somewhat gross HTTP service along side the gRPC service to push and pull bytes to. After some short research (not testing myself!), it sounds like gRPC has significant overhead for large files due to having to chunk each file up, and the byte chunks end up not being efficient on CPU time/etc. Since my download service required no security/etc that gRPC might excel at, I just used gRPC for setting up the download/upoad, querying data, etc. It would have been much simpler to fully use gRPC for the upload and download, but it sounded costly. With no specific question, what are your thoughts on gRPC streaming "large" data? example perf tests: https://ops.tips/blog/sending-files-via-grpc/ https://ops.tips/blog/sending-files-via-grpc/
- Matthias247 8y agoIn an ideal implementation it should be pretty much as fast as plain HTTP/2, since the overhead is only a bit of protobuf framing between chunks. Which depending on the chunk size is negligible. However what I think comes into play in the benchmark is the behavior of the real library, and most likely the garbage collector. There might be paths in the code where the each chunk is freshly allocated and later on dropped. This gets more costly if chunks get bigger, which might explain the degradation in the measurements. In this example the client's chunk size is allocated once and everything else is a cheap slice, which should be good. However for the server I'm not sure, I guess it might allocate the buffer for each chunk just in order to drop it later on. Then you could investigate if you can give protobuf a prepopulated data structure with a reserved maximum size (e.g. from a pool) that it should use for deserialization, which might speed things up. Another thing which obviously comes into play is the performance of HTTP/2 implementations, which may vary a lot. I think even for Go, the HTTP/2 implementation in the net package and the one in grpc where different (not sure if they unified them now, there was an attempt on the way). So the question would need to be investigated separately for each of those.
- notheguyouthink 8y agoAppreciate your insight!