My Image

Django 포스팅

[Django] 비동기 작업 처리 Celery를 설치하고 Redis와 연결하기

Doyeon0430 | 2023년 08월 01일

Django 이미지

이번시간에는 비동기 방식인 Celery를 설치하고 Redis와 연결하겠습니다.

비동기 방식은 정보처리산업기사를 공부할 때 잠깐 배웠던 개념으로

다른 작업이 진행될 때 해당 작업을 기다리지 않고 동시에 실행하는 프로그래밍 용어입니다.

만약 API를 가져온다면 응답이 오래 걸리는 문제가 발생합니다.

이럴 때 Celery를 통해 쉽게 해결 할 수 있습니다.

 

  1. Celery와 Redis 설치 - 프로젝트

  2. Celery와 Redis 설치 - 앱

  3. Celery와 Redis 설치 - 실행

 

 

1. Celery와 Redis 설치 - 프로젝트

Celery는 비동기 작업을 도와주는 도구로 서버에 여러 작업자를 두고 분산 처리를 진행합니다.

예를들어 외부에서 api를 가져올 때 서버에 로딩이 생기게 되는데 여기서 캐시 기능과 Celery Beat를 사용하면

주기적으로 반복하는 명렁어를 줘서 캐시를 크롤링 할 수 있습니다.

그러나 캐시를 사용하기 위해서 데이터를 저장해야합니다.

메모리 기반 데이터베이스인 Redis를 사용하면 간편하게 저장할 수 있습니다.

물론 메모리는 휘발성이라 서버가 종료되면 사라지는 단점이 있습니다.

 

1. ubuntu 터미널

# 우분투 업데이트
$ sudo apt update

# Redis 설치
$ sudo apt install redis-server

# Celery 설치
$ pip install celery
$ pip install djangorestframework
$ pip install django-celery-beat
$ pip install django-celery-results

Redis는 윈도우에서 설치하기 까다롭습니다.

그래서 라이트세일에 우분투로 진행했습니다.

Redis 뿐만아니라 RabbitMQ 방식도 사용하는데 저는 안정적인 Redis를 선택했습니다.

 

2. 경로 위치

루트 디렉토리/
├── config/ # 프로젝트
│   ├── __init__.py <-- 여기에 넣어주세요
│   ├── asgi.py
│   ├── celery.py <-- 새로 추가
│   ├── settings.py <-- 여기에 넣어주세요
│   ├── urls.py
│   └── wsgi.py
├── manage.py
└── myprofile/ # 앱
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── models.py
    ├── tests.py
    ├── views.py
    └── ...

프로젝트 폴더 안에 celery.py라는 파일을 생성해주세요.

 

3. __init__.py

from .celery import app as celery_app

__all__ = ('celery_app',)

 

4. settings.py

# 코드 삽입
INSTALLED_APPS = [
    'celery',
    'rest_framework',
    'django_celery_beat',
    'django_celery_results',
    ...
]

# 추가
CELERY_BROKER_URL = 'redis://127.0.0.1:6379/0'
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/0'
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True

redis는 6379 포트를 사용하고 0은 데이터베이스 위치입니다.

서버의 메모리를 사용하기 위해 127.0.0.1로 넣었습니다.

 

5. celery.py

import os
from celery import Celery

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

app = Celery('config')

app.config_from_object('django.conf:settings', namespace='CELERY')

app.autodiscover_tasks()

@app.task(bind=True, ignore_result=True)
def debug_task(self):
    print(f'Request: {self.request!r}')

os.environ.setdefault에서 config,settings은 프로젝트 settings에 경로를 나타냅니다.

app을 선언하고 Celery 클래스를 생성합니다.

config_from_object는 app이 settings.py로 시작하게 지정합니다.

autodiscover_tasks는 데스크를 자동으로 발견하는 기능입니다.

 

 

2. Celery와 Redis 설치 - 앱

서버에서 패키지를 설치하고 프로젝트에 코드를 넣어봤습니다.

이제 앱에서 Celery를 불러와야하는 단계입니다.

tasks.py를 만들고 함수를 입력하면 Celery worker가 비동기방식으로 가져와 처리합니다.

그럼 오래 걸리는 대기시간을 빠르게 단축시켜줍니다.

 

1. 경로 위치

루트 디렉토리/
├── config/ # 프로젝트
│   ├── __init__.py
│   ├── asgi.py
│   ├── celery.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
└── myprofile/ # 앱
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── models.py
    ├── tasks.py <-- 새로 추가
    ├── tests.py
    ├── views.py <-- 여기에 넣어주세요
    └── ...

tasks.py를 새로 만들어주세요.

views.py에서 명령어를 실행시키면 tasks.py로 가서 등록한 코드를 검색합니다.

 

2. tasks.py

from celery import shared_task

@shared_task
def add(x, y):
    return x + y

 

3. views.py

from myprofile.tasks import add

def introduce(request):
    ...
    result = add.delay(4, 3)
    introduce_data = {'result': result}
    return render(request, 'myprofile/introduce.html', introduce_data)

 

4. HTML 코드

<div>Celery 테스트</div>
<ul>
   <li>결과 : {{ result }}</li>
</ul>

제 블로그에 출력물을 올려놨습니다.

링크를 통해 확인해보세요.

주소 : Celery 테스트 결과

 

 

3. Celery와 Redis 설치 - 실행

마지막으로 우분투 서버에서 Redis와 Celery를 등록하겠습니다.

Redis가 성공적으로 실행되면 Celery에 워커를 등록하고 Redis와 연결할 수 있습니다.

 

1. ubuntu 터미널 - Redis 실행

$ sudo service redis-server start
$ sudo service redis-server status
● redis-server.service - Advanced key-value store
     ...
     Active: active (running) since Tue 2023-08-01 02:14:45 KST; 1min 25s ago
     ...

Redis는 패키지를 설치하자마자 자동으로 실행됩니다.

start 명령어를 입력하고 status로 상태를 확인해봅시다.

초록불로 active가 뜨면 성공입니다.

 

2. ubuntu 터미널 - Redis 테스트

$ redis-cli ping
PONG

만약 active가 안나온다면 위의 코드를 입력해보세요.

PONG 이외에 값은 제대로 작동하는게 아닙니다.

Redis 재설치하거나 오류 내용을 수정해서 start 해보세요.

 

3. ubuntu 터미널 - Celery 실행

$ celery -A config worker -l INFO

...

[tasks]
  . config.celery.debug_task
  . myprofile.tasks.add

[2023-08-01 02:30:55,039: INFO/MainProcess] Connected to redis://127.0.0.1:6379/0
[2023-08-01 02:30:55,045: INFO/MainProcess] mingle: searching for neighbors
[2023-08-01 02:30:56,053: INFO/MainProcess] mingle: all alone
[2023-08-01 02:30:56,062: INFO/MainProcess] celery@ip-172-26-5-202 ready.
[2023-08-01 02:31:25,947: INFO/MainProcess] Task myprofile.tasks.add[8cafb80d-c74e-4185-a72
9-3072896f5283] received
[2023-08-01 02:31:25,955: INFO/ForkPoolWorker-1] Task myprofile.tasks.add[8cafb80d-c74e-418
5-a729-3072896f5283] succeeded in 0.006647760999840102s: 7

등록했던 tasks들이 나오는 것을 확인할 수 있습니다.

밑에 값을 보면 succeeded로 7이 나왔습니다.

 

4. celery 테스트 결과화면

디장고 celery 결과화면

댓글 (0)

    댓글이 없습니다.

간편 댓글 작성

My Image My Image My Image My Image