Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Consider alternatives to GRPC for generic write path? #1982

Closed
tomwilkie opened this Issue Sep 12, 2016 · 7 comments

Comments

Projects
None yet
4 participants
@tomwilkie
Copy link
Member

tomwilkie commented Sep 12, 2016

My aim is to support the new grpc generic write path in Frankenstein. On the surface this seems easy - however I've hit a number of problems that make me think it might be better to not use grpc just yet.

The explanation of the problems requires a little background. At weave, traffic to frankenstein need to go through a couple of services first, for SSL and to be authenticated. So traffic goes:

internet -> frontend -> authfe -> frankenstein
  • The frontend is Nginx, and adds/removes SSL. Its done this way for legacy reasons, so the certs can be managed in one place, although eventually we imagine we'll merge it with authfe. All traffic from frontend is sent to authfe.
  • Authfe checks the auth tokens / cookie etc and then picks the service to forward the RPC to.
  • Frankenstein accepts the reads and does the right thing with them.

First problem I hit was Nginx won't proxy http2 requests - it can accept them, but all calls downstream are http1 (see https://trac.nginx.org/nginx/ticket/923). This wasn't such a big deal, so it now looks like:

internet --(grpc/http2)--> frontend --(grpc/http1)--> authfe --(grpc/http1)--> frankenstein

Next problem was golang grpc server won't accept http1 requests (see https://groups.google.com/forum/#!topic/grpc-io/JnjCYGPMUms). It is possible to link a grpc server in with a normal go http mux, as long as the mux server is serving over SSL, as the golang http client & server won't do http2 over anything other than an SSL connection. This would require making all our service to service comms SSL. So I had a go a writing a grpc http1 server, and got pretty far. But is was a bit of a mess.

So finally I thought I'd make a separate grpc frontend for this, running in parallel with the frontend/authfe combo on a different port - and first up I'd need a grpc reverse proxy. Ideally we'd have some nice, generic reverse proxy that only knew about a map from service names -> downstream service, and didn't need to decode & re-encode every request as it went through. It seems like this can't be done with golang's grpc library - see mwitkow/grpc-proxy#1.

And then I was surprised to find you can't do grpc from browsers! See http://www.grpc.io/faq/ - not important to us, but I'm starting to question why we decided to use grpc in the first place?

It would seem we could have most of the benefits of grpc with protos over HTTP, and this wouldn't preclude moving to grpc when its a bit more mature? In fact, the grcp FAQ even admits as much:

Why is gRPC better than any binary blob over HTTP/2?
This is largely what gRPC is on the wire.

@tomwilkie

This comment has been minimized.

Copy link
Member Author

tomwilkie commented Sep 12, 2016

@juliusv

This comment has been minimized.

Copy link
Member

juliusv commented Sep 13, 2016

Briefly from airport: I don't think the main benefits of gRPC are how it transfers data, but the client library abstractions: load-balanced channels, service definitions with generated client stubs that support a bunch of options, etc.. And it's becoming a popular way for connecting services.

So much for the upsides, of course that doesn't negate the downsides you experienced.

@fabxc was the main champion for gRPC, so it'd be good to get his view on this as well.

@mattkanwisher

This comment has been minimized.

Copy link
Contributor

mattkanwisher commented Sep 13, 2016

An alternative is to put NGINX into TCP proxy instead of http proxy mode. We are currently using HAPROXY but in TCP mode. Not sure if that works for your usecase

@juliusv

This comment has been minimized.

Copy link
Member

juliusv commented Sep 13, 2016

@mattkanwisher I guess the problem is that you then can't do the auth and other L7 stuff like routing or TLS termination in the reverse proxy.

The discussion in #1487 already foreshadowed these problems with gRPC. While gRPC is great for intra-DC service communications, I'm now also wondering how suitable it is for these kinds of open-internet communications that cross infrastructure boundaries. Leaning somewhat towards going HTTP+protobuf again.

@louiscryan

This comment has been minimized.

Copy link

louiscryan commented Sep 14, 2016

Sorry to hear about your struggles.

Take a look at nghttpx instead of nginx for layer-7 if you can. Works very well. Nginx will support this use case but it will take time

@louiscryan

This comment has been minimized.

Copy link

louiscryan commented Sep 16, 2016

Meant to follow up on this sooner. If you do want to resurrect GRPC support I suggest taking a hard look at

https://github.com/lyft/envoy

which just shipped and is IMHO a pretty impressive product.
This part largely solves your browser issues

https://lyft.github.io/envoy/docs/configuration/http_filters/grpc_http1_bridge_filter.html

Using proto + HTTP is a perfectly reasonable solution for fully-buffered unary calls in the meantime

@lock

This comment has been minimized.

Copy link

lock bot commented Mar 24, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked and limited conversation to collaborators Mar 24, 2019

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.