将请求从一个 uwsgi 分派到另一个 uwsgi 实例 运行 Django Channels
Dispatching requests from one uwsgi to another uwsgi instance running Django Channels
我目前正在使用 Django 通道进行 websocket 通信。我阅读了这篇文章,它指出我应该将项目拆分为两个 uwsgi 实例。它指出
"The web server undertakes the task of dispatching normal requests to one uWSGI instance and WebSocket requests to another one"
现在我有两个 uwsgi 实例 运行。我就是这样 运行 两者。
这个 uwsgi 处理正常的 django 站点请求
uwsgi --virtualenv /home/ec2-user/MyProjVenv --socket /home/ec2-user/MyProjVenv/MyProjWeb/site1.socket --chmod-socket=777 --buffer-size=32768 --workers=5 --master --module main.wsgi
这个 uwsgi 处理 websocket 请求
uwsgi --virtualenv /home/ec2-user/MyProjVenv --http-socket /home/ec2-user/MyProjVenv/MyProjWeb/web.socket --gevent 1000 --http-websockets --workers=2 --master --chmod-socket=777 --module main.wsgi_websocket
现在 websocket uwsgi 启动 main.wsgi_websocket
main.wsgi_websocket一个的代码是这样的
import os
import gevent.socket
import redis.connection
redis.connection.socket = gevent.socket
os.environ.update(DJANGO_SETTINGS_MODULE='main.settings')
from ws4redis.uwsgi_runserver import uWSGIWebsocketServer
application = uWSGIWebsocketServer()
现在在启动两个 uwsgi 实例后我可以访问网站 fine.The websocket uwsgi 实例也在接收数据但是我不确定它是否将该数据传递给 django 网站 uwsgi 实例基本上使用 django 通道并具有 send/receive 函数的处理程序。我在这里使用 Django Channels,这是我在 Django Channels
设置中指定的配置
CHANNEL_LAYERS = {
"default": {
"BACKEND": "asgi_redis.RedisChannelLayer",
"CONFIG": {
"hosts": [(redis_host, 6379)],
},
"ROUTING": "main.routing.channel_routing",
},
}
频道路由是这样的
channel_routing = [
include("chat.routing.websocket_routing", path=r"^/chat/stream"),
include("chat.routing.custom_routing"),
]
这是我的 websocket_routing
websocket_routing = [
route("websocket.connect", ws_connect),
# Called when WebSockets get sent a data frame
route("websocket.receive", ws_receive),
# Called when WebSockets disconnect
route("websocket.disconnect", ws_disconnect),
]
现在的问题是我的 ws_receive 从未被调用过。如果我在我的本地开发机器上使用 ipaddress:8000/chat/stream
进行测试,这工作得很好但是我不知道为什么当我使用 ipadress/ws/
时我的接收没有被调用。我确定我的另一个 uwsgi 实例正在获取该数据,但我不知道如何确定它是否将它传递给 djnago 端的另一个 uwsgi 实例,如果是,那么为什么我的接收没有被调用?对此的任何建议肯定会有所帮助
当我在这里看到你的另一个问题时,我正在想这个
拆分项目是个好主意。我假设这两个实例 运行 落后于 nginx
(来自你的上述问题)。
那么,nginx 应该决定哪个请求到哪个实例?您可以为每个 channels
和 django
应用程序使用不同的 url 路径。
示例:
对于 Django 应用:/whatever/whatever/...
对于 channels
:/ws/whatever/...
假设您的 channels
消费者实例在 8000 上。
将此添加到您的 nginx
:
location /ws/ {
proxy_pass http://0.0.0.0:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
这样,无论您的查询是什么,如果 url 以 /ws/
开头,它将被端口 8000 上的任何实例 运行 使用。
我目前正在使用 Django 通道进行 websocket 通信。我阅读了这篇文章,它指出我应该将项目拆分为两个 uwsgi 实例。它指出
"The web server undertakes the task of dispatching normal requests to one uWSGI instance and WebSocket requests to another one"
现在我有两个 uwsgi 实例 运行。我就是这样 运行 两者。
这个 uwsgi 处理正常的 django 站点请求
uwsgi --virtualenv /home/ec2-user/MyProjVenv --socket /home/ec2-user/MyProjVenv/MyProjWeb/site1.socket --chmod-socket=777 --buffer-size=32768 --workers=5 --master --module main.wsgi
这个 uwsgi 处理 websocket 请求
uwsgi --virtualenv /home/ec2-user/MyProjVenv --http-socket /home/ec2-user/MyProjVenv/MyProjWeb/web.socket --gevent 1000 --http-websockets --workers=2 --master --chmod-socket=777 --module main.wsgi_websocket
现在 websocket uwsgi 启动 main.wsgi_websocket
main.wsgi_websocket一个的代码是这样的
import os
import gevent.socket
import redis.connection
redis.connection.socket = gevent.socket
os.environ.update(DJANGO_SETTINGS_MODULE='main.settings')
from ws4redis.uwsgi_runserver import uWSGIWebsocketServer
application = uWSGIWebsocketServer()
现在在启动两个 uwsgi 实例后我可以访问网站 fine.The websocket uwsgi 实例也在接收数据但是我不确定它是否将该数据传递给 django 网站 uwsgi 实例基本上使用 django 通道并具有 send/receive 函数的处理程序。我在这里使用 Django Channels,这是我在 Django Channels
设置中指定的配置CHANNEL_LAYERS = {
"default": {
"BACKEND": "asgi_redis.RedisChannelLayer",
"CONFIG": {
"hosts": [(redis_host, 6379)],
},
"ROUTING": "main.routing.channel_routing",
},
}
频道路由是这样的
channel_routing = [
include("chat.routing.websocket_routing", path=r"^/chat/stream"),
include("chat.routing.custom_routing"),
]
这是我的 websocket_routing
websocket_routing = [
route("websocket.connect", ws_connect),
# Called when WebSockets get sent a data frame
route("websocket.receive", ws_receive),
# Called when WebSockets disconnect
route("websocket.disconnect", ws_disconnect),
]
现在的问题是我的 ws_receive 从未被调用过。如果我在我的本地开发机器上使用 ipaddress:8000/chat/stream
进行测试,这工作得很好但是我不知道为什么当我使用 ipadress/ws/
时我的接收没有被调用。我确定我的另一个 uwsgi 实例正在获取该数据,但我不知道如何确定它是否将它传递给 djnago 端的另一个 uwsgi 实例,如果是,那么为什么我的接收没有被调用?对此的任何建议肯定会有所帮助
当我在这里看到你的另一个问题时,我正在想这个
拆分项目是个好主意。我假设这两个实例 运行 落后于 nginx
(来自你的上述问题)。
那么,nginx 应该决定哪个请求到哪个实例?您可以为每个 channels
和 django
应用程序使用不同的 url 路径。
示例:
对于 Django 应用:/whatever/whatever/...
对于 channels
:/ws/whatever/...
假设您的 channels
消费者实例在 8000 上。
将此添加到您的 nginx
:
location /ws/ {
proxy_pass http://0.0.0.0:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
这样,无论您的查询是什么,如果 url 以 /ws/
开头,它将被端口 8000 上的任何实例 运行 使用。