托管Django频道与gunicorn + Uvicorn + Postgresql + Redis在铁路上
#django #postgres #redis #channels

最近,我必须为一家创业公司构建REST API,在此期间,我的任务是为其聊天应用程序构建Web插座。我认为这是一项简单的工作,因为我过去做过类似的事情,但是后来我意识到我以前从未托管过Web插座项目。

通过大量文档,我开始使用达芙妮(Daphne)的部署过程,但这是徒劳的。 httpwebsocket端点都无法正常工作。经过大量的研究和文档阅读,我能够运行它。在本教程中,我将为如何在铁路上托管您的Django Asgi项目提供详细的解释。

我会假设您已经对Django和Django频道知识很少,因此我不会对此做出很多解释。让我们首先创建我们的Django项目

$ mkdir chat
$ cd chat
$ python -m venv venv
$ source venv/bin/activate
$ pip install django channels_redis
$ django-admin startproject chat .
$ python manage.py startapp myapp

将在当前目录中创建App myapp。转到chat/settings.py并将myapp添加到INSTALLED_APPS

# chat/settings.py

INSTALLED_APPS = [
    # other apps
    "myapp.apps.MyappConfig",
]

接下来,在终端运行以下命令。

$ python manage.py migrate
$ python manage.py createsuperuser

运行上述命令后,请确保启动服务器,以确保您的项目通过下面的命令运行

$ python manage.py runserver

访问https://localhost:8000/查看该项目。接下来,我们将配置我们的项目以使用 asgi 。要使用ASGI服务器,我们将安装django-channelsdaphne

$ python -m pip install channels["daphne"]

安装完成后,将以下代码添加到必要的文件中。

# chat/settings py
INSTALLED_APPS = [
    "daphne" # this should be the topmost app.
    # other apps
]

ASGI_APPLICATION = "chat.asgi.application"

# chat/asgi.py
import os
from django.core.asgi import get_asgi_application
import django

# django channels
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator

from chat.websocket_urls import websocket_urlpatterns

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Chat.settings')

django.setup()

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": AllowedHostsOriginValidator(
        AuthMiddlewareStack(
            URLRouter(
                websocket_urlpatterns
            )
        )
    )
})

现在,我们的设置部分完成了,请返回终端并重新启动服务器。您应该看到这样的东西。如果看起来不那样,请尝试进行故障排除。

daphne-server

另一种可以运行服务器的方式是直接使用Daphne。

$ daphne chat.asgi: application

为了加快事物的速度,我将为消费者和路由器提供代码。快速在myapp目录中创建两个文件。文件应命名为cumput.py and Routers.py。将以下代码添加到文件中。

# myapp/consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        await self.accept()
        # other code

    async def disconnect(self, close_code):
        await self.channel_layer.group_discard(self.room_group_name, self.channel_name)

    async def receive(self, text_data):
         # piece of code to handle receive events.
# myapp/routers.py

from django.urls import re_path
from . import consumers

websocket_urlpatterns = [
    re_path(r"ws/chat/(?P<room_name>\w+)/$",consumers.ChatConsumer.as_asgi()),
]

尚未完成,因为我们仍然需要使用频道层来广播消息。为此,将此代码添加到chat/settings py

# chat/settings.py

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [("localhost", 6379)],
        },
    },
}

我们现在已经设置了频道层,现在可以通过消息广播。到目前为止,我们一直在开发环境,现在就部署我们的应用程序。生产环境与开发环境完全不同,但由于我从一开始就已经想到了,因此无需改变。

$ python -m pip install psycopg2 gunicorn uvicorn
$ pip freeze > requirements.txt

安装了这些软件包并创建requirements.txt文件后,创建一个文件并将其命名为Procfile,而没有扩展名。这告诉铁路部署我们的应用程序时要使用的开始命令。将其添加到文件中。

web: python manage.py migrate && python -m gunicorn Chat.asgi:application -k uvicorn.workers.UvicornWorker

需要对我们的chat/settings.py文件进行一些更改,但我只会介绍其中的一些。

# chat/settings.py
import os

SECRET_KEY = os.environ.get("SECRET_KEY")

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": os.environ.get("PG_NAME"),
        "USER": os.environ.get("PG_USER"),
        "PASSWORD": os.environ.get("PG_PASSWORD"),
        "HOST": os.environ.get("PG_HOST"),
        "PORT": os.environ.get("PG_PORT"),
    }
}

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [(os.environ.get("REDIS_URL"))], # update this line.
        },
    },
}

通过这几个更改,我们准备将渠道申请部署到铁路。转到铁路网站,创建一个PostgreSQL项目和Redis项目。完成后,通过从GitHub中选择该项目来创建一个Django项目(您现在应该推出代码)。转到变量,并设置我们在settings.py中使用的所有环境变量和项目中的其他变量。 PostgreSQL的环境变量在您创建的PostgreSQL项目中,对于Redis环境变量相同。另外,您很可能应该将DJANGO_SETTINGS_MODULE变量设置为项目的settings.py文件。完成此操作后,您的项目现在应该进行。

如果您在部署期间遇到的任何问题,请在评论部分中指出,我很乐意为您提供帮助