不同 docker 容器之间的 Django 通道

Posted

技术标签:

【中文标题】不同 docker 容器之间的 Django 通道【英文标题】:Django channels between different docker containers 【发布时间】:2018-10-29 01:11:01 【问题描述】:

我正在使用 django channels,但我对如何使用 channels 发送消息有疑问

上下文

我有 2 个容器:celery-workerapi,我想通过 websockets 从 celery-worker 容器通过 api 容器使用 channels 将数据发送到浏览器,这里是图片:

问题

您知道如何“初始化”api 容器中的通道并在celery-worker 容器中使用此通道吗?在celery-worker 容器中仅调用Group('pablo').send(message) 之后,它会自动发送到浏览器。

任何建议都可以。

注意:我尝试不发布代码,因为它非常广泛,可能会导致难以理解问题,但如果您愿意,我可以发布一些您需要的代码。

【问题讨论】:

你添加的依赖于你的docker-compose??? 【参考方案1】:

我创建了使用 Celery 和 Django Channels 2 (github) 的示例(带有简单任务)。 Celery worker 正在向通道层发送消息。消息被广播到连接到 websocket 的客户端。

在服务器端我有消费者:

class TasksConsumer(AsyncWebsocketConsumer):

    async def connect(self):
        # One group name for all clients: 'tasks'
        self.group_name = 'tasks'
        await self.channel_layer.group_add(self.group_name, self.channel_name)
        await self.accept()

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

    async def receive(self, text_data):
        pass

    async def task_update_message(self, event):
        # Send message to channel
        await self.send(json.dumps(event))

可以看到组名是“tasks”。在芹菜方面,工人正在打电话:

channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)("tasks", msg)

要在工作代码中使用通道,您需要设置 django 设置:

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'server.settings')
import django
django.setup()

希望对您有所帮助!

【讨论】:

【参考方案2】:

您需要告知您依赖的其他容器。例子。在这里,您看到 PostgreSQL 具有来自 user_service 和 notification_service 的依赖项,您需要为每个想要使用链接或依赖的其他容器的容器添加它。这是一个例子。

version: '3'
services:
db:
    image: postgres
    ports:
    - '5434:5434'
user_service:
    build: ""
    environment:
    - JWT_SECRET=mysecret_json_web_token_pass
    command: python user/app.py
    volumes:
    - .:/microservices
    ports:
    - "9001:9001"
    depends_on:
    - db
notification_service:
    build: ""
    environment:
    - JWT_SECRET=mysecret_json_web_token_pass
    command: python notification/app.py
    volumes:
    - .:/microservices
    ports:
    - "9002:9002"
    depends_on:
    - db

对于您的情况,您可能需要添加 取决于: - 芹菜 - redis

你也可以建立一个本地网络。但我没有这样做,而是在同一个 docker-compose 中创建容器,这样他们就知道彼此了。

这是另一个例子

version: '2'  
services:  
nginx:
    image: nginx:latest
    container_name: nx01
    ports:
    - "8001:8001"
    volumes:
    - ../src:/src
    - ./static:/static
    - ./media:/media/
    - ./config/nginx:/etc/nginx/conf.d
    depends_on:
    - web
web:
    build: .
    container_name: dg01
    command: gunicorn mydjango.wsgi 0.0.0.0:8000

    depends_on:
    - db
    links:
    - redis
    volumes:
    - ../src:/src
    - ./static:/static
    - ./media:/media/
    expose:
    - "8001"
db:
    image: postgres:latest
    container_name: pq01
    ports:
    - "5432:5432"

redis:
    image: redis:latest
    container_name: rd01
    ports:
    - '6379:6379'

celery:
    build: .
    container_name: cl01
    command: celery worker --app=app.tasks
    volumes:
    - ..:/src
    links:
    - db
    - redis

在您的代码上调用它...像这样使用它。

CELERY_BROKER_URL = 'redis://redis:6379/0'
CELERY_RESULT_BACKEND = 'redis://redis:6379/0'

【讨论】:

以上是关于不同 docker 容器之间的 Django 通道的主要内容,如果未能解决你的问题,请参考以下文章

Django 不会连接到 Redis Docker 容器

Docker 微服务架构 - 不同容器之间的通信

docker同宿主机容器和不同宿主机容器之间怎么通信?

在不同的docker容器之间共享python中的变量

在同一主机上的不同网络中的 Docker 容器之间进行通信

在不同 docker-compose 文件中描述并在不同 docker-machines 中运行的容器之间创建 NFS 共享