Celery: DatabaseScheduler๋Š” ์…€๋Ÿฌ๋ฆฌ 4.1.0์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2017๋…„ 08์›” 07์ผ  ยท  28์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: celery/celery

django_celey_beat 1.0.1๊ณผ ํ•จ๊ป˜ ์…€๋Ÿฌ๋ฆฌ 4.1.0์„ ์„ค์น˜ํ–ˆ๋Š”๋ฐ DatabaseScheduler๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

[2017-08-07 21:12:10,790: DEBUG/MainProcess] DatabaseScheduler: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ผ์ • ๊ฐ€์ ธ์˜ค๊ธฐ
[2017-08-07 21:12:10,797: DEBUG/MainProcess] ํ˜„์žฌ ์ผ์ •:
[2017-08-07 21:12:10,807: DEBUG/MainProcess] beat: ์ตœ๋Œ€ ๊ฐ„๊ฒฉ->5.00์ดˆ๋กœ ๋˜‘๋”ฑ
[2017-08-07 21:12:10,809: DEBUG/MainProcess] beat: 5์ดˆ ๋งŒ์— ๊นจ์šฐ๊ธฐ.
[2017-08-07 21:12:15,813: DEBUG/MainProcess] beat: ์Šค์ผ€์ค„ ๋™๊ธฐํ™” ์ค‘...
[2017-08-07 21:12:15,813: INFO/MainProcess] ํ•ญ๋ชฉ ์ž‘์„ฑ ์ค‘...
[2017-08-07 21:12:15,816: DEBUG/MainProcess] beat: 5์ดˆ ๋งŒ์— ๊นจ์šฐ๊ธฐ.
[2017-08-07 21:12:20,818: DEBUG/MainProcess] beat: 5์ดˆ ๋งŒ์— ๊นจ์šฐ๊ธฐ.
[2017-08-07 21:12:25,825: DEBUG/MainProcess] beat: 5์ดˆ ๋งŒ์— ๊นจ์šฐ๊ธฐ.
[2017-08-07 21:12:30,831: DEBUG/MainProcess] beat: 5์ดˆ ๋งŒ์— ๊นจ์šฐ๊ธฐ.
[2017-08-07 21:12:35,839: DEBUG/MainProcess] beat: 5์ดˆ ๋งŒ์— ๊นจ์šฐ๊ธฐ.
[2017-08-07 21:12:40,844: DEBUG/MainProcess] beat: 5์ดˆ ๋งŒ์— ๊นจ์šฐ๊ธฐ.
[2017-08-07 21:12:45,851: DEBUG/MainProcess] beat: 5์ดˆ ๋งŒ์— ๊นจ์šฐ๊ธฐ.
[2017-08-07 21:12:50,854: DEBUG/MainProcess] beat: 5์ดˆ ๋งŒ์— ๊นจ์šฐ๊ธฐ.
[2017-08-07 21:12:55,860: DEBUG/MainProcess] beat: 5์ดˆ ๋งŒ์— ๊นจ์šฐ๊ธฐ.
[2017-08-07 21:13:00,862: DEBUG/MainProcess] beat: 5์ดˆ ๋งŒ์— ๊นจ์šฐ๊ธฐ.
[2017-08-07 21:13:05,870: DEBUG/MainProcess] beat: 5์ดˆ ๋งŒ์— ๊นจ์šฐ๊ธฐ.
^C[2017-08-07 21:13:10,245: INFO/MainProcess] ํ•ญ๋ชฉ ์ž‘์„ฑ ์ค‘...
[2017-08-07 21:13:10,246: INFO/MainProcess] ํ•ญ๋ชฉ ์ž‘์„ฑ ์ค‘...

๋ณด์‹œ๋‹ค์‹œํ”ผ ์Šค์ผ€์ค„๋Ÿฌ๋Š” ๋งค๋ถ„ ๋น„ํŠธ๋ฅผ ๋ณด๋‚ด์•ผํ–ˆ์ง€๋งŒ ๋น„ํŠธ๊ฐ€ ํ‘œ์‹œ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค (crontab์„ ๋ชจ๋‘ *๋กœ ์„ค์ • ํ–ˆ์œผ๋ฏ€๋กœ ์‹œ๊ฐ„๋Œ€ ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์—†์Œ)

๊ทธ๋Ÿฌ๋‚˜ ์…€๋Ÿฌ๋ฆฌ 4.0.2์—์„œ๋Š” ๋ชจ๋“  ๊ฒƒ์ด ์ž˜ ๋ฉ๋‹ˆ๋‹ค! ๋ฒ„๊ทธ์ธ์ง€ ์•„๋‹Œ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. django_celery_beat๊ฐ€ 4.1.0๊ณผ ํ˜ธํ™˜๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

[2017-08-07 21:18:43,339: DEBUG/MainProcess] ํ˜„์žฌ ์ผ์ •:
[2017-08-07 21:18:43,351: DEBUG/MainProcess] beat: ์ตœ๋Œ€ ๊ฐ„๊ฒฉ->5.00์ดˆ๋กœ ๋˜‘๋”ฑ
[2017-08-07 21:18:43,364: INFO/MainProcess] ์Šค์ผ€์ค„๋Ÿฌ: ๋งˆ๊ฐ๋œ ์ž‘์—… ์ผ์ • ๋ณด๋‚ด๊ธฐ (GeneBank.tasks.test)
[2017-08-07 21:18:43,376: DEBUG/MainProcess] beat: ์Šค์ผ€์ค„ ๋™๊ธฐํ™” ์ค‘...
[2017-08-07 21:18:43,376: INFO/MainProcess] ํ•ญ๋ชฉ ์ž‘์„ฑ ์ค‘...
[2017-08-07 21:18:43,380: DEBUG/MainProcess] GeneBank.tasks.test๊ฐ€ ์ „์†ก๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์•„์ด๋””->9c1bdf10-0a5f-440a-98db-9eb24433a8d4
[2017-08-07 21:18:43,381: DEBUG/MainProcess] beat: 5์ดˆ ๋งŒ์— ๊นจ์šฐ๊ธฐ.
[2017-08-07 21:18:48,386: DEBUG/MainProcess] beat: 5์ดˆ ๋งŒ์— ๊นจ์šฐ๊ธฐ.
[2017-08-07 21:18:53,392: DEBUG/MainProcess] beat: 5์ดˆ ๋งŒ์— ๊นจ์šฐ๊ธฐ.
[2017-08-07 21:18:58,397: DEBUG/MainProcess] beat: Wake up in 1.59์ดˆ.
[2017-08-07 21:19:00,001: INFO/MainProcess] Scheduler: ๋งˆ๊ฐ๋œ ์ž‘์—… ์ผ์ • ๋ณด๋‚ด๊ธฐ (GeneBank.tasks.test)

