我们有一个使用渠道包的应用程序,在localhost上工作得很好.一旦我们点击staging并在Django(使用SSL)前放置一个Nginx框,我们就可以连接到套接字,但客户端不会收到任何消息.
Nginx conf:
worker_processes auto;
error_log /dev/stdout info;
user nobody nogroup;
pid /tmp/Nginx.pid;
events {
worker_connections 1024;
accept_mutex off;
}
http {
include mime.types;
default_type application/octet-stream;
access_log /dev/stdout;
sendfile on;
keepalive_timeout 65;
gzip on;
gzip_disable "MSIE [1-6].(?!.*SV1)";
gzip_vary on;
upstream ws_server {
server unix:/tmp/daphne.sock fail_timeout=0;
}
server {
# redirect all http requests to https
listen 80;
listen [::]:80 ipv6only=on;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
client_max_body_size 4G;
server_name changemyip.com;
keepalive_timeout 5;
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets on;
ssl_dhparam /etc/Nginx/ssl/dhparam.pem;
location /ws/ {
try_files $uri @proxy_to_ws;
}
location @proxy_to_ws {
proxy_pass http://ws_server;
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-Proto $scheme;
# Websocket specific
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_connect_timeout 86400;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}
...
ssl_protocols TLSv1.1 TLSv1.2;
...
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
}
}
Django用gunicorn和websockets运行我加入了一个daphne服务器.我可以在daphne日志中看到我的客户端正在连接,但仍然没有收到从daphne到客户端的消息.
Daphne正在创建一个unix套接字,Nginx接受通信:
daphne main.asgi:channel_layer -u /tmp/daphne.sock
> Django Channels Group Pt1
> Django Channels Group Pt2
# Enable upgrading of connection (and websocket proxying) depending on the
# presence of the upgrade field in the client request header
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Create an upstream alias to where we've set daphne to bind to
upstream django_app_server {
server 127.0.0.1:8000;
}
server {
listen 80;
server_name YOURDOMAIN.COM;
client_max_body_size 4G;
access_log /webapps/General/logs/Nginx-access.log;
error_log /webapps/General/logs/Nginx-error.log;
location /static/ {
alias /webapps/General/DjangoProject/static/;
}
location /media/ {
alias /webapps/General/DjangoProject/media/;
}
location / {
if (!-f $request_filename) {
proxy_pass http://django_app_server;
break;
}
# Require http version 1.1 to allow for upgrade requests
proxy_http_version 1.1;
# We want proxy_buffering off for proxying to websockets.
proxy_buffering off;
# http://en.wikipedia.org/wiki/X-Forwarded-For
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# enable this if you use HTTPS:
# proxy_set_header X-Forwarded-Proto https;
# pass the Host: header from the client for the sake of redirects
proxy_set_header Host $http_host;
# We've set the Host header,so we don't need Nginx to muddle
# about with redirects
proxy_redirect off;
# Depending on the request value,set the Upgrade and
# connection headers
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
# Error pages
error_page 500 502 503 504 /500.html;
location = /500.html {
root /webapps/General/DjangoProject/templates/;
}
}
我的项目中的websockets运行得非常好(组和通道),所有请求都由Daphne提供,但如果您真的需要使用套接字,这种配置可能实际上对您有所帮助.
要考虑的要点
>请记住,这个Nginx文件允许Daphne通常连接,但在生产服务器中,您需要分别运行“Daphne Instance Server”和“Daphne Workers”,以便能够通过您的频道传输消息.
>检查在为频道和组提供服务时是否使用Redis-Server或其他队列管理器.我这样说是因为我注意到在使用“InMemory”配置时,丢失了多条消息.
>还要检查您的生产环境是否将Redis-Server作为守护程序运行.我注意到在几个系统中,Redis-Server甚至没有工作,但是当连接被拒绝时,Django应用程序没有引发异常.
>你需要一些东西来保持达芙妮和它的工人,因为即使他们循环,他们也不是“例外抗性”所以当异常被提出时他们会死.显然,我建议使用Supervisor或使用Linux系统进行服务.
>我不知道当DEBUG == False时,daphne的工作人员是否可以提供静态和媒体文件,但显然使用Nginx配置单独提供它们会更好.
>与使用套接字相比,我仍然不知道使用端口的安全/性能影响,所以这是值得检查的事情(如下所示,我发现Daphne或我的配置可能存在错误).
我知道现在这对你来说可能无关紧要了(我的意思是差不多1个月),但也许有人会对这个答案有所帮助.
未知和非常奇怪的安全问题
TL; DR:不要使用此配置在同一服务器中描绘两个Django-Daphne应用程序,否则您将遇到不好的时间.
通过使用这种配置,我可以在没有任何问题的情况下将Phoenix应用程序与Django应用程序一起部署,但是在使用这种类型的配置部署2个或更多Django应用程序时遇到了问题.出于某种原因,达芙妮知道它必须不断阅读哪些端口来接收请求,但它只是读取所有这些端口并将它们提供给任何它喜欢的人.例如,如果我在同一台服务器上运行DJANGO_APP_1和DJANGO_APP_2(具有不同的Nginx配置和明显不同的系统端口),有时DJANGO_APP_2的Daphne Workers将窃取针对DJANGO_APP_1的请求,反之亦然.我无法确定问题的根源,但我认为这与达芙妮的工作人员在一定程度上与他们所涉及的项目无关. (只是一个理论,我没有时间检查他们的代码).