5. celery 구동시키기
celery가 서버에서 동작하기 위해서는 celery의 task를 받아 처리하는 broker가 필요합니다. 이를 위해 우리는 앞에서 rabbitmq를 설치 하였습니다. celery의 기본 broker가 rabbitmq 이기 때문에 별도의 broker셋팅을 하지 않았습니다.
ㅇ celery 구동
docker의 컨테이너에서 앞에서 django에 셋팅 해 놓은 celery를 동작시킵니다.
# celery -A mywebapp worker -l info
/usr/local/lib/python3.6/dist-packages/celery/platforms.py:795: RuntimeWarning: You're running the worker with superuser privileges: this is
absolutely not recommended!
Please specify a different user using the -u option.
User information: uid=0 euid=0 gid=0 egid=0
uid=uid, euid=euid, gid=gid, egid=egid,
-------------- celery@629b4d182cdc v4.1.0 (latentcall)
---- **** -----
--- * *** * -- Linux-4.4.89-boot2docker-x86_64-with-Ubuntu-18.04-bionic 2018-04-08 03:03:53
-- * - **** ---
- ** ---------- [config]
- ** ---------- .> app: applycelery:0x7fb1cef84550
- ** ---------- .> transport: amqp://guest:**@localhost:5672//
- ** ---------- .> results: disabled://
- *** --- * --- .> concurrency: 1 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** -----
-------------- [queues]
.> celery exchange=celery(direct) key=celery
[tasks]
. applycelery.tasks.celery
. applycelery.tasks.celery_delay
. mywebapp.celery.debug_task
[2018-04-08 03:03:53,666: ERROR/MainProcess] consumer: Cannot connect to amqp://guest:**@127.0.0.1:5672//: [Errno 111] Connection refused.
Trying again in 2.00 seconds...
[2018-04-08 03:03:55,690: ERROR/MainProcess] consumer: Cannot connect to amqp://guest:**@127.0.0.1:5672//: [Errno 111] Connection refused.
Trying again in 4.00 seconds...
celery가 동작 하였지만, 하단의 에러 메시지가 지속적으로 반복 됩니다. 메시지를 보면 amqp에 연결할 수 없다고 나오는데, celery의 task를 받아주는 broker가 없다는 말로 볼 수 있습니다. 이를 해결하기 위해 rabbitmq 를 구동합니다.
ㅇ rabbitmq 구동
celery 와 동시에 rabbitmq를 동작시켜야 하기에, 별도의 docker container의 콘솔창을 띄워 rabbitmq를 구동 시킵니다.
# rabbitmq-server
RabbitMQ 3.6.10. Copyright (C) 2007-2017 Pivotal Software, Inc.
## ## Licensed under the MPL. See http://www.rabbitmq.com/
## ##
########## Logs: /var/log/rabbitmq/rabbit@629b4d182cdc.log
###### ## /var/log/rabbitmq/rabbit@629b4d182cdc-sasl.log
##########
Starting broker...
completed with 0 plugins.
ㅇ 동작 확인
rabbitmq를 구동 시킨 후 앞에서 실행시킨 celery의 콘솔창을 보면 정상적인 동작을 확인할 수 있습니다.
[2018-04-08 03:07:24,670: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672//
[2018-04-08 03:07:24,798: INFO/MainProcess] mingle: searching for neighbors
[2018-04-08 03:07:26,290: INFO/MainProcess] mingle: all alone
[2018-04-08 03:07:26,439: WARNING/MainProcess] /usr/local/lib/python3.6/dist-packages/kombu/pidbox.py:71: UserWarning: A node named celery@629b4d182cdc is already using this process mailbox!
Maybe you forgot to shutdown the other node or did not do so properly?
Or if you meant to start multiple nodes on the same host please make sure
you give each node a unique node name!
warnings.warn(W_PIDBOX_IN_USE.format(node=self))
[2018-04-08 03:07:26,486: WARNING/MainProcess] /usr/local/lib/python3.6/dist-packages/celery/fixups/django.py:202: UserWarning: Using settings.DEBUG leads to a memory leak, never use this setting in production environments!
warnings.warn('Using settings.DEBUG leads to a memory leak, never '
[2018-04-08 03:07:26,491: INFO/MainProcess] celery@629b4d182cdc ready.
[2018-04-08 03:07:28,332: INFO/MainProcess] Received task: applycelery.tasks.celery[4bf76bd7-7779-4594-ac80-ec760ff48ba2]
[2018-04-08 03:07:28,529: INFO/ForkPoolWorker-1] Task applycelery.tasks.celery[4bf76bd7-7779-4594-ac80-ec760ff48ba2] succeeded in 0.1741230510006062s: None
몇가지 경고 메시지가 발생 하지면 정상적으로 작동 중입니다.
6. celery 비동기 동작 직접 확인하기
이제 준비가 완료 외었습니다. 띄워놓은 docker 콘솔 이외에 추가적인 콘솔을 실행시켜 서버로 django를 구동해 봅시다.
ㅇ 서버 및 django 구동
# sh docker_start.sh
*** Starting uWSGI 2.0.15 (64bit) on [Sun Apr 8 03:11:39 2018] ***
compiled with version: 7.2.0 on 17 January 2018 14:22:13
os: Linux-4.4.89-boot2docker #1 SMP Wed Sep 27 22:59:39 UTC 2017
nodename: 629b4d182cdc
machine: x86_64
clock source: unix
detected number of CPU cores: 1
current working directory: /mysite
detected binary path: /usr/local/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
*** WARNING: you are running uWSGI without its master process manager ***
your processes number limit is 1048576
your memory page size is 4096 bytes
detected max file descriptor number: 1048576
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to UNIX address /tmp/mysite.sock fd 3
Python version: 3.6.4 (default, Dec 27 2017, 13:02:49) [GCC 7.2.0]
* Starting nginx nginx [ OK ]
*** Python threads support is disabled. You can enable it with --enable-threads ***
Python main interpreter initialized at 0x561bbc35d990
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 72760 bytes (71 KB) for 1 cores
*** Operational MODE: single process ***
WSGI app 0 (mountpoint='') ready in 2 seconds on interpreter 0x561bbc35d990 pid: 398 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI worker 1 (and the only) (pid: 398, cores: 1)
ㅇ 비동기(백그라운드) 동작 확인하기
앞에서 celery를 적용하지 않는 버튼의 경우 클릭시에 정의한 프로세스를 실행하는 동안 사이트는 멈추어 있고, 해당 프로세스가 완료된 후에 다시 복귀하여 사이트가 동작 하였습니다. 이제 celery를 이용해 정의된 버튼들의 동작을 확인 해봅시다.
- CELERY(DELAY 10S) 버튼 클릭
버튼을 클릭 하였음에도 아무일도 일어나지 않았습니다. 사이트가 동작중일때 표시되는 동그라미 작업중 표시도 나타나지 않습니다.
- 10초 이상 지난 후 루트페이지로 이동
우리가 10초의 DELAY를 정의 하였음으로 그 시간 후 헤더의 "Django Celery" 버튼을 눌러 루트 페이지로 이동 해 봅니다.
아무 버튼을 누르지 않았음에도 정의한 프로세스가 작동하여 사이트에 표시 되었습니다.
- CELERY(DELAY 10S) 누르고 2~3초후 OPERATE버튼 누르기
비동기 프로세스로 인해 버튼을 누른 순서와 상관없이 작업이 끝나는 대로 사이트에 기록된 것을 확인할 수 있습니다.
우리는 CELERY(DELAY 10S)을 먼저 누르고, OPERATE 버튼을 클릭 하였고, 이는 "버튼클릭" 항목의 시간을 통해서도 확인이 가능합니다.
하지만 끝나는 시간이 뒤에누른 OPERATE가 빠름으로 사이트에는 버튼을 누른 순서와 상관없이 작업이 끝나는 순서대로 사이트에 기록 되었음을 확인할 수 있습니다.
7. 마치며
우리는 지금까지 Celery를 활용하여 비동기(백그라운드) 프로세스를 구현해보고 직접 확인 해보았습니다. 본 포스팅은 백그라운드 동작을 보여주기 위하여 delay() 라는 임의적인 지연을 적용 하였으나, 실제로 서비스 시에는 장시간이 소요되는 프로세스를 celery와 버무려 작성한다면 사용자에게 끊기지 않고 서비스를 이용하는 경험을 제공할 수 있을 것입니다.
※ 기타사항
django-celery-beat : 주기적으로 특정 프로세스를 동작시키기 위한 페키지
django-celery-results : django admin 페이지에서 celery 동작 결과 및 로그 관리
'Technique' 카테고리의 다른 글
카카오톡 플러스친구를 이용한 email 간편 전송 서비스 만들기(feat, DJANGO, groomide) 2 (0) | 2018.09.04 |
---|---|
카카오톡 플러스친구를 이용한 email 간편 전송 서비스 만들기(feat, DJANGO, groomide) 1 (0) | 2018.09.04 |
웹서비스 비동기(백그라운드) 프로세스 만들기 (feat. Django, Celery) 4 (0) | 2018.04.05 |
웹서비스 비동기(백그라운드) 프로세스 만들기 (feat. Django, Celery) 3 (0) | 2018.04.05 |
웹서비스 비동기(백그라운드) 프로세스 만들기 (feat. Django, Celery) 2 (0) | 2018.04.01 |