Celerybeat

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

@mchen-scala ๋‹น์‹ ์€ ์‚ด๋ฉด์„œ ๋ณต์žกํ•œ ์‹œ์Šคํ…œ์„ ์ž‘์„ฑํ•œ ์ ์ด ์—†์œผ๋ฉฐ ์ด ํ‹ฐ์ผ“์˜ ๋งฅ๋ฝ์กฐ์ฐจ ์ดํ•ดํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ฆ‰, Celery 4 ์‹œ๋ฆฌ์ฆˆ์—๋Š” ์‹œ๊ฐ„๋Œ€๊ฐ€ UTC๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ CELERY_BEAT_SCHEDULE๋ฅผ ๋”ฐ๋ฅด์ง€ ์•Š๋Š” ์ผ๋ถ€ ๋ฒ„์ „์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ท€ํ•˜์˜ ์š”์ ์€ ์—ฌ๋Ÿฌ ์ˆ˜์ค€์—์„œ ๋ชจ๋‘ ๋ถ€์ •ํ™•ํ•˜๊ณ  ๋ชจ์š•์ ์ž…๋‹ˆ๋‹ค. ๋†๋‹ด์€ ๋‹น์‹ ์ด ์—ฌ๋Ÿฌ ์‚ฐ์—…์— ๊ฑธ์ณ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์˜ ์š”๊ตฌ์— ๋งž๋Š” OSS ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•ด ์šฐ๋ฆฌ๋ฅผ ๋ชจ์š•ํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๊ธฐ์— ์™”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹น์‹ ์ด ๊ณ ์šฉ์ฃผ๋ฅผ ์œ„ํ•ด ์ž‘์„ฑํ•œ ๋ชจ๋“  ๊ฒƒ์ด Celery ํ”„๋กœ์ ํŠธ๋งŒํผ ๋งŽ์€ ๋น›์„ ๋ณด์ง€ ๋ชปํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์ด์ „ ์ž‘์—…์„ ์ฐธ์กฐํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์• ์ž์ผ ์„ธ๊ณ„์—์„œ๋Š” 2-4์ฃผ๋งˆ๋‹ค ๋ฆด๋ฆฌ์Šคํ•  ๊ฒƒ์ด๋ฏ€๋กœ, ๋‹น์‹ ์ด ๊ตฌ์ถ•ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐ๋˜๋Š” ์ด ๋ฉ‹์ง„ ์‹œ์Šคํ…œ ๋Œ€์‹  ์ƒ์†๋ฐ›์€ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์€ ๋‹น์‹ ์ด ๋ถ€ํ’€๋ ค์ง„ ์ž๊ธฐ ๊ฐ€์น˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋‚˜์—๊ฒŒ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

๋˜ํ•œ mchen-scala, ์…€๋Ÿฌ๋ฆฌ๋ฅผ ๋„๋„๋ก ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์ฃผ๋กœ ์šฐ๋ฆฌ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ๋‹น์‹ ์˜ ํƒœ๋„๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ €๋Š” OSS๋ฅผ ํ™œ์šฉํ•˜๊ณ  ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ์ง€์›์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋†’์€ ๊ธ‰์—ฌ๋ฅผ ๋ฐ›๋Š” ์ง์—…์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹น์‹ ์ด ์ž์‹ ์˜ ๋งŒํŠธ๋ผ๋ฅผ ๋”ฐ๋ฅด๊ณ  ์ž์‹ ์ด ์ž˜ํ•˜๋Š” ๊ฒƒ์— ์ถฉ์‹คํ•  ๊ฒƒ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ถ„๋ช…ํžˆ ๊ธฐ์กด ์†”๋ฃจ์…˜์˜ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ž์‹ ์˜ ์†”๋ฃจ์…˜์„ ๋กค๋งํ•˜๊ณ  ๋‚˜๋จธ์ง€ ์šฐ๋ฆฌ์—๊ฒŒ ๋ฐ˜์‚ฌํšŒ์  ๋ฐ”๋ณด๊ฐ€ ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‹œ์•„!

๋ชจ๋“  28 ๋Œ“๊ธ€

๋‚˜๋Š” ๋‘˜ ๋‹ค ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ณ  ๊ทธ๋“ค์€ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค

๋ฒ„์ „ 4.0.2์—์„œ ๋ฒ„์ „ 4.1.0์œผ๋กœ ์—…๋ฐ์ดํŠธํ•œ ํ›„ ์œ ์‚ฌํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์ž‘์—… ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์Œ

์—ฌ๊ธฐ์„œ๋„ 4.0.2๋กœ ๋‹ค์šด๊ทธ๋ ˆ์ด๋“œํ•˜๋ฉด ๋‹ค์‹œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ฒ„๊ทธ๋Š” ์‹œ๊ฐ„๋Œ€์™€ ๊ด€๋ จ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„๋Œ€๋ฅผ UTC๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

CELERY_TIMEZONE = 'UTC'
CELERY_ENABLE_UTC = ์ฐธ

ํ˜„์žฌ master ์ง€์ ์„ ๋‹ค์‹œ ํ™•์ธํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

4.1.0์—์„œ ์ด ๋ฒ„๊ทธ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด ์„ค์ •์—์„œ:

CELERY_TIMEZONE = 'Europe/Moscow'

์˜ˆ, ๋‹ค์Œ๊ณผ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

CELERY_TIMEZONE = 'UTC'
CELERY_ENABLE_UTC = True

๊ฐ™์€ ๋ฌธ์ œ -- ์…€๋Ÿฌ๋ฆฌ ๋น„ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์—ฌ๋Ÿฌ ํ”„๋กœ์ ํŠธ๊ฐ€ ์žˆ์ง€๋งŒ ๊ทธ ์ค‘ ํ•˜๋‚˜๊ฐ€ ์šฐ์—ฐํžˆ CELERY_TIMEZONE์„ America/NewYork์ธ ํ”„๋กœ์ ํŠธ ์‹œ๊ฐ„๋Œ€๋กœ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ž ๊ทธ๋Œ€๋กœ ๋‚˜๋Š” Rabbit QA ์„œ๋ฒ„์—์„œ 1,800๋งŒ ๊ฐœ์˜ ๋ฉ”์‹œ์ง€๋กœ ์ž ์—์„œ ๊นผ์Šต๋‹ˆ๋‹ค. ์ž‘์—…์ž๊ฐ€ ๋Œ€๊ธฐ์—ด์— ์ถ”๊ฐ€๋˜๋Š” ์†๋„(๋ถ„๋‹น ์ˆ˜๋ฐฑ ๊ฐœ)๋ฅผ ๋”ฐ๋ผ์žก์„ ์ˆ˜ ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์„ค์ •์„ ์‚ญ์ œํ•˜๊ณ  ํ”„๋กœ์ ํŠธ ๊ธฐ๋ณธ๊ฐ’์„ ์—†์Œ์˜ CELERY_TIMEZONE์œผ๋กœ ์„ค์ •ํ•ด๋„ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

FWIW -- ๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ DatabaseScheduler๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ ์ด๋ฆ„์„ ๋ฐ”๊ฟ”์•ผ ํ• ๊นŒ์š”?

@matteius @AyumuKasuga master ๋ถ„๊ธฐ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์ˆ˜์ • ์‚ฌํ•ญ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ์— ๋Œ€ํ•ด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” @georgepsarakis์ž…๋‹ˆ๋‹ค !
๋ฐฉ๊ธˆ ๋งˆ์Šคํ„ฐ ๋ธŒ๋žœ์น˜๋ฅผ ํ…Œ์ŠคํŠธํ–ˆ๋Š”๋ฐ ๋ถˆํ–‰ํžˆ๋„ ๋‚ด ์„ค์ •์—์„œ ๋ฌธ์ œ๊ฐ€ ์—ฌ์ „ํžˆ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€!

์•ˆ๋…•ํ•˜์„ธ์š”,

๋น„์Šทํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html ์˜ django-celery-beat ์„ค์ • ์ง€์นจ์„ ๋”ฐ๋ž์Šต๋‹ˆ๋‹ค.

CELERY_TIMEZONE = 'UTC'
CELERY_ENABLE_UTC = True
CELERY_RESULT_BACKEND = 'django-db'
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'

๊ทธ๋Ÿฐ ๋‹ค์Œ ์ฃผ๊ธฐ์  ์ž‘์—…์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

@periodic_task(run_every=timedelta(seconds=30))
def do_stuff():
   print("HI")

์…€๋Ÿฌ๋ฆฌ ๋น„ํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

$> DJANGO_SETTINGS_MODULE="proj.settings.dev" celery -A proj beat -l info
celery beat v4.1.0 (latentcall) is starting.
__    -    ... __   -        _
LocalTime -> 2017-08-28 15:58:44
Configuration ->
    . broker -> amqp://guest:**<strong i="14">@localhost</strong>:5672//
    . loader -> celery.loaders.app.AppLoader
    . scheduler -> django_celery_beat.schedulers.DatabaseScheduler

    . logfile -> [stderr]@%INFO
    . maxinterval -> 5.00 seconds (5s)
[2017-08-28 15:58:44,425: INFO/MainProcess] Writing entries...
[2017-08-28 15:58:45,629: INFO/MainProcess] DatabaseScheduler: Schedule changed.
[2017-08-28 15:58:45,630: INFO/MainProcess] Writing entries...

์ฃผ๊ธฐ์  ์ž‘์—…์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์กด์žฌํ•˜๋ฉฐ enabled ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์…€๋Ÿฌ๋ฆฌ ์ž‘์—…์ž๋Š” ์ฃผ๊ธฐ์ ์ธ ์ž‘์—…์„ ์ˆ˜์‹ ํ•˜๊ฑฐ๋‚˜ ์‹คํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

$> DJANGO_SETTINGS_MODULE="proj.settings.dev" celery -A proj worker -l info -E

 -------------- celery@proj-dev v4.0.2 (latentcall)
---- **** ----- 
--- * ***  * -- Linux-4.4.0-83-generic-x86_64-with-Ubuntu-16.04-xenial 2017-08-28 15:57:42
-- * - **** --- 
- ** ---------- [config]
- ** ---------- .> app:         proj:0x7f89f78faeb8
- ** ---------- .> transport:   amqp://guest:**<strong i="20">@localhost</strong>:5672//
- ** ---------- .> results:     
- *** --- * --- .> concurrency: 1 (prefork)
-- ******* ---- .> task events: ON
--- ***** ----- 
 -------------- [queues]
                .> celery           exchange=celery(direct) key=celery


[tasks]
  . proj.tasks.do_nothgin
  . proj.tasks.do_stuff

