๐1. APScheduler ์ค์นํ๊ธฐ
pip install apscheduler
์ถ๊ฐ์ ์ธ ์์กด์ฑ ์ค์น
- APScheduler๋ ๊ธฐ๋ณธ์ ์ผ๋ก `threading`์ ์ฌ์ฉํ์ง๋ง, ์คํ ํ๊ฒฝ์ ๋ฐ๋ผ ๋ค๋ฅธ ๋ฐฉ์๋ ์ง์ํฉ๋๋ค.
- ํน์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ค๋ฉด ์๋ ํจํค์ง๋ ํจ๊ป ์ค์นํด์ผ ํ ์ ์์ต๋๋ค.
pip install apscheduler[asyncio] # asyncio ํ๊ฒฝ ์ง์ pip install apscheduler[gevent] # gevent ํ๊ฒฝ ์ง์ pip install apscheduler[tornado] # tornado ํ๊ฒฝ ์ง์ pip install apscheduler[redis] # Redis ๊ธฐ๋ฐ Job Store ์ฌ์ฉ
๐ 2. APScheduler์ ์ฃผ์ ๊ฐ๋
APScheduler๋ ์ฌ๋ฌ ๊ฐ์ ์์ (Job)์ ์์ฝํ์ฌ ์คํํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
์ด๋ฅผ ์ํด ์๋์ ๊ฐ์ ๊ฐ๋ ์ ์ดํดํด์ผ ํฉ๋๋ค.
๊ฐ๋ | ์ค๋ช |
Job Store (์์ ์ ์ฅ์) | ์์ฝ๋ ์์ ์ ์ ์ฅํ๋ ๊ณต๊ฐ (๊ธฐ๋ณธ์ ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅ๋์ง๋ง, DB, Redis ๋ฑ๋ ๊ฐ๋ฅ) |
Trigger (ํธ๋ฆฌ๊ฑฐ) | ์์ ์ด ์คํ๋ ์กฐ๊ฑด์ ์ ์ (ํน์ ์๊ฐ, ์ฃผ๊ธฐ์ ์ผ๋ก ์คํ ๋ฑ) |
Executor (์คํ๊ธฐ) | ์์ ์ ์คํํ๋ ๋ฐฉ์ (์ค๋ ๋, ํ๋ก์ธ์ค, ๋น๋๊ธฐ ๋ฑ) |
Scheduler (์ค์ผ์ค๋ฌ) | ์ ์ฒด ์์ ์ ๊ด๋ฆฌํ๊ณ ์คํํ๋ ์ญํ |
๐ 3. APScheduler ์ฌ์ฉ ์์
1๏ธโฃ ๊ธฐ๋ณธ ์ค์ผ์ค๋ฌ ์คํ
from apscheduler.schedulers.background import BackgroundScheduler
import time
def my_task():
print("์์
์ด ์คํ๋์์ต๋๋ค!")
scheduler = BackgroundScheduler()
scheduler.add_job(my_task, 'interval', seconds=10) # 10์ด๋ง๋ค ์คํ
scheduler.start()
try:
while True:
time.sleep(1) # ํ๋ก๊ทธ๋จ์ด ์ข
๋ฃ๋์ง ์๋๋ก ์ ์ง
except KeyboardInterrupt:
scheduler.shutdown()
โ ์ค๋ช :
- `BackgroundScheduler()`๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ผ์ค๋ฌ๋ฅผ ์คํ
- `add_job()`์ ์ฌ์ฉํด 10์ด๋ง๋ค ์คํ๋๋ ์์ ์ ์ถ๊ฐ
- `scheduler.start()`๋ก ์คํ ์์
2๏ธโฃ ํน์ ์๊ฐ์ ํ ๋ฒ ์คํ
from apscheduler.schedulers.blocking import BlockingScheduler
from datetime import datetime
def my_task():
print(f"์์
์คํ๋จ: {datetime.now()}")
scheduler = BlockingScheduler()
scheduler.add_job(my_task, 'date', run_date='2025-02-20 15:30:00')
scheduler.start()
โ ์ค๋ช :
- `date` ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ฌ์ฉํด ํน์ ์๊ฐ(2025๋ 2์ 20์ผ 15์ 30๋ถ)์ ์คํ
- `BlockingScheduler()`๋ ํ๋ก๊ทธ๋จ์ด ์คํ๋ ์ฑ๋ก ์ ์ง๋จ
3๏ธโฃ ๋งค์ผ ํน์ ์๊ฐ์ ์คํ
from apscheduler.schedulers.background import BackgroundScheduler
scheduler = BackgroundScheduler()
scheduler.add_job(my_task, 'cron', hour=0, minute=30) # ๋งค์ผ ์ค์ 9์ 30๋ถ ์คํ
scheduler.start()
โ ์ค๋ช :
- `cron` ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ฌ์ฉํด ๋งค์ผ ํน์ ์๊ฐ (9์ 30๋ถ) ์ ์คํ
4๏ธโฃ ๋งค์ฃผ ์์์ผ, ์์์ผ, ๊ธ์์ผ ์คํ
scheduler.add_job(my_task, 'cron', day_of_week = 'mon,wed,fri', hour=10, minute=0)
โ ์ค๋ช :
- `day_of_week` ๋ฅผ ์ฌ์ฉํด ๋งค์ฃผ ์/์/๊ธ ์ค์ 10์์ ์คํ
5๏ธโฃ ๋์ ์ผ๋ก ์์ ์ถ๊ฐ ๋ฐ ์ ๊ฑฐ
job = scheduler.add_job(my_task, 'interval', minute=5)
job.remove() # ์์
์ญ์
โ ์ค๋ช :
- `add_job` ์ ํตํด ๋์ ์ผ๋ก ์์ ์ถ๊ฐ
- `remove()`๋ฅผ ํธ์ถํ์ฌ ํน์ ์์ ์ญ์ ๊ฐ๋ฅ
6๏ธโฃ ์คํ ์ค์ธ ๋ชจ๋ ์์ ์กฐํ
for job in scheduler.get_jobs():
print(f"๋ฑ๋ก๋ ์์
: {job}")
โ ์ค๋ช :
- `get_jobs()`๋ฅผ ํธ์ถํ๋ฉด ํ์ฌ ๋ฑ๋ก๋ ๋ชจ๋ ์์ ๋ชฉ๋ก์ ๊ฐ์ ธ์ฌ ์ ์์
๐ 4. APScheduler์์ Job Store ์ฌ์ฉํ๊ธฐ
๊ธฐ๋ณธ์ ์ผ๋ก APScheduler๋ ๋ฉ๋ชจ๋ฆฌ์ ์์ ์ ์ ์ฅํ์ง๋ง, ํ์ผ ๋๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ ์๋ ์์.
1๏ธโฃ SQLite์ ์์ ์ ์ฅ
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
jobstores = {
'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite')
}
scheduler = BackgroundScheduler(jobstores=jobstores)
scheduler.start()
โ ์ค๋ช :
- APScheduler์ Job Store๋ฅผ SQLite๋ก ์ค์ ํ๋ฉด, ์์ ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋จ
- `sqlite:///jobs.sqlite`๋ ํ์ฌ ํด๋์ jobs.sqlite ํ์ผ์ ์์ฑํจ
2๏ธโฃ Redis์ ์์ ์ ์ฅ
from apscheduler.jobstores.redis import RedisJobStore
jobstores = {
'default': RedisJobStore(host='localhost', port=6379)
}
scheduler = BackgroundScheduler(jobstores=jobstores)
scheduler.start()
โ ์ค๋ช :
- Redis๋ฅผ ์ฌ์ฉํ์ฌ Job Store๋ฅผ ์ค์ ํ๋ฉด, ์์ ์ด Redis์ ์ ์ฅ๋จ
- ์ด ๋ฐฉ๋ฒ์ ์ฌ๋ฌ ์๋ฒ์์ ๋์ผํ ์์ ์ ๊ณต์ ํ ๋ ์ ์ฉํจ
๐ 5. APScheduler์์ Executor ์ค์ ํ๊ธฐ
Executor๋ ์์ ์ ์คํํ๋ ๋ฐฉ์์ ๊ฒฐ์ ํจ
1๏ธโฃ ๊ธฐ๋ณธ ์ค์ (ThreadPoolExecutor)
from apscheduler.executors.pool import ThreadPoolExecutor
executors = {
'default': ThreadPoolExecutor(max_workers=5) # ์ต๋ 5๊ฐ์ ์์
๋์ ์คํ
}
scheduler = BackgroundScheduler(executors=executors)
scheduler.start()
โ ์ค๋ช :
- ThreadPoolExecutor(max_workers=5)๋ฅผ ์ฌ์ฉํ๋ฉด ์ต๋ 5๊ฐ์ ์์ ์ ๋์์ ์คํํ ์ ์์
2๏ธโฃ ๋ฉํฐ ํ๋ก์ธ์ค ์คํ (ProcessPoolExecutor)
from apscheduler.executors.pool import ProcessPoolExecutor
executors = {
'default': ProcessPoolExecutor(max_workers=3) # ๋ฉํฐ ํ๋ก์ธ์ค๋ก ์คํ
}
scheduler = BackgroundScheduler(executors=executors)
scheduler.start()
โ ์ค๋ช :
- ProcessPoolExecutor๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉํฐ ํ๋ก์ธ์ค๋ฅผ ํ์ฉํ์ฌ ์คํ ๊ฐ๋ฅ
- CPU ๋ถํ๊ฐ ๋์ ์์ ์ ์ ํฉ
๐ 6. APScheduler์ ์คํ ๋ฐฉ์
APScheduler๋ 4๊ฐ์ง ๋ฐฉ์์ผ๋ก ์คํํ ์ ์์.
์คํ ๋ฐฉ์ | ์ค๋ช | |
BlockingScheduler | ํ๋ก๊ทธ๋จ์ด ์ข ๋ฃ๋์ง ์๊ณ ์ ์ง๋จ (๋จ์ผ ํ๋ก์ธ์ค์์ ์คํํ ๋ ์ฌ์ฉ) | |
BackgroundScheduler | ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์คํ๋จ (์ผ๋ฐ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ํฉ) | |
AsyncIOScheduler | asyncio ์ด๋ฒคํธ ๋ฃจํ์์ ์คํ๋จ (๋น๋๊ธฐ ์์ ์ ์ ํฉ) | |
TornadoScheduler | Tornado ํ๋ ์์ํฌ์์ ์คํ๋จ |
โ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ:
scheduler = BackgroundScheduler()
scheduler.start()
โ FastAPI ๋๋ Flask ๊ฐ์ ์น ์๋ฒ์์๋:
scheduler = BackgroundScheduler()
scheduler.start(paused=True) # ์น ์ ํ๋ฆฌ์ผ์ด์
๊ณผ ํจ๊ป ์คํ
๐ 7. ๊ฒฐ๋ก
APScheduler๋ฅผ ์ฌ์ฉํ๋ฉด ์ค์ผ์ค๋ง์ด ํ์ํ ์์ ์ ๊ฐํธํ๊ฒ ์๋ํํ ์ ์์ต๋๋ค.
- `interval`, `date`, `cron` ํธ๋ฆฌ๊ฑฐ๋ฅผ ํ์ฉํ์ฌ ๋ค์ํ ์คํ ์ฃผ๊ธฐ๋ฅผ ์ค์ ๊ฐ๋ฅ
- SQLite, Redis ๊ฐ์ Job Store๋ฅผ ์ด์ฉํ์ฌ ์์ ์ ์ ์ฅ ๊ฐ๋ฅ
- Thread, Process, Async ๋ฑ์ ํ์ฉํด ์คํ ๋ฐฉ์ ์กฐ์ ๊ฐ๋ฅ
'Python' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Python] datetime.weekday() (0) | 2025.02.24 |
---|---|
[Python] strftime๊ณผ strptime (0) | 2025.01.23 |
[Python] ์ด๋ฉ์ผ์ ํ์ผ ์ฒจ๋ถํ๊ธฐ - smtplib (2) | 2024.11.19 |
[Python] ํ์ด์ฌ ๋ ์ง ํํ ํ๊ธ ์๋ฌ (1) | 2024.11.14 |
[Python] UIAutomation for Windows ๊ฐ์ฒด ์ปจํธ๋กคํ๊ธฐ (0) | 2024.10.22 |