容器化部署(Docker + 微服務(wù))+ GRPC通信
1. 架構(gòu)設(shè)計(jì)
-
解耦A(yù)I服務(wù):將AI模塊拆分為獨(dú)立服務(wù)(gRPC服務(wù)),避免阻塞主游戲邏輯。
-
通信方式:Go服務(wù)端通過gRPC調(diào)用AI服務(wù)接口,傳遞游戲狀態(tài)并接收決策結(jié)果。
2. 容器化與傳統(tǒng)方案部署方案對(duì)比
| 步驟 |
容器化方案 |
傳統(tǒng)方案 |
| 環(huán)境準(zhǔn)備 |
安裝Docker或Kubernetes |
安裝Python及依賴 |
| 代碼構(gòu)建 |
Docker鏡像構(gòu)建 |
本地編譯可執(zhí)行文件 |
| 服務(wù)部署 |
Docker Compose/Kubernetes |
systemd托管服務(wù) |
| 網(wǎng)絡(luò)通信 |
服務(wù)間通過內(nèi)網(wǎng)域名調(diào)用 |
Nginx反向代理 |
| 擴(kuò)展性 |
水平擴(kuò)展容器實(shí)例 |
手動(dòng)部署多節(jié)點(diǎn) |
3. HTTP vs gRPC方案對(duì)比
| 維度 |
HTTP (RESTful) |
gRPC |
| 性能 |
基于HTTP/1.1,文本傳輸(JSON/XML),序列化開銷大,連接無法復(fù)用 |
基于HTTP/2,二進(jìn)制傳輸(Protobuf),多路復(fù)用、頭部壓縮,性能提升約10倍 |
| 開發(fā)效率 |
手動(dòng)定義API文檔,客戶端需解析JSON,調(diào)試工具成熟(如Postman) |
通過Protobuf自動(dòng)生成代碼,強(qiáng)類型接口減少運(yùn)行時(shí)錯(cuò)誤 |
| 通信模式 |
僅支持請(qǐng)求-響應(yīng) |
支持單向/雙向流、服務(wù)端推送,適合實(shí)時(shí)交互場(chǎng)景 |
| 協(xié)議靈活性 |
兼容瀏覽器、移動(dòng)端,通用性強(qiáng) |
需特定客戶端支持,更適合服務(wù)間內(nèi)部通信 |
| 調(diào)試工具 |
工具豐富(如curl、瀏覽器) |
需專用工具(如Apifox與Apipost,支持.proto文件調(diào)試) |
附錄一、python服務(wù)腳本grpc_server.py
import os
import sys
import logging
import grpc
from concurrent import futures
from env.game import InfoSet
from env.move_generator import MoveGenerator
from env import utils
import evaluation.deep_agent as deep_agent
import proto.model_service_pb2
import proto.model_service_pb2_grpc
from google.protobuf.json_format import MessageToJson
from grpc_reflection.v1alpha import reflection
# logging.basicConfig(level=logging.INFO, filename="test.log", filemode="w")
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger("game")
# 這里需要根據(jù) DouZero 項(xiàng)目實(shí)際加載模型的方式調(diào)整
modelDA = deep_agent.DeepAgent(0, "models/model.ckpt")
generator = MoveGenerator()
def _get_obs(observation: proto.model_service_pb2.Observation) -> InfoSet:
# .... 自己的obs轉(zhuǎn)換代碼....
return info
class PyTorchModel:
def __init__(self, model):
self.model = model
def predict(self, obs):
action = self.model.act(obs)
return action
class ModelServicer(proto.model_service_pb2_grpc.ModelServiceServicer):
def __init__(self, model):
self.model = model
def Predict(self, request, context):
try:
obs = _get_obs(request.observation)
action = self.model.predict(obs)
logger.debug(f"obs: '{obs}' action: '{action}'")
return proto.model_service_pb2.Response(code=0, msg="OK", action=action)
except Exception as e:
json_str = MessageToJson(request.observation)
logger.error(f"error: {str(e)}, obs: '{json_str}'")
return proto.model_service_pb2.Response(code=-1, msg=str(e))
def serve():
model = PyTorchModel(modelDA)
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
proto.model_service_pb2_grpc.add_ModelServiceServicer_to_server(
ModelServicer(model), server
)
# 啟用反射服務(wù)
SERVICE_NAMES = (
proto.model_service_pb2.DESCRIPTOR.services_by_name['ModelService'].full_name,
reflection.SERVICE_NAME,
)
reflection.enable_server_reflection(SERVICE_NAMES, server)
server.add_insecure_port("[::]:50051")
server.start()
logger.info("gRPC Server running on port 50051")
server.wait_for_termination()
if __name__ == "__main__":
serve()
附錄二、Dockerfile
FROM pytorch/pytorch:latest
# 安裝依賴
RUN apt update
RUN apt install git -y
RUN pip install grpcio protobuf grpcio-reflection GitPython -i https://pypi.tuna.tsinghua.edu.cn/simple
# 復(fù)制代碼
COPY models/model.ckpt /app/models/model.ckpt
COPY env /app/env
COPY dmc /app/dmc
COPY evaluation /app/evaluation
COPY proto /app/proto
COPY grpc_server.py /app/grpc_server.py
COPY version.txt /app/version.txt
# 設(shè)置工作目錄
WORKDIR /app
# 暴露端口
EXPOSE 50051
# 啟動(dòng)應(yīng)用
CMD ["python3", "grpc_server.py"]
附錄三、k8s配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: deepai-game1
labels:
app: deepai-game1
spec:
replicas: 1
selector:
matchLabels:
app: deepai-game1
template:
metadata:
labels:
app: deepai-game1
spec:
containers:
- name: deepai-game1
image: registry-vpc.cn-hangzhou.aliyuncs.com/balt/deepai-game1:latest
imagePullPolicy: Always
ports:
- containerPort: 50051
protocol: TCP
name: grpc
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "1000m"
memory: "512Mi"
---
apiVersion: v1
kind: Service
metadata:
name: deepai-game1
spec:
clusterIP: None # 關(guān)鍵配置
ports:
- port: 50051
name: grpc
selector:
app: deepai-game1 # 匹配后端 Pod 標(biāo)簽
按業(yè)務(wù)維度拆分部署(即是按游戲來)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。