Golang / GoLang System Architecture and Testing Interview Questions
How do you build a production-ready gRPC client in Go with connection reuse and resilience?
A gRPC client wraps a ClientConn which manages a pool of HTTP/2 connections. Unlike HTTP/1.1, a single gRPC connection multiplexes many concurrent RPCs — connection reuse is critical.
// Production gRPC client setup func newUserClient(addr string) (pb.UserServiceClient, func(), error) { conn, err := grpc.NewClient(addr, // TLS in production grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})), // Keep-alive: detect dead connections grpc.WithKeepaliveParams(keepalive.ClientParameters{ Time: 10 * time.Second, Timeout: 5 * time.Second, PermitWithoutStream: true, }), // Retry policy (built-in retry) grpc.WithDefaultServiceConfig(`{ "methodConfig": [{ "name": [{"service": "user.UserService"}], "retryPolicy": { "maxAttempts": 3, "initialBackoff": "0.1s", "maxBackoff": "1s", "backoffMultiplier": 2, "retryableStatusCodes": ["UNAVAILABLE"] } }] }`), ) if err != nil { return nil, nil, err } cleanup := func() { conn.Close() } return pb.NewUserServiceClient(conn), cleanup, nil } // Using the client â always pass context func fetchUser(ctx context.Context, client pb.UserServiceClient, id int64) (*pb.User, error) { ctx, cancel := context.WithTimeout(ctx, 2*time.Second) defer cancel() return client.GetUser(ctx, &pb.GetUserRequest{Id: id}) } // Client interceptors (middleware for outgoing calls) conn, _ := grpc.NewClient(addr, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithChainUnaryInterceptor( metadataInterceptor, // attach trace ID to outgoing metadata retryInterceptor, ), )
Connection sharing: share one ClientConn per target service across the entire application. HTTP/2 multiplexing means thousands of concurrent RPCs share a single TCP connection — creating a new conn per RPC defeats the purpose and wastes resources.
More Related questions...