1. 什麼是Job?
Job直譯過來就是工作,可以是任意的Python函式,你可以把你想要非同步執行的任務都寫成Job函式。簡而言之,Job就是你想執行的操作。例如,我想統計任意網頁的字元數量,可以寫一個這樣的Job函式:
import requests
def count_words(url):
return len(requests.get(url).text.split())
這樣一個函式就可以稱之為Job。
2. 什麼是Queue?
當我有很多Job時,假如我現在有3個Job,分別是j1、j2、j3,那麼當計算機要執行這些任務的時候,會按照j1、j2、j3加入的順序來執行這些Job,這樣的一個可以忘裡面新增Job,並且能夠順序執行佇列稱之為Queue。
例如,我們可以這樣來構建一個Queue:
import redis from rq import Queue
redis_conn = redis.Redis()
q = Queue('default', connection=redis_conn) # 第一個引數是Queue的名稱,可以不傳,預設為default
3. 怎麼把Job放到佇列裡面去?
j = q.enqueue(count_words, args=('',))
enqueue第一引數是Job函式,args是Job函式的引數,關鍵字引數可以透過kwargs傳入。
4. 什麼是Worker?
Worker是Job的消費者,簡單來說,你把很多Job加入到了Queue,誰來執行這些Job呢?當然就是Worker啦,你也可以看出Worker必須是獨立的程式,這個程式從Redis裡面獲取Job的資訊(包括函式、引數等等),然後執行這個Job。
啟動Worker程式也很簡單:
$ rq worker low high default
16:56:02 RQ worker 'rq:worker:s2.6443' started, version 0.8.1
16:56:02 Cleaning registries for queue: low
16:56:02 Cleaning registries for queue: high
16:56:02 Cleaning registries for queue: default
16:56:02
16:56:02 *** Listening on low, high, default...
後面的三個引數low、high、default,就是這個Worker將要執行哪些Queue裡面的Job,這個順序很重要,排在前面的Queue裡面的Job將優先被執行。
5. 一個完整的例子
jobs.py
[root@iZ2ze66bhrbxkc31nljgjnZ ~]# more jobs.py
import requests
import redis
from rq import Queue
import pymysql
def count_words(url):
return len(requests.get(url).text.split())
def recover_to_db(sql, dbinfo):
dbinfo['charset'] = 'utf8mb4'
dbinfo['autocommit'] = True
dbconn = pymysql.Connect(**dbinfo)
dbconn.autocommit(1)
cur = dbconn.cursor()
cur.execute(sql)
dbconn.close()
app.py
from jobs import count_words,recover_to_db
import requests
import redis
from rq import Queue
import time
def run():
redis_conn = redis.Redis()
q = Queue(connection=redis_conn)
for i in range(92,99):
j = q.enqueue(recover_to_db, 'insert into `tt`(`id`) VALUES (%d);' % i,{'host': '47.93.243.162', 'password': 'ESBecs00', 'port': 3306, 'user': 'root','db':'te
st'})
#j = q.enqueue(, '')
#print(j.result)
#time.sleep(3)
#print(j.result)
if __name__ == '__main__':
run()
啟動Worker:
$ rq worker
執行:
$ python app.py