在任务线索中创建模型无法连接到Postgres数据库-尝试使用套接字而不是网络端口

时间:2018-09-02 12:37:44

标签: django postgresql rabbitmq docker-compose celery

我机智。我研究了一段时间,也许我不知道正确的关键字,但找不到有效的解决方案。

我已经用Postgres后端对Django应用程序(自定义链接缩短程序)进行了docker化,该后端使用Celery,RabbitMQ完成一项任务-在发出GET请求时将对象创建并保存到数据库中。

这个想法是这样的:当请求一个短链接(GET请求)时,该应用程序只是将请求重定向到另一个URL,而且还使用Celery创建了一个任务。该任务应该将分析记录添加到Postgres数据库中。重定向工作正常。我可以创建新的短链接。 Django应用程序可以很好地连接到postgres容器。但是Celery在另一个容器中尝试在创建新对象并通过套接字将其保存到postgres容器时进行连接。这是主要错误:

celery      | django.db.utils.OperationalError: could not connect to server: No such file or directory
celery      |   Is the server running locally and accepting
celery      |   connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

以下是我认为相关的代码,但是如果我未包含某些内容,请告诉我。谢谢。

docker-compose.yml:

version: '3.6'

services:

  pgdb:
    container_name: postgres
    restart: unless-stopped
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
    image: postgres:10-alpine
    ports:
      - 5432:5432
    volumes:
      - postgres_data:/var/lib/postgres/data
    networks:
      - net1

  rabbitmq:
    container_name: rabbitmq
    restart: always
    image: rabbitmq:3.7-alpine
    environment:
      - RABBITMQ_DEFAULT_USER=slinky
      - RABBITMQ_DEFAULT_PASS=pwd
    depends_on:
      - pgdb
    networks:
      - net1
    ports:
      - 5672:5672

  django:
    container_name: django
    restart: unless-stopped
    environment:
      - DB_NAME=postgres
      - DB_USER=postgres
      - DB_PASSWORD=password
      - DB_HOST=pgdb
      - DB_PORT=5432
    build:
      context: .
      dockerfile: docker/django.dockerfile
    command: sh -c "/usr/local/bin/gunicorn slinky.wsgi -w 2 -b 0.0.0.0:8000 --log-file gunicorn.log"
    volumes:
      - .:/code
      - /tmp
    networks:
      - net1
    ports:
      - 8000:8000
    depends_on:
      - pgdb
      - rabbitmq

  celery:
    container_name: celery
    restart: unless-stopped
    build:
      context: .
      dockerfile: docker/django.dockerfile
    command: celery -A slinky worker -l info
    volumes:
      - .:/code
    depends_on:
      - rabbitmq
    networks:
      - net1

  nginx:
    container_name: nginx
    restart: unless-stopped
    build:
      context: .
      dockerfile: docker/nginx.dockerfile
    volumes:
      - .:/code
    ports:
      - 80:80
    networks:
      - net1
    depends_on:
      - django

volumes:
  postgres_data:

networks:
  net1:
    driver: bridge
    name: net1

tasks.py:

from __future__ import absolute_import, unicode_literals
from celery import shared_task
from django.conf import settings
from django.db import models
from .utils import ip2country


@shared_task
def redirect_event(url, slink, label, ip):
    country = "Switzerland" # ip2country(ip)
    print("Saving redirect event object: ", country)
    obj = RedirectEvent(url=url, slink=slink, label=label, country=country)
    obj.save()

utils.py:

from django.conf import settings
from django.db import models

import random
import string
import requests

SLINK_LENGTH = getattr(settings, "SLINK_LENGTH", 6)

def code_gen(size=SLINK_LENGTH, chars = string.ascii_lowercase + string.digits):
    return ''.join(random.choice(chars) for _ in range(size))

def create_code(instance, size=SLINK_LENGTH):
    new_code = code_gen(size=size)
    Klass = instance.__class__
    qs_exists = Klass.objects.filter(shortcode=new_code).exists()
    if qs_exists:
        return create_code(size=size)
    return new_code

def ip2country(ip):
    url = "http://api.ipaddress.com/iptocountry?format=json&ip=" + ip
    print("IP2 country API call: ", url)
    r = requests.get(url)
    data = r.json()
    return data['country_name']

views.py:

from django.conf import settings
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.views import View
from .models import Slink, SlinkBaseDomain, RedirectEvent
from shortener.tasks import redirect_event

SLINK_BASE = getattr(settings, "SLINK_BASE", "www.meydan.tv")

class SlinkRedirectView(View):
    def get(self, request, slink=None, *args, **kwargs):
        obj = get_object_or_404(Slink, shortcode=slink)
        latest_domain_obj = SlinkBaseDomain.objects.latest()
        latest_domain = latest_domain_obj.domain
        url = latest_domain + obj.url
        ip = request.META['REMOTE_ADDR']

        # celery task (delayed job)
        redirect_event.delay(obj.url, slink, obj.label, ip)

        print("================= Redirecting user to external URL: ", url)
        return HttpResponseRedirect(url)

来自app models.py:

class RedirectEvent(models.Model):
    url = models.CharField(max_length=255)
    slink = models.CharField(max_length=SLINK_LENGTH)
    country = models.CharField(max_length=255, blank=True)
    label = models.CharField(max_length=25, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.slink)

    class Meta:
        verbose_name = "Redirect Analytic"

0 个答案:

没有答案