我有一个ERP产品,它需要nodejs和Django之间的实时双向进程间通信。现在我正在使用npm WebSocket和Django频道。在使用" python manage.py runserver"开发期间,它工作正常。但在生产过程中,django推荐daphne和runworker。我用nginx进行了测试。现在我的问题是,连接在一段时间后断开连接。在Django(1.9)中,连接持续24小时左右。在我改为Django2之后,连接只持续了1个小时左右。系统没有显示任何错误。我的配置如下。
nginx.conf
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html;
index index.html index.htm;
server_name 209.97.166.79;
#location /static/ {
# alias /<project-static-files-path>/static/;
# expires 1y;
#}
location / {
proxy_pass http://0.0.0.0:8001;
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;
}}
项目结构
.
├── db.sqlite3
├── django_two_main
│ ├── asgi.py
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── asgi.cpython-35.pyc
│ │ ├── __init__.cpython-35.pyc
│ │ ├── routing.cpython-35.pyc
│ │ ├── settings.cpython-35.pyc
│ │ └── urls.cpython-35.pyc
│ ├── routing.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
├── README.md
├── requirements.txt
├── sales
│ ├── django_node_connect
│ │ ├── consumers.py
│ │ ├── __init__.py
│ │ ├── __pycache__
│ │ │ ├── consumers.cpython-35.pyc
│ │ │ ├── __init__.cpython-35.pyc
│ │ │ └── routing.cpython-35.pyc
│ │ ├── routing.py
│ │ └── views.py
│ ├── __init__.py
│ └── __pycache__
│ └── __init__.cpython-35.pyc
└── static
Settings.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
ALLOWED_HOSTS = []
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'django_two_main.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'django_two_main.wsgi.application'
ASGI_APPLICATION = "django_two_main.routing.application"
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 6379)],
},
},
}
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
asgi.py
import os
import django
from channels.routing import get_default_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE",
"django_two_main.settings")
django.setup()
application = get_default_application()
用于运行daphne的命令
daphne -b 0.0.0.0 -p 8001 django_two_main.asgi:application --access-
log /home/logs/access.log &
的access.log
127.0.0.1:37012 - - [13/Jun/2018:08:23:25] "GET /" 400 53326
127.0.0.1:37014 - - [13/Jun/2018:08:35:45] "HEAD /phpmyadmin/" 400 -
127.0.0.1:37016 - - [13/Jun/2018:08:35:45] "HEAD /PMA/" 400 -
127.0.0.1:37018 - - [13/Jun/2018:08:35:46] "HEAD /dbadmin/" 400 -
127.0.0.1:37020 - - [13/Jun/2018:08:35:46] "HEAD /pma/" 400 -
127.0.0.1:37022 - - [13/Jun/2018:08:35:46] "HEAD /db/" 400 -
127.0.0.1:37024 - - [13/Jun/2018:08:37:29] "GET /" 400 53322
127.0.0.1:37026 - - [13/Jun/2018:08:37:30] "GET /" 400 53322
127.0.0.1:37028 - - [13/Jun/2018:08:41:50] "GET /" 400 53320
127.0.0.1:37030 - - [13/Jun/2018:08:49:56] "GET /" 400 53322
127.0.0.1:37032 - - [13/Jun/2018:09:00:31] "GET /" 400 53322
127.0.0.1:37036 - - [13/Jun/2018:09:13:38] "GET /" 400 53320
127.0.0.1:37038 - - [13/Jun/2018:09:18:39] "GET /" 400 53572
127.0.0.1:37040 - - [13/Jun/2018:09:18:40] "GET /" 400 53572
127.0.0.1:37042 - - [13/Jun/2018:09:20:54] "GET /" 400 53320
127.0.0.1:37044 - - [13/Jun/2018:09:36:07] "GET /" 400 53324
nginx错误日志(IP地址已更改)
2018/06/13 04:56:31 [error] 5969#5969: *1820 connect() failed (111:
Connection refused) while connecting to upstream, client:
80.211.172.33, server: 100.23.126.79, request: "HEAD
http://239.237.136.29:80/dbadmin/ HTTP/1.1", upstream:
"http://0.0.0.0:8001/dbadmin/", host: "239.197.163.734"
2018/06/13 04:56:32 [error] 5969#5969: *1820 connect() failed (111:
Connection refused) while connecting to upstream, client:
80.211.172.33, server: 249.23.163.193, request: "HEAD
http://219.12.66.71:80/pma/ HTTP/1.1", upstream:
"http://0.0.0.0:8001/pma/", host: "212.37.136.49"
routing.py
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import sales.django_node_connect.routing
application = ProtocolTypeRouter({
# (http->django views is added by default)
'websocket': AuthMiddlewareStack(
URLRouter(
sales.django_node_connect.routing.websocket_urlpatterns
)
),
})
nodejs(pm2)日志显示此消息
[2018-06-13T10:29:06.899Z] reconnecting:ws://localhost:8001/channel
[2018-06-13T10:29:08.900Z] reconnecting:ws://localhost:8001/channel
[2018-06-13T10:29:10.900Z] reconnecting:ws://localhost:8001/channel
答案 0 :(得分:1)
Nginx在预定义的时间后关闭连接。如果要使用长连接,则需要设置自定义超时。我也有same issue并在将proxy_read_timeout
设置为86400
后得到修复。
location / {
proxy_pass http://0.0.0.0:8001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}