如何在同一Django项目中同时运行REST API与gRPC服务
可行解决方案分为两类,可根据你的场景选择:
方案1:双端口独立部署(改造成本最低,适配现有依赖)
你当前使用的django-grpc包的设计逻辑就是将HTTP服务和gRPC服务拆分为两个独立进程,无法通过单命令同时启动,直接分两个进程跑不同端口即可:
- DRF的HTTP服务启动命令:
python manage.py runserver 0.0.0.0:8000 - gRPC服务启动命令:
python manage.py grpcserver 0.0.0.0:50051
开发环境可以直接开两个终端分别运行,生产环境可以将两个进程配置为系统服务、容器实例分别托管。如果需要统一访问入口,前端加一层Nginx做路径/协议分流即可:HTTP1.x请求转发到8000端口,HTTP2的gRPC请求转发到50051端口。
方案2:单端口多协议复用(和.NET的同端口监听逻辑一致)
如果需要同一个端口同时处理REST请求和gRPC请求,需要替换依赖并调整启动方式:
- 替换gRPC依赖:卸载
django-grpc,安装django-grpc-framework,后者支持ASGI协议下的多服务整合 - 改造项目根目录的
asgi.py文件,将gRPC服务路由和Django原生HTTP路由整合,示例代码如下:
import os from django.core.asgi import get_asgi_application from django_grpc_framework.routing import grpc_route # 替换为你自己写的gRPC服务类 from your_app.grpc.services import CustomGrpcService os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project.settings') http_app = get_asgi_application() # 整合HTTP和gRPC路由 application = grpc_route( http_app, [ # 替换为你自己的proto包名、服务名和对应实现类 ('your_proto_package.CustomService', CustomGrpcService), ] )
- 使用支持HTTP2的ASGI服务器启动服务,以Uvicorn为例,启动命令为:
uvicorn your_project.asgi:application --host 0.0.0.0 --port 8000 --http h2
启动后同一个8000端口会同时支持HTTP1的DRF接口访问和HTTP2的gRPC请求访问。
补充说明:Django自带的
runserver是仅支持HTTP1的WSGI服务器,本身就不支持HTTP2的gRPC协议,所以你之前单独启动runserver时gRPC无法正常工作是原生限制,django-grpc自带的grpcserver仅加载gRPC服务逻辑没有处理HTTP路由,所以REST接口无法访问,属于两个命令的设计特性。
内容的提问来源于stack exchange,提问作者Phat Huynh
相关产品推荐
相关产品推荐

