I am a little bit confused about grpc and http/2. From what I learned, grpc is a RPC framework and can use different types of transports and http/2 is just one of the transports.
In golang, grpc.Dial() will create a connection to the server and the grpc server is created by grpc#Server.Serve(). So what is this connection? Is that a http/2 connection?
Thank you very much for your help.
When you connect to a server with gRPC, that does establish a single HTTP/2 connection that can be shared between many gRPC requests (the channel concept).
gRPC is indeed an RPC framework, built on HTTP/2. By default, it uses Protobufs as the serialization protocol, but that can be customised.
Think of gRPC as an RPC application layer over HTTP/2. To quote the FAQ:
"... gRPC is also a set of libraries that will provide higher-level features consistently across platforms that common HTTP libraries typically do not. Examples of such features include:
interaction with flow-control at the application layer
cascading call-cancellation
load balancing & failover
"
Related
I'm trying to connect to a grpc-service from a Java client. The problem is that this service is currently supporting only grpc-web over http1.1, this is because of a limitation of supporting http2 in Azure App service where the service is deployed.
The grpc-java client liberary from io.grpc only supports grpc over http2 protocol, which maskes sense, and unfortenatly is not working for me.
I managed to consume a service using HTTP client from apache and okhttp3 but this works for unary calls and it didn't work for a server-side streaming service.
Is any one aware of a grpc-web java client liberary that I could use or a work arround using convenienal Http for reading grpc-web server-side streaming service.
If I understand your question correctly, you want a Java client for gRPC-Web so that your client can talk HTTP/1.1 through a gRPC-Web proxy (e.g. Envoy gRPC-Web) because you're unable to talk HTTP/2 directly to your service because of the Azure networking limitation?
In theory this should be possible. The JavaScript implementation is because, in-browser, there's no alternative except JSON transcoding. The JavaScript implementation does implement server-side streaming, which is another requirement and confirms that this should be possible over HTTP/1.1.
However, in a quick search I found no other (i.e non-JavaScript) client implementations of gRPC-Web.
The requirement of my application is to send the data from the server to the client once the connection is established over HTTP/2.
I have opted to go with a combination of SSE for frontend and HTTP/2 Pusher in the backend.
But since gRPC is in general availability for the browser clients, I am thinking to switch to gRPC (because of simpler structure and protobufs) but I couldn't find any performance benchmarks for these two.
So whats better Http/2 with Pusher making a uni-directional channel or gRPC with a bi-directional channel.
I'm newbie of grpc and have played with simple grpc clients of java, go, and python. I know basic http and https but not familiar with protocal details. So this question may be rediculous to you but I didn't find any explaination online.
I know grpc has insecure(go: grpc.WithInsecure(), python: grpc.insecure_channel, java: usePlaintext()) and secure mode(TLS). and grpc is based on httpv2, and http has security mode(https).
So what if use insecure grpc with https? Is the overall data transfer safe?
And what if use TLS grpc with https? Is there performance overhead(becuase I think the messages are encrypted twice)?
Thank you for any answer, any exsiting webpages explaining such topic that will be best!
Insecure implies http. And TLS implies https. So there's no way "to use insecure grpc with https", as at that point it is then http.
There is no double-encryption. The gRPC security mode is the same as the HTTP security mode.
Using gRPC over TLS is highly recommended if you gRPC server is serving requests coming from outside(external network). For example you're creating front end app in javascript serving user requests. Your javascript app make call to your gRPC server for APIs your server provide. Your javascript communicate to your gRPC server through stub created in javascript end. At the end of your gRPC server, you need to set tls mechanism to secure communication between your javascript app and your gRPC server(because requests coming from outside).
gRPC somehow mostly used for internal services communication inside internal network in microservice architecture. You don't need to set tls for internal network usage since requests coming from your own environment from within your watch.
If you want to apply something like "gRPC over HTTPS", then you need something like gateway to map your http call to your gRPC server. Check this out.
You need to compile your proto file as gateway service definitions as well using provided tools. Now you can create your normal http server with tls enabled through something like http.ListenAndServeTLS(...). Dont forget to register your grpc server to the http server using the service definitions compiled from the proto file. With this all your requests to are encrypted with tls to your http server like normal rest apis do, but get proxied to gRPC server you defined. There's no need to enable tls at your gRPC server since it has been enabled in your http server.
I'm just curious if I'm missing something in http2 that would make it more efficient in service-to-service communication, for example in a microservice architecture.
Are its improvements just related to end-users (browsers)?
If you are issuing many concurrent requests between microservices, then there's benefit from connection multiplexing. You do not need to manage TCP connection pools on the client, and restrict the number of incoming TCP connections at the service side.
Some services might benefit from server push, though it really depends on what the service does.
Headers compression can be useful if you have high traffic volumes to the service with repeated meta-data. More information can be found here.
In summary, yes, it is designed more with end users in mind, but there's value for RESTful microservices as well, especially due to connection multiplexing.
HTTP/2 adds an additional aspect to service-to-service communication that was not mandatory with HTTP/1.1. And that is security in form of SSL/TLS.
Although not required by the RFC standard, almost all HTTP/2 servers and clients will only support HTTP/2 over TLS, which makes encryption de facto mandatory.
So if you want to offer and consume microservices over HTTP/2, you have to think about ways to create, manage and distribute SSL-certificates to servers and clients.
Consequently, moving to HTTP/2 means introducing a new stack of technology, e.g. a public key infrastructure, to your service eco system.
Another way to make your services HTTP/2-ready for your service consumers would be to place a reverse proxy between your HTTP/2-enabled consumers and your HTTP/1.1 services.
The proxy would terminate the HTTP/2 connections from the consumers and translate them into HTTP/1.1 requests for your servers (and vise-versa).
This would implement a separation of concern, where your services would only be responsible for their business-logic stuff, while the proxies would handle the certificates and encryption. But again, you would add more complexity to your system.
More Complexity, but also better use of network resources
More complexity is what you are paying with. But you get a smarter consumption of network resources for it. With HTTP/1.1 you can have multiple TCP connections between one client and a server. And opening multiple connection is almost always necessary to overcome HTTP/1.1's performance drawbacks.
Establishing TCP connections is an expensive task, though. In order to create them DNS lookup, TCP handshake and SSL handshake are necessary.
HTTP/2 limits the number of open TCP-connections between one client and one server to exactly one (1). But at the same time, HTTP/2 brings us connection multiplexing, i.e. you can have multiple HTTP conversations simultaneously over the same TCP connection (HTTP/1.1: 1 TCP-connection = 1 HTTP connection).
Websocket is designed in such a way that its servers can share a port with HTTP servers, by having its handshake be a valid HTTP Upgrade request.
I have a doubt in this design philosophy.
Any ways the WebSocket Protocol is an independent TCP-based protocol.
Why would we need this HTTP handshake(upgrade request) and a protocol switching. Instead why can't we directly(& independently) follow a websocket like protocol?
To quote from the IETF 6455 WebSocket spec:
The WebSocket Protocol attempts to address the goals of existing
bidirectional HTTP technologies in the context of the existing HTTP
infrastructure; as such, it is designed to work over HTTP ports 80
and 443 as well as to support HTTP proxies and intermediaries, even
if this implies some complexity specific to the current environment.
However, the design does not limit WebSocket to HTTP, and future
implementations could use a simpler handshake over a dedicated port
without reinventing the entire protocol.
In other words, there is a vast infrastructure for HTTP and HTTPS that already exists (proxies, firewalls, caches, and other intermediaries). In order to increase the chances of being adopted widely, the WebSocket protocol was designed to allow adjustments and extensions to the existing infrastructure without having to recreate everything from scratch to support a new protocol on a dedicate port.
It's also important to note that even if WebSocket protocol were to get rid of the HTTP compatible handshake, it would still need a handshake of almost equivalent complexity to support security requirements of the modern web so the browser and server can validate each other and to support CORS (cross-origin request sharing) securely. Even "raw" Flash sockets do a handshake with the server via the security policy request prior to creating the actual socket.