Hi Josh, Thanks for getting back ! Wouldn't having a single TCP connection be a bottleneck (assuming no layer-4 load balancer) especially if there is a slow reader, tcp flow control would limit other streams on that connection. In that case wouldn't having more connections help ?
Thanks, Nakul On Wednesday, October 17, 2018 at 6:26:00 AM UTC-7, Joshua Humphries wrote: > > *[email protected] <javascript:>* > > *moving [email protected] <javascript:> to BCC* > > In general, connections are not cheap, but stubs are. Actual > implementations for some languages differ, but Go complies with this. > > What that means is that, generally speaking, you should not try creating > the *grpc.ClientConn for each request. Instead create it once and cache > it. You *can* create the stub just once and cache it (they are safe to > use concurrently form multiple goroutines). But that is not necessary; you > could also create the stub for each request, using the cached connection. > > In practice, creating a new connection for each request will have overhead > in terms of allocations, creating and tearing down goroutines, and also in > terms of latency, to establish a new network connection every time. So it > is advisable to cache and re-use them. However, if you are not using TLS, > it *may be* acceptable to create a new connection per request (since the > network connection latency is often low, at least if the client and server > are in the same region/cloud provider). If you are using TLS, however, > creating a connection per request is a bit of an atrocity: you are not only > adding the extra latency of a TLS handshake to every request (typically 10s > of milliseconds IIRC), but you are also inducing a potentially huge amount > of load on the server, by making it perform many more digital signatures > (one of the handshake steps) than if the clients cached and re-used > connections. > > Historically, the only reason it might be useful to create a new > connection per request in Go was if you were using a layer-4(TCP) load > balancer. In that case, the standard DNS resolver would resolve to a single > IP address (that of the load balancer) and then only maintain a single > connection. This would result in very poor load balancing since 100% of > that client's requests would all route to the same backend. This would also > happen when using standard Kubernetes services (when using gRPC for > server-to-serve communication), as kubedns resolves a service name into a > single virtual IP. I'm not sure if the current state of the world regarding > TCP load balancers and the grpc-go project, but if it's still an issue and > you run services in Kubernetes, you can use a 3rd party resolver: > https://github.com/sercand/kuberesolver. > > ---- > *Josh Humphries* > [email protected] <javascript:> > > > On Wed, Oct 17, 2018 at 2:13 AM <[email protected] <javascript:>> wrote: > >> Hello, >> >> I intend to use grpc between two fixed endpoints (client and server) >> where the client receives multiple requests (the client serves as a proxy) >> which in turn sends a grpc request to the server. I wanted to know of the >> following would be considered good practice: >> >> a) For every request that comes in at the client, do the following in the >> http handler: >> a) conn := grpc.Dial(...) // establish a grpc connection >> b) client := NewClient(conn) // instantiate a new client >> c) client.Something(..) // invoke the grpc method on >> the client >> >> i.e Establish a new connection and client in handling every request >> >> b) Establish a single grpc connection between client and server at init() >> time and then inside the handler, instantiate a new client and invoke the >> grpc method >> a) client := NewClient(conn) // instantiate a new client >> b) client.Something(..) // invoke the grpc method on >> the client >> >> c) Establish a connection and instantiate a client at init() and then in >> every handler, just invoke the grpc method. >> a) client.Something(..) >> >> The emphasis here is on performance as I expect the the client to process >> a large volume of requests coming in. I do know that grpc underneath >> creates streams but at the end of the day a single >> logical grpc connection runs on a single TCP connection (multiplexing the >> streams) on it and having just one connection for all clients might not cut >> it. Thoughts and ideas appreciated ! >> >> Thanks, >> Nakul >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected] <javascript:>. >> For more options, visit https://groups.google.com/d/optout. >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