[2017-08-28 15:57:42,269: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672//
[2017-08-28 15:57:42,287: INFO/MainProcess] mingle: searching for neighbors
[2017-08-28 15:57:43,324: INFO/MainProcess] mingle: all alone

์†Œํ”„ํŠธ์›จ์–ด:

celery==4.1.0
django-celery-beat==1.0.1
django-celery-results==1.0.1
Django==1.8.2

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์•„์ด๋””์–ด/๋„์›€์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค.

์ตœ์ƒ์˜,
์„ธ๋ฐ”์Šค์ฐฌ

๋˜ฅ๋ฉ์–ด๋ฆฌ. ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@mchen-scala ์ €๋Š” OSS ํ”„๋กœ์ ํŠธ๊ฐ€ ํ˜‘๋ ฅ์ ์ด๊ณ  ๊ฐ๊ด€์ ์ด๊ณ  ๊ฑด์„ค์ ์ธ ๋น„ํ‰๊ฐ€๋ฅผ ์œ„ํ•œ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋ช‡ ์ค„์˜ ์ฝ”๋“œ๋ฅผ ๋˜ฅ ์กฐ๊ฐ์— ๋„ฃ์—ˆ์Šต๋‹ˆ๊นŒ? ์‹ค์ œ๋กœ ๋น„ํŠธ๊ฐ€ ์žˆ๋Š” Celery๊ฐ€ ์™„๋ฒฝํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋‹น์‹ ์ด ์ง€๊ธˆ๊นŒ์ง€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋” ์ง„๋ณด๋œ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์šด์˜ ์ฒด์ œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ๋นˆ๋„๊ฐ€ ๋†’์€ ๊ฑฐ๋ž˜ ํ”Œ๋žซํผ๊ณผ ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ ์„ผํ„ฐ ๊ฐ„ DB๋ฅผ ๊ตฌ์ถ•ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋” ๋งŽ์€.

์ฝ”๋“œ ์ค„? ๋‚˜๋Š” ์ž‘๋™ํ•˜๋Š” ์‹œ์Šคํ…œ๋งŒ ๋ด…๋‹ˆ๋‹ค. LOC๋Š” tyros๋ฅผ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ œ๊ฐ€ ๋ฌผ๋ ค๋ฐ›์€ ์‹œ์Šคํ…œ์ด Celery๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— Celery๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์—†์• ๊ณ  ์šฐ๋ฆฌ๊ฐ€ ์ฒซ ๋ฒˆ์งธ ๋ฐฐ๋‹ฌ์„ ๋งˆ์น˜๋ฉด ๋‚ด ์ž์‹ ์„ ์“ธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋น„ํŠธ ๋ฌธ์ œ ์™ธ์—๋„ ์ž‘์—… ์‹คํ–‰์—์„œ ์ตœ๋Œ€ ํ•œ ๋ฒˆ ์†์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ์ž ๊ธˆ์„ ์‚ฌ์šฉํ•˜๋„๋ก ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์€ ์—„์ฒญ๋‚œ ๋†๋‹ด์ž…๋‹ˆ๋‹ค.

๋‹น์‹ ์€ ๊ณ ์ž„๊ธˆ ์ง์—…์„ ๊ฐ€์งˆ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— OSS์ธ ๋‹น์‹ ์ด ์ž˜ํ•˜๋Š” ๊ฒƒ์— ์ถฉ์‹คํ•˜์‹ญ์‹œ์˜ค.

@mchen-scala ๋‹น์‹ ์€ ์‚ด๋ฉด์„œ ๋ณต์žกํ•œ ์‹œ์Šคํ…œ์„ ์ž‘์„ฑํ•œ ์ ์ด ์—†์œผ๋ฉฐ ์ด ํ‹ฐ์ผ“์˜ ๋งฅ๋ฝ์กฐ์ฐจ ์ดํ•ดํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ฆ‰, Celery 4 ์‹œ๋ฆฌ์ฆˆ์—๋Š” ์‹œ๊ฐ„๋Œ€๊ฐ€ UTC๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ CELERY_BEAT_SCHEDULE๋ฅผ ๋”ฐ๋ฅด์ง€ ์•Š๋Š” ์ผ๋ถ€ ๋ฒ„์ „์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ท€ํ•˜์˜ ์š”์ ์€ ์—ฌ๋Ÿฌ ์ˆ˜์ค€์—์„œ ๋ชจ๋‘ ๋ถ€์ •ํ™•ํ•˜๊ณ  ๋ชจ์š•์ ์ž…๋‹ˆ๋‹ค. ๋†๋‹ด์€ ๋‹น์‹ ์ด ์—ฌ๋Ÿฌ ์‚ฐ์—…์— ๊ฑธ์ณ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์˜ ์š”๊ตฌ์— ๋งž๋Š” OSS ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•ด ์šฐ๋ฆฌ๋ฅผ ๋ชจ์š•ํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๊ธฐ์— ์™”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹น์‹ ์ด ๊ณ ์šฉ์ฃผ๋ฅผ ์œ„ํ•ด ์ž‘์„ฑํ•œ ๋ชจ๋“  ๊ฒƒ์ด Celery ํ”„๋กœ์ ํŠธ๋งŒํผ ๋งŽ์€ ๋น›์„ ๋ณด์ง€ ๋ชปํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์ด์ „ ์ž‘์—…์„ ์ฐธ์กฐํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์• ์ž์ผ ์„ธ๊ณ„์—์„œ๋Š” 2-4์ฃผ๋งˆ๋‹ค ๋ฆด๋ฆฌ์Šคํ•  ๊ฒƒ์ด๋ฏ€๋กœ, ๋‹น์‹ ์ด ๊ตฌ์ถ•ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐ๋˜๋Š” ์ด ๋ฉ‹์ง„ ์‹œ์Šคํ…œ ๋Œ€์‹  ์ƒ์†๋ฐ›์€ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์€ ๋‹น์‹ ์ด ๋ถ€ํ’€๋ ค์ง„ ์ž๊ธฐ ๊ฐ€์น˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋‚˜์—๊ฒŒ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

๋˜ํ•œ mchen-scala, ์…€๋Ÿฌ๋ฆฌ๋ฅผ ๋„๋„๋ก ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์ฃผ๋กœ ์šฐ๋ฆฌ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ๋‹น์‹ ์˜ ํƒœ๋„๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ €๋Š” OSS๋ฅผ ํ™œ์šฉํ•˜๊ณ  ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ์ง€์›์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋†’์€ ๊ธ‰์—ฌ๋ฅผ ๋ฐ›๋Š” ์ง์—…์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹น์‹ ์ด ์ž์‹ ์˜ ๋งŒํŠธ๋ผ๋ฅผ ๋”ฐ๋ฅด๊ณ  ์ž์‹ ์ด ์ž˜ํ•˜๋Š” ๊ฒƒ์— ์ถฉ์‹คํ•  ๊ฒƒ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ถ„๋ช…ํžˆ ๊ธฐ์กด ์†”๋ฃจ์…˜์˜ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ž์‹ ์˜ ์†”๋ฃจ์…˜์„ ๋กค๋งํ•˜๊ณ  ๋‚˜๋จธ์ง€ ์šฐ๋ฆฌ์—๊ฒŒ ๋ฐ˜์‚ฌํšŒ์  ๋ฐ”๋ณด๊ฐ€ ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‹œ์•„!

๋‚˜๋Š” ์‹ค์ œ ์‹œ๊ฐ„๋Œ€ ์˜คํ”„์…‹์ด ์•„๋‹ˆ๋ผ๊ณ  ํ™•์‹ ํ•˜๋Š” ์˜คํ”„์…‹ +20์—์„œ ์ด๋ฏธ ์‹œ๊ฐ„๋Œ€๋ฅผ ์ธ์‹ํ•˜๊ณ  ์žˆ๋Š” ๋‚ ์งœ ์‹œ๊ฐ„์„ ๋ฏธ๋ž˜ ๋‚ ์งœ ์‹œ๊ฐ„์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ •ํ™•ํ•œ ์ฝ”๋“œ ๋ผ์ธ์„ ์ง€์ ํ–ˆ์Šต๋‹ˆ๋‹ค.
2017-10-11 22:42:27.041931-04:00์€ ๋‚ด Pull Request์˜ ๋ผ์ธ์—์„œ 2017-10-12 22:42:27.041931+20:00์œผ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.
๋ถ„๋ช…ํžˆ UTC ๋ชจ๋“œ์—์„œ datetime ๊ฐ์ฒด๋Š” ์ฝ”๋“œ์˜ ์ด ์‹œ์ ์—์„œ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค์Œ์— ์ผ์–ด๋‚˜๋Š” ์ผ์€ ๋‚˜๋จธ์ง€_๋ธํƒ€์˜ ๊ฒฐ๊ณผ๊ฐ€ -1์ผ, 1:27:32.958069 ์ž‘์—… ์ผ์ •๋ณด๋‹ค ๋Šฆ์€ ๊ฒƒ์œผ๋กœ ํ•ด์„๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ทธ๊ฒƒ์€ ์ž‘์—…์„ ๋ณด๋‚ด๊ณ  ํ•ญ์ƒ ๋’ค์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜ค๋ž˜ ์ž์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ž‘์—… ๋งˆ๊ฐ์ผ๊นŒ์ง€ ํ•ญ์ƒ -1์ผ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ž‘์—…์„ ๊ณ„์†ํ•ด์„œ ์ดˆ๊ณผํ•ฉ๋‹ˆ๋‹ค.

๋‚ด PR์ด ์‹ค์ œ ์˜ค๋ž˜๋œ ์ฝ”๋“œ ์ค„์— ์ฃผ์„์„ ๋‹ฌ๊ณ  ์žˆ์Œ์„ ์ธ์ •ํ•˜์ง€๋งŒ ๋ชจ๋“  ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š” ํ†ต๊ณผํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์˜€๊ณ  ๋‚ด ํ…Œ์ŠคํŠธ์—์„œ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. ํ˜‘๋ ฅ์ž ํ”ผ๋“œ๋ฐฑ์—์„œ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ์ด๊ฒƒ์ด Python 2.7๊ณผ Python 3.5 ๋ฐ 3.6 ๋ฒ„์ „์—์„œ ๋ฌธ์ œ์ž„์„ ๋ณด์—ฌ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฒ„์ „์˜ ๋ฒ„๊ทธ๊ฐ€ ์•„๋‹ˆ๋ผ ๋‚ด๊ฐ€ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•œ ๋ฒ„์ „์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋น„ํŠธ์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  django-celery-beat๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋ ค๊ณ ํ–ˆ์Šต๋‹ˆ๋‹ค ... ํ•˜๋ฃจ๋Š” ์ฃผ๋กœ github ๋ฌธ์ œ๋ฅผ ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค :(

CELERY_TIMEZONE = 'UTC' ์‚ฌ์šฉํ•  ๋•Œ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์ € ์„ธํŠธ๋กœ ํ•˜๋Š”๊ฒƒ๋„ ๋ฌธ์ œ์ธ๋ฐ..

@xeor CELERY_ENABLE_UTC = True๋กœ ์„ค์ •ํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

localize()๋กœ ์ „๋‹ฌ๋˜๋Š” datetime์˜ ์‹ค์ œ ๋ฌธ์ œ๋Š” ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•ด UTC๊ฐ€ ์•„๋‹Œ ์ง€์—ญ ์‹œ๊ฐ„๋Œ€๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น datetime์ด ์ด๋ฏธ localize๋กœ ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์ด ์ •ํ™•ํ•˜๊ณ  dt = dt.astimezone(tz)์ด ์ด๋ฅผ a๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜๋ฏธ๊ฐ€ ์—†๋Š” ์‹œ๊ฐ„๋Œ€๊ฐ€ ํฌํ•จ๋œ ๋ฌด์˜๋ฏธํ•œ ๋ฏธ๋ž˜ ๋‚ ์งœ/์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค.

@xeor ๋‹ค์Œ ์„ค์ •์—์„œ๋„ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

CELERY_TIMEZONE = 'UTC'
CELERY_ENABLE_UTC = True
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'

์ด์ œ ์–ด๋ฆฌ์„์€ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ Celery์™€ django-celery-beat๋ฅผ ๋ชจ๋‘ ์ œ๊ฑฐํ•˜๊ณ  ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ๋‹ค์‹œ ์„ค์น˜ํ–ˆ๋Š”๋ฐ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ณ ๋งˆ์›Œ.. ๋‚˜๋Š” ์šด์—†์ด ๊ทธ 3 ๊ฐœ ๋ชจ๋‘๋กœ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค.
๋‚˜์ค‘์— ๊นจ๋—ํ•œ ํ™˜๊ฒฝ์œผ๋กœ ๋ฆฌ๋นŒ๋“œํ•ด์„œ ํ•ด๋ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค..

@xeor ๊ธ€์Ž„, ์ด ๋ฌธ์ œ๊ฐ€ ๋‹น์‹ ์ด ๊ฒช๊ณ  ์žˆ๋Š” ๋ฌธ์ œ๊ฐ€ ์•„๋‹ ๊ฐ€๋Šฅ์„ฑ์ด ๋งค์šฐ ๋†’์Šต๋‹ˆ๋‹ค. ์ด ํ‹ฐ์ผ“์˜ ์กฐ์–ธ์€ ์ง€๊ธˆ๊นŒ์ง€ ์ด ๋ฌธ์ œ๋ฅผ ๊ฒช๊ณ  ์žˆ๋Š” ๋ชจ๋“  ์‚ฌ์šฉ์ž์—๊ฒŒ ์ผ๊ด€์ ์ด๋ฉฐ, ์ด๋กœ ์ธํ•ด ์˜ˆ์•ฝ๋œ ์ž‘์—…์„ ์ œ์–ดํ•  ์ˆ˜ ์—†๋Š” ๋Œ€๊ธฐ์—ด์— ๋„ฃ๊ณ  ์ž‘์—…์ด ์Œ“์ด๊ณ  ์ œ๋Œ€๋กœ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜ค๋ฅ˜ ๋˜๋Š” ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๊ฒฐ๊ณผ์— ๋Œ€ํ•ด ๋งŽ์€ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ๋‚จ๊ธฐ์ง€ ์•Š์€ ๊ฒƒ์ฒ˜๋Ÿผ ํŠน์ • ๋ฌธ์ œ๋ฅผ ๋” ์ž์„ธํžˆ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

ํ•ญ์ƒ ๊ธฐ์˜๊ฒŒ ๋„์™€๋“œ๋ฆฝ๋‹ˆ๋‹ค. DatabaseScheduler ์—†์ด ์ด ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๊ณ  ์‹œ๊ฐ„๋Œ€๋งŒ ๋ณ€๊ฒฝํ•˜์—ฌ ์ˆ˜์ •ํ–ˆ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์‹ญ์‹œ์˜ค. ๋‚ด ํ…Œ์ŠคํŠธ์—์„œ ์ด ๋ฒ„๊ทธ ์ด์ „๊ณผ ์ดํ›„์— ์ƒ์„ฑ๋œ ์ผ์ • ํŒŒ์ผ์ด ๋™์ผํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฒ„๊ทธ๊ฐ€ ์Šค์ผ€์ค„๋Ÿฌ์— ๊ด€ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ localize() ํ˜ธ์ถœ๋กœ ์ „๋‹ฌ๋˜๋Š” ๋‚ ์งœ ์‹œ๊ฐ„ ์œ ํ˜•์— ๊ด€ํ•œ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ฏธ๋ฆฌ ์•Œ๋ ค์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

์•„๋งˆ ๋‹ค์Œ ์ฃผ ๋ง์ด๋‚˜ ๊ทธ ๋‹ค์Œ ์ฃผ ์ „์— ๋” ๊นŠ์€ ๋ฃจํ”„๋ฅผ ์žก์„ ์ˆ˜ ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ ๋™์•ˆ ์ด ์Šค๋ ˆ๋“œ์˜ ์ง„ํ–‰ ์ƒํ™ฉ์— ๋Œ€ํ•ด ๊ณ„์† ์•Œ๋ ค ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‚ด ์„ค์ •์ด ํŠน๋ณ„ํ•œ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ docker, amqp, rabbitmq ๋ฐ ๋ชจ๋“  ์ตœ์‹  ๋ฒ„์ „์˜ celery python ํŒจํ‚ค์ง€(rabbitmq๊ฐ€ ์•„๋‹˜)๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค)..

๋น„์Šทํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋•Œ๋•Œ๋กœ celery-beat๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(์ค‘๊ฐœ์—…์ฒด์— ์ž‘์—…์„ ๋ณด๋‚ด์ง€ ์•Š์Œ). ๋˜ํ•œ 59๋ถ„๋งˆ๋‹ค ๋„ˆ๋ฌด ๋งŽ์€ ์ž‘์—…์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
1๋ถ„๋งˆ๋‹ค ์‹คํ–‰๋˜๋Š” ํ…Œ์ŠคํŠธ ์ž‘์—…์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

[2017-11-09 20:52:00,052: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 20:53:00,049: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 20:54:00,019: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 20:55:00,027: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 20:56:00,049: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 20:57:00,004: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 20:58:00,045: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 20:59:00,032: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 20:59:00,035: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 20:59:00,037: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 20:59:00,044: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
...
[2017-11-09 20:59:59,977: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 20:59:59,979: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 20:59:59,981: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 20:59:59,986: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 20:59:59,989: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 20:59:59,994: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 20:59:59,997: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 21:00:00,000: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 21:01:00,047: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 21:02:00,047: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)
[2017-11-09 21:03:00,053: INFO/MainProcess] Scheduler: Sending due task test-task (tasks.test.test_task)

59๋ถ„์— ์—ฌ๋Ÿฌ ์ž‘์—…์ด ์‹คํ–‰๋˜๊ธฐ ์‹œ์ž‘ํ•˜๊ณ  ์‹œ๊ฐ„์ด 0๋ถ„์— ๋„๋‹ฌํ•˜๋ฉด ์˜ˆ์ƒ๋Œ€๋กœ ๋‹ค์‹œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
์ด ๋ฒ„๊ทธ์— ๋Œ€ํ•œ ๋‹จ์„œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค..?

์ด๊ฒƒ์€ ์…€๋Ÿฌ๋ฆฌ 4.1.0์˜ ์„ค์ •์ž…๋‹ˆ๋‹ค.

timezone = 'Asia/Seoul'
enable_utc = False

์ผ์ •์— ํŒŒ์ผ db๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

python 3.6.3, pytz 2017.3, django 1.11.7, celery 4.1.0 ๋ฐ django-celery-beat 1.1.0์—์„œ๋„ ์ด ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋จผ์ € ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ง€์›๋‹ˆ๋‹ค.

#update django_celery_beat_periodictask set last_run_at = NULL;
#select name, last_run_at from django_celery_beat_periodictask;
           name           |          last_run_at          
--------------------------+-------------------------------
celery.backend_cleanup |                                                       
> pipenv run celery beat -A appname -l debug --scheduler django_celery_beat.schedulers:DatabaseScheduler
Loading .env environment variablesโ€ฆ
celery beat v4.1.0 (latentcall) is starting.
__    -    ... __   -        _
LocalTime -> 2017-11-30 08:28:58
Configuration ->
    . broker -> amqp://guest:**<strong i="9">@localhost</strong>:5672//
    . loader -> celery.loaders.app.AppLoader
    . scheduler -> django_celery_beat.schedulers.DatabaseScheduler

    . logfile -> [stderr]@%DEBUG
    . maxinterval -> 5.00 seconds (5s)
[2017-11-30 08:28:58,945: DEBUG/MainProcess] Setting default socket timeout to 30
[2017-11-30 08:28:58,946: INFO/MainProcess] beat: Starting...
[2017-11-30 08:28:58,946: DEBUG/MainProcess] DatabaseScheduler: initial read
[2017-11-30 08:28:58,946: INFO/MainProcess] Writing entries...
[2017-11-30 08:28:58,968: DEBUG/MainProcess] DatabaseScheduler: Fetching database schedule
[2017-11-30 08:28:59,068: DEBUG/MainProcess] Current schedule:
<ModelEntry: celery.backend_cleanup celery.backend_cleanup(*[], **{}) <crontab: 0 4 * * * (m/h/d/dM/MY)>>
[2017-11-30 08:28:59,115: INFO/MainProcess] DatabaseScheduler: Schedule changed.
[2017-11-30 08:28:59,115: INFO/MainProcess] Writing entries...
[2017-11-30 08:28:59,115: DEBUG/MainProcess] DatabaseScheduler: Fetching database schedule
[2017-11-30 08:28:59,121: DEBUG/MainProcess] Current schedule:
<ModelEntry: celery.backend_cleanup celery.backend_cleanup(*[], **{}) <crontab: 0 4 * * * (m/h/d/dM/MY)>>
[2017-11-30 08:28:59,122: DEBUG/MainProcess] beat: Ticking with max interval->5.00 seconds
[2017-11-30 08:28:59,138: DEBUG/MainProcess] Start from server, version: 0.9, properties: {'capabilities': {'publisher_confirms': True, 'exchange_exchange_bindings': True, 'basic.nack': True, 'consumer_cancel_notify': True, 'connection.blocked': True, 'consumer_priorities': True, 'authentication_failure_close': True, 'per_consumer_qos': True, 'direct_reply_to': True}, 'cluster_name': 'rabbit<strong i="10">@Jupiter</strong>', 'copyright': 'Copyright (C) 2007-2017 Pivotal Software, Inc.', 'information': 'Licensed under the MPL.  See http://www.rabbitmq.com/', 'platform': 'Erlang/OTP 20.1', 'product': 'RabbitMQ', 'version': '3.6.14'}, mechanisms: [b'AMQPLAIN', b'PLAIN'], locales: ['en_US']
[2017-11-30 08:28:59,152: DEBUG/MainProcess] using channel_id: 1
[2017-11-30 08:28:59,153: DEBUG/MainProcess] Channel open
[2017-11-30 08:28:59,154: DEBUG/MainProcess] beat: Synchronizing schedule...
[2017-11-30 08:28:59,155: INFO/MainProcess] Writing entries...
[2017-11-30 08:28:59,160: INFO/MainProcess] Scheduler: Sending due task celery.backend_cleanup (celery.backend_cleanup)
[2017-11-30 08:28:59,161: DEBUG/MainProcess] celery.backend_cleanup sent. id->1dd626be-1dea-43ec-b000-ab61fdd33f9d
[2017-11-30 08:28:59,163: INFO/MainProcess] Scheduler: Sending due task celery.backend_cleanup (celery.backend_cleanup)
[2017-11-30 08:28:59,163: DEBUG/MainProcess] celery.backend_cleanup sent. id->7a9c7d44-e570-4a5a-9803-0a8e5111f035
[2017-11-30 08:28:59,165: INFO/MainProcess] Scheduler: Sending due task celery.backend_cleanup (celery.backend_cleanup)
[2017-11-30 08:28:59,166: DEBUG/MainProcess] celery.backend_cleanup sent. id->114ee8e1-4b3c-4f43-a632-9a249d7db364
[2017-11-30 08:28:59,167: INFO/MainProcess] Scheduler: Sending due task celery.backend_cleanup (celery.backend_cleanup)
[2017-11-30 08:28:59,168: DEBUG/MainProcess] celery.backend_cleanup sent. id->5b7f3825-d6c8-43a5-b056-2d567ec2c4df
[2017-11-30 08:28:59,170: INFO/MainProcess] Scheduler: Sending due task celery.backend_cleanup (celery.backend_cleanup)
[2017-11-30 08:28:59,171: DEBUG/MainProcess] celery.backend_cleanup sent. id->f1bfb936-0dd1-47b6-be10-3763d4446758
[2017-11-30 08:28:59,172: INFO/MainProcess] Scheduler: Sending due task celery.backend_cleanup (celery.backend_cleanup)
[2017-11-30 08:28:59,173: DEBUG/MainProcess] celery.backend_cleanup sent. id->7a12f2da-3717-45ab-b018-6b4fd7b83982
[2017-11-30 08:28:59,175: INFO/MainProcess] Scheduler: Sending due task celery.backend_cleanup (celery.backend_cleanup)
[2017-11-30 08:28:59,175: DEBUG/MainProcess] celery.backend_cleanup sent. id->64fbd61d-e80e-4a32-a49d-31ddc7e155c7
[2017-11-30 08:28:59,177: INFO/MainProcess] Scheduler: Sending due task celery.backend_cleanup (celery.backend_cleanup)
[2017-11-30 08:28:59,179: DEBUG/MainProcess] celery.backend_cleanup sent. id->ff38e88e-e7e8-4436-9724-9c416dde4d72
[2017-11-30 08:28:59,181: INFO/MainProcess] Scheduler: Sending due task celery.backend_cleanup (celery.backend_cleanup)
[2017-11-30 08:28:59,181: DEBUG/MainProcess] celery.backend_cleanup sent. id->d5116c47-df14-4f3e-a4d1-09087cd1af80
[2017-11-30 08:28:59,183: INFO/MainProcess] Scheduler: Sending due task celery.backend_cleanup (celery.backend_cleanup)
...

๊ทธ๋ฆฌ๊ณ  ๋Œ€๊ธฐ์—ด์€ 600/์ดˆ์˜ ์†๋„๋กœ ๊ณ„์† ์ฑ„์›Œ์ง‘๋‹ˆ๋‹ค.

# select name, last_run_at from django_celery_beat_periodictask;
           name           |          last_run_at          
--------------------------+-------------------------------
 celery.backend_cleanup   | 2017-11-30 16:40:59.352453-08 

๋‚ด ์„ค์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค(๋ฌธ์„œ๊ฐ€ ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ๋งค์šฐ ๋ถˆ๋ถ„๋ช…ํ•˜๊ณ  ๊ตฌ์‹์ด๊ธฐ ๋•Œ๋ฌธ์— ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ์„ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค):

settings.py
CELERY_TIMEZONE = 'Canada/Pacific'
CELERY_ENABLE_UTC=False
USE_TZ = True
TIME_ZONE = 'Canada/Pacific'

celery.py
app = Celery('MyApp')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.conf.timezone = 'Canada/Pacific'
app.conf.enable_utc = False

๋”ฐ๋ผ์„œ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ๋Š”์ง€๋Š” ์…€๋Ÿฌ๋ฆฌ๊ฐ€ 08:28:59-08์— ์ž‘์—…์„ ์‹คํ–‰ํ•˜์ง€๋งŒ last_run_time์„ ์ €์žฅํ•  ๋•Œ ์ €์žฅํ•˜๊ธฐ ์ „์— 16:28:59-08์„ ์–ป๋Š” ๋ฐ ์—ฌ์ „ํžˆ 8์‹œ๊ฐ„์ด ์ถ”๊ฐ€๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. DB.

schedules.py๋ฅผ ๊ฐ„๋‹จํžˆ ์‚ดํŽด๋ณด๋ฉด crontab.is_due()์—์„œ timedelta ๋˜๋Š” #์ดˆ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์—์„œ ๊ณ„์† ํŒŒ๊ณ ๋“ค ์‹œ๊ฐ„์ด ์—†์ง€๋งŒ ๋ถ„๋ช…ํžˆ crontab ํด๋ž˜์Šค ๋‚ด๋ถ€์˜ ๋ฌด์–ธ๊ฐ€๊ฐ€ ํ˜„์žฌ ์‹œ๊ฐ„๊ณผ ํ˜„์žฌ ์‹œ๊ฐ„ ์‚ฌ์ด์˜ tz replaced (๋ณ€ํ™˜๋˜์ง€ ์•Š์Œ)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ timedelta๋ฅผ ์–ป๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” replace ์‹œ๊ฐ„๋Œ€์˜ ๋ผ์ธ์„ ๋งค์šฐ ์˜์‹ฌํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค -- ์ด ๋ฒ„๊ทธ๊ฐ€ ์žˆ๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ์ด ๋งˆ์Šคํ„ฐ๋ฅผ ๋ณต์ œํ•˜๊ณ  ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜๋Š”์ง€ ๋‹ค์‹œ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด. ์ง€๋‚œ ๋ฐค์— ์ œ PR์ด ๋ณ‘ํ•ฉ๋˜์—ˆ๊ณ  ๋ฒ„๊ทธ๊ฐ€ ์ˆ˜์ •๋˜์—ˆ์Œ์„ ๋ฐฉ๊ธˆ ํ™•์ธํ–ˆ์ง€๋งŒ DB ์Šค์ผ€์ค„๋Ÿฌ ๋˜๋Š” ๊ธฐํƒ€ ๋ฐฑ์—”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด ์ถ”๊ฐ€ ํ™•์ธ์„ ๋ฐ›๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”!

976515108a4357397a3821332e944bb85550dfa2 ์ด๊ฒƒ์„ ์ ์šฉํ•˜๊ณ  ํ™•์ธ

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