使用django通道的进程间通信在一小时后失败

时间:2018-06-13 10:36:02

标签: django websocket ipc django-channels daphne

我有一个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

1 个答案:

答案 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;
}