# Servers

> Configure gRPC servers with TLS, load balancing, and deployment options

gRPC servers can be configured with various options for security, performance, and scalability. Proper server configuration is crucial for production deployments.

## Basic server setup

Set up a basic gRPC server with multiple services:

```python title="server.py"
import grpc
from concurrent import futures
import user_service_pb2_grpc
import auth_service_pb2_grpc
from user_service import UserServiceServicer
from auth_service import AuthServiceServicer

def create_server():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    
    # Add services
    user_service_pb2_grpc.add_UserServiceServicer_to_server(
        UserServiceServicer(), server
    )
    auth_service_pb2_grpc.add_AuthServiceServicer_to_server(
        AuthServiceServicer(), server
    )
    
    # Listen on insecure port for development
    server.add_insecure_port('[::]:50051')
    
    return server

if __name__ == '__main__':
    server = create_server()
    server.start()
    print("gRPC server started on port 50051")
    server.wait_for_termination()
```

## TLS configuration

Configure TLS for secure production deployments:

```python title="secure_server.py"
import grpc
from grpc import ssl_server_credentials

def create_secure_server():
    # Load TLS certificates
    with open('server-key.pem', 'rb') as f:
        private_key = f.read()
    with open('server-cert.pem', 'rb') as f:
        certificate_chain = f.read()
    with open('ca-cert.pem', 'rb') as f:
        root_certificates = f.read()
    
    # Create server credentials
    server_credentials = ssl_server_credentials(
        [(private_key, certificate_chain)],
        root_certificates=root_certificates,
        require_client_auth=True  # Mutual TLS
    )
    
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=50))
    
    # Add services
    user_service_pb2_grpc.add_UserServiceServicer_to_server(
        UserServiceServicer(), server
    )
    
    # Listen on secure port
    server.add_secure_port('[::]:443', server_credentials)
    
    return server
```

## Server options

Configure various server options for performance and behavior:

```python title="configured_server.py"
import grpc
from grpc import compression

def create_configured_server():
    # Define server options
    options = [
        ('grpc.keepalive_time_ms', 30000),
        ('grpc.keepalive_timeout_ms', 5000),
        ('grpc.keepalive_permit_without_calls', True),
        ('grpc.http2.max_pings_without_data', 0),
        ('grpc.http2.min_time_between_pings_ms', 10000),
        ('grpc.http2.min_ping_interval_without_data_ms', 300000),
        ('grpc.max_connection_idle_ms', 60000),
        ('grpc.max_connection_age_ms', 300000),
        ('grpc.max_connection_age_grace_ms', 30000),
        ('grpc.max_receive_message_length', 4 * 1024 * 1024),
        ('grpc.max_send_message_length', 4 * 1024 * 1024),
    ]
    
    server = grpc.server(
        futures.ThreadPoolExecutor(max_workers=100),
        options=options,
        compression=compression.Gzip
    )
    
    return server
```

## Health checking

Implement health checking for load balancer integration:

```protobuf health.proto
syntax = "proto3";

package grpc.health.v1;

service Health {
  // Check health status
  rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
  
  // Watch health status changes
  rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse);
}

message HealthCheckRequest {
  string service = 1;
}

message HealthCheckResponse {
  enum ServingStatus {
    UNKNOWN = 0;
    SERVING = 1;
    NOT_SERVING = 2;
    SERVICE_UNKNOWN = 3;
  }
  ServingStatus status = 1;
}
```

Health service implementation:

```python title="health_service.py"
import grpc
from grpc_health.v1 import health_pb2
from grpc_health.v1 import health_pb2_grpc

class HealthServicer(health_pb2_grpc.HealthServicer):
    
    def __init__(self):
        self._service_status = {}
    
    def Check(self, request, context):
        service_name = request.service
        status = self._service_status.get(
            service_name, 
            health_pb2.HealthCheckResponse.SERVING
        )
        
        return health_pb2.HealthCheckResponse(status=status)
    
    def Watch(self, request, context):
        # Implementation for streaming health updates
        service_name = request.service
        
        while not context.is_active():
            status = self._service_status.get(
                service_name,
                health_pb2.HealthCheckResponse.SERVING
            )
            
            yield health_pb2.HealthCheckResponse(status=status)
            time.sleep(5)  # Check every 5 seconds
    
    def set_service_status(self, service_name, status):
        self._service_status[service_name] = status
```

## Reflection

Enable gRPC reflection for development and debugging:

```python title="reflection_server.py"
import grpc
from grpc_reflection.v1alpha import reflection

def create_server_with_reflection():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    
    # Add services
    user_service_pb2_grpc.add_UserServiceServicer_to_server(
        UserServiceServicer(), server
    )
    
    # Enable reflection
    SERVICE_NAMES = (
        user_service_pb2.DESCRIPTOR.services_by_name['UserService'].full_name,
        reflection.SERVICE_NAME,
    )
    reflection.enable_server_reflection(SERVICE_NAMES, server)
    
    server.add_insecure_port('[::]:50051')
    return server
```

## Load balancing

Configure client-side load balancing:

```python title="load_balanced_client.py"
import grpc

def create_load_balanced_channel():
    # DNS-based load balancing
    channel = grpc.insecure_channel(
        'dns:///user-service.example.com:50051',
        options=[
            ('grpc.lb_policy_name', 'round_robin'),
            ('grpc.dns_enable_srv_queries', True),
        ]
    )
    
    return channel