IT/Django

Django에서 Celery가 필요한 이유?

bepuri 2024. 1. 4. 17:22
728x90

먼저 django와 celery가 뭐하는 녀석인지 이론적인것들은 개인적으로 찾아보시길 바라며, 이포스팅에선 구체적으로 어떤 이슈를 겪었고, 어떻게 해결했는지에 집중하겠다.

 

이슈 - backend에서 web-push request시 response delay로 인한 frontend로의 응답 지연.

http의 특성상 일반적으로는 request 후 response가 올 때까지 대기하는 것이 원칙이다.

이 경우 response가 오기 전까지는 서비스가 멈춘 것처럼 유저는 느낄 수 있다.

 

이 원론적인 프로토콜 구성 때문에 생기는 문제가 한가지 있는데,

나는 최근 web-push를 구현하면서 겪게 되었다.

 

web-push를 구현하는 것도 참고할만한 자료가 없어서 꽤나 시간이 걸렸는데,

구현하고보니 web-push의 경우 request를 subscription 시 응답받은 endpoint로 subscription정보와 payload와 함께 보내게되면 push가 가는 구조인데,

이 webpush request를 보내고, response를 받는 시간이 꽤 걸린다.

 

이런 로직 때문에 필연적으로 생기는 문제가 있는데, 바로 응답처리의 지연이다.

 

예를들어 내가 댓글은 남기는 경우 , 이웃들에게 푸시 메시지를 보내주는 기능이 있다고 해보자.

이 경우 내가 댓글 남길때 모든 이웃들에게 푸시 메시지를 보낼텐데, 이 때 푸시 메시지는 앞서 말한 것처럼 subscription에서 나온 endpoint로 가능하기 때문에 endpoint로 request를 보내고 response를 기다리는 로직이 여러번 반복된다.

 

이 경우 상당한 시간이 걸릴 거라는건 안봐도 뻔하다.

 

그렇기 때문에 따로 task queue를 따로 만들어서 application server가 아닌 다른 task에서 처리해주는 로직이 필요한데, 그걸 알아서 처리 해주는 기능을 가진게 celery이다.

 

나는 아래 튜토리얼을 약간 수정하여 원하는 기능을 만들었고,

https://code.tutsplus.com/using-celery-with-django-for-background-task-processing--cms-28732t

 

Using Celery With Django for Background Task Processing | Envato Tuts+

Web applications usually start out simple but can become quite complex. Properly using background tasks can make your application faster and more scalable.

code.tutsplus.com

 

윈도우에서는 아래에서 언급한 명령으론 제대로 작동하지 않아서 stackoverflow를 참고하여 구현했다~

https://stackoverflow.com/questions/71698207/celery-not-receiving-tasks-to-run-in-background

 

Celery not receiving tasks to run in background

I'm having an issue setting up celery to work with my flask app. I've used a barebones app to test the configuration and have found that my celery worker is started but not picking up any of the ta...

stackoverflow.com

 

실제로 추가해야할 파일은 두가지인데,

메인 프로젝트\celery.py

추가한 앱\tasks.py

 

두가지이다. celery를 실행하면 자동으로 task는 찾아서 추가하니 신경 안써도 된다.

또한 task 함수의 변경이 있으면 celery를 다시 시작해줘야한다.

내경우는 안그럼 수정한 코드가 반영이 안되더라.

 

사실 귀차니즘이 와서 celery 없이 async를 구현할 수 있는 방법이 없나 찾아봤는데,, 그런 방법은 없는듯하다.

 

마지막으로 당연하게도 rabbitMQ나 redis는 필수로 사용해야한다.

나는 redis를 사용했고, 도커를 쓰고 있어서 아래 명령으로 간단하게 redis를 띄워줬다~ㅎ

sudo docker run -p 6379:6379 redis

 

도커를 안썼더라면 redis 환경을 구축하는데 과연 한줄의 명령으로 되었을까?

싶기도하고, 얼마나 귀찮았을지 상상이 안가기도 한다.

 

PS. 만약 dockerizing을 할 생각이라면 아래 예제를 참고하는게 나아 보인다.

https://saasitive.com/tutorial/django-celery-redis-postgres-docker-compose/

 

또한 dockerizing시 기본적으로 docker container 간의 통신은 localhost가 아닌 container name으로 되니 redis 주소 localhost에서 redis로 변경해줘야 한다.

postgresql db도 마찬가지임.

728x90