服务器
为生产部署设置和配置 gRPC 服务器
gRPC 服务器可以配置各种安全性、性能和可扩展性选项。正确的服务器配置对于生产部署至关重要。
基本服务器设置
设置具有多个服务的基本 gRPC 服务器:
server.py
import grpcfrom concurrent import futuresimport user_service_pb2_grpcimport auth_service_pb2_grpcfrom user_service import UserServiceServicerfrom auth_service import AuthServiceServicerdef create_server():server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))# Add servicesuser_service_pb2_grpc.add_UserServiceServicer_to_server(UserServiceServicer(), server)auth_service_pb2_grpc.add_AuthServiceServicer_to_server(AuthServiceServicer(), server)# Listen on insecure port for developmentserver.add_insecure_port('[::]:50051')return serverif __name__ == '__main__':server = create_server()server.start()print("gRPC server started on port 50051")server.wait_for_termination()
TLS 配置
为安全的生产部署配置 TLS:
secure_server.py
import grpcfrom grpc import ssl_server_credentialsdef create_secure_server():# Load TLS certificateswith 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 credentialsserver_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 servicesuser_service_pb2_grpc.add_UserServiceServicer_to_server(UserServiceServicer(), server)# Listen on secure portserver.add_secure_port('[::]:443', server_credentials)return server
服务器选项
配置各种服务器选项以优化性能和行为:
configured_server.py
import grpcfrom grpc import compressiondef create_configured_server():# Define server optionsoptions = [('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.proto
syntax = "proto3";package grpc.health.v1;service Health {// Check health statusrpc Check(HealthCheckRequest) returns (HealthCheckResponse);// Watch health status changesrpc 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.py
import grpcfrom grpc_health.v1 import health_pb2from grpc_health.v1 import health_pb2_grpcclass HealthServicer(health_pb2_grpc.HealthServicer):def __init__(self):self._service_status = {}def Check(self, request, context):service_name = request.servicestatus = 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 updatesservice_name = request.servicewhile 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 secondsdef set_service_status(self, service_name, status):self._service_status[service_name] = status
反射
为开发和调试启用 gRPC 反射:
reflection_server.py
import grpcfrom grpc_reflection.v1alpha import reflectiondef create_server_with_reflection():server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))# Add servicesuser_service_pb2_grpc.add_UserServiceServicer_to_server(UserServiceServicer(), server)# Enable reflectionSERVICE_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_balanced_client.py
import grpcdef create_load_balanced_channel():# DNS-based load balancingchannel = grpc.insecure_channel('dns:///user-service.example.com:50051',options=[('grpc.lb_policy_name', 'round_robin'),('grpc.dns_enable_srv_queries', True),])return channel# Using a load balancer with multiple targetsdef create_multi_target_channel():targets = ['user-service-1.example.com:50051','user-service-2.example.com:50051','user-service-3.example.com:50051',]# Use a service mesh or load balancerchannel = grpc.insecure_channel(f'ipv4:///{",".join(targets)}',options=[('grpc.lb_policy_name', 'round_robin')])return channel
Kubernetes 部署
在 Kubernetes 上部署 gRPC 服务:
grpc-service.yaml
apiVersion: apps/v1kind: Deploymentmetadata:name: user-servicespec:replicas: 3selector:matchLabels:app: user-servicetemplate:metadata:labels:app: user-servicespec:containers:- name: user-serviceimage: user-service:latestports:- containerPort: 50051name: grpcenv:- name: GRPC_PORTvalue: "50051"livenessProbe:exec:command: ["/bin/grpc_health_probe", "-addr=:50051"]initialDelaySeconds: 30readinessProbe:exec:command: ["/bin/grpc_health_probe", "-addr=:50051"]initialDelaySeconds: 5---apiVersion: v1kind: Servicemetadata:name: user-servicespec:selector:app: user-serviceports:- port: 50051targetPort: 50051name: grpctype: ClusterIP
监控和可观测性
为你的 gRPC 服务器添加监控和跟踪:
monitored_server.py
import grpcimport timefrom prometheus_client import Counter, Histogram, start_http_server# Prometheus metricsREQUEST_COUNT = Counter('grpc_requests_total','Total gRPC requests',['method', 'status'])REQUEST_DURATION = Histogram('grpc_request_duration_seconds','gRPC request duration',['method'])class MonitoringInterceptor(grpc.ServerInterceptor):def intercept_service(self, continuation, handler_call_details):method = handler_call_details.methodstart_time = time.time()def monitor_wrapper(behavior):def wrapper(request, context):try:response = behavior(request, context)REQUEST_COUNT.labels(method=method, status='OK').inc()return responseexcept Exception as e:REQUEST_COUNT.labels(method=method, status='ERROR').inc()raisefinally:duration = time.time() - start_timeREQUEST_DURATION.labels(method=method).observe(duration)return wrapperreturn grpc.unary_unary_rpc_method_handler(monitor_wrapper(continuation(handler_call_details).unary_unary))def create_monitored_server():# Start Prometheus metrics serverstart_http_server(8000)server = grpc.server(futures.ThreadPoolExecutor(max_workers=10),interceptors=[MonitoringInterceptor()])return server
环境特定配置
为不同环境配置服务器:
config.py
import osfrom dataclasses import dataclass@dataclassclass ServerConfig:port: intmax_workers: intenable_tls: boolcert_file: str = Nonekey_file: str = Noneenable_reflection: bool = Falseenable_health_check: bool = Truedef get_config() -> ServerConfig:env = os.getenv('ENVIRONMENT', 'development')if env == 'production':return ServerConfig(port=50051,max_workers=100,enable_tls=True,cert_file='/etc/ssl/certs/server.crt',key_file='/etc/ssl/private/server.key',enable_reflection=False,enable_health_check=True)elif env == 'staging':return ServerConfig(port=50051,max_workers=50,enable_tls=True,cert_file='/etc/ssl/certs/staging.crt',key_file='/etc/ssl/private/staging.key',enable_reflection=True,enable_health_check=True)else: # developmentreturn ServerConfig(port=50051,max_workers=10,enable_tls=False,enable_reflection=True,enable_health_check=True)def create_server_from_config(config: ServerConfig):server = grpc.server(futures.ThreadPoolExecutor(max_workers=config.max_workers))# Add services...if config.enable_tls:# Configure TLSwith open(config.cert_file, 'rb') as f:cert = f.read()with open(config.key_file, 'rb') as f:key = f.read()credentials = grpc.ssl_server_credentials([(key, cert)])server.add_secure_port(f'[::]:{config.port}', credentials)else:server.add_insecure_port(f'[::]:{config.port}')return server
正确的服务器配置确保你的 gRPC 服务安全、高性能并为生产工作负载做好准备。