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.

Reply via email to