【问题标题】:Receive Django signals across different containers跨不同容器接收 Django 信号
【发布时间】:2019-01-08 03:45:05
【问题描述】:

我目前正在处理一个 Django 项目,但在处理不同容器之间的信号时遇到了一些问题。

我有一个连接到上游数据管道并填充 Django 数据库的第一个容器。我有另一个用于后端本身的容器,并且我在其上运行服务器。我想使用信号“post save”来通知我的一个应用程序已经保存了一个新的模型实例。因此,我在我的应用程序中使用下一段代码来接收此信号并处理已保存的实例。

@receiver(post_save, sender=Organization)
def index_post_save(sender, instance, **kwargs):
    connections.create_connection(hosts=['elasticsearch'])  
    instance.indexing()

如果我在 Django 管理界面上手动创建一个组织实例,这将非常有效,但是当我使用我的第一个容器填充数据库时没有收到信号。

这是我描述的两个容器的 docker-compose 文件的一部分:

worker:
   build:
      context: .
      dockerfile: Dockerfile
   command: ./run_celery.sh
   env_file:
      - ./.envs/.local/.workers
   volumes:
      - .:/app

web:
   restart: always
   build:
     context: .
     dockerfile: Dockerfile
   hostname: web
   command: /app/run_web.sh
   env_file:
     - ./.envs/.local/.web
   volumes:
     - .:/app
   ports:
     - "80:8000"
   links:
     - db
     - pipeline_db
   depends_on:
     - db
     - pipeline_db
     - elasticsearch

有没有办法跨容器使用 Django 信号,或者我应该使用其他方法来发送和接收这些消息?

谢谢

【问题讨论】:

  • Django 不会向其他正在运行的进程(实例)发送信号,它只是为当前正在运行的实例触发它们,它甚至不知道其他容器的存在。您应该实现某种消息队列来通知其他容器。据我了解,您已经在使用 celery,因此您可以在 index_post_save 方法下使用 celery 将消息传递到另一个容器。
  • 是的,就像我在回答中所说的那样,您可以使用某种通信方式,例如 API、套接字……每个服务器都在不同的端口上运行,如果在同一个服务器上,您可能要记住设置 CORS
  • 好的,谢谢这些答案。由于容器使用相同的数据库,我认为有一种方法可以使信号在两者之间起作用。我想我会选择芹菜解决方案

标签: python django docker-compose django-signals


【解决方案1】:

等等什么?信号仅在 django 项目中有效,一个信号可以到达的最外部点是当它们在方法中运行命令 save() 并检查数据库是否保存它时...

您可以做的是在您的终端、API、套接字或任何您想与后端对话的通信中运行一些 python 代码。

因此,试一试,您可以为上游的管道创建一个 API(我不太了解它是什么),以便能够接收一些 POST 或 GET 方法,并设置您的后端以向您的应用程序发送一个请求(在其他容器)来接收你想要的数据......你可以使用requestscurl

我考虑到您在不同的容器中使用 2 个服务器

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 2020-11-16
    • 1970-01-01
    • 1970-01-01
    • 2013-07-07
    相关资源
    最近更新 更多