প্রক্রিয়াধীন থাকা সারিগুলির কাজগুলির একটি তালিকা আমি কীভাবে পুনরুদ্ধার করতে পারি?
প্রক্রিয়াধীন থাকা সারিগুলির কাজগুলির একটি তালিকা আমি কীভাবে পুনরুদ্ধার করতে পারি?
উত্তর:
সম্পাদনা: সারি কার্যগুলির তালিকা পাওয়ার জন্য অন্যান্য উত্তরগুলি দেখুন।
আপনার এখানে নজর দেওয়া উচিত: সেলারি গাইড - কর্মীদের পরিদর্শন করা
মূলত এটি:
from celery.app.control import Inspect
# Inspect all nodes.
i = Inspect()
# Show the items that have an ETA or are scheduled for later processing
i.scheduled()
# Show tasks that are currently active.
i.active()
# Show tasks that have been claimed by workers
i.reserved()
আপনি যা চান তার উপর নির্ভর করে
i.reserved()
সারিবদ্ধ কাজের তালিকা পেতে ব্যবহার করুন ।
inspect(['celery@Flatty'])
। বিশাল গতির উন্নতি হয়েছে inspect()
।
আপনি যদি খরগোশ এমকিউ ব্যবহার করে থাকেন তবে এটি টার্মিনালে ব্যবহার করুন:
sudo rabbitmqctl list_queues
এটি মুলতুবি থাকা কাজের সংখ্যার সাথে সারির তালিকা মুদ্রণ করবে। উদাহরণ স্বরূপ:
Listing queues ...
0b27d8c59fba4974893ec22d478a7093 0
0e0a2da9828a48bc86fe993b210d984f 0
10@torob2.celery.pidbox 0
11926b79e30a4f0a9d95df61b6f402f7 0
15c036ad25884b82839495fb29bd6395 1
celerey_mail_worker@torob2.celery.pidbox 0
celery 166
celeryev.795ec5bb-a919-46a8-80c6-5d91d2fcf2aa 0
celeryev.faa4da32-a225-4f6c-be3b-d8814856d1b6 0
ডান কলামে সংখ্যাটি সারিতে কাজ করার সংখ্যা। উপরে, সেলারি সারিতে 166 টি টেন্ডিংয়ের কাজ রয়েছে।
grep -e "^celery\s" | cut -f2
বের করার জন্য পাইপ করতে পারেন 166
যদি আপনি পরে এই সংখ্যাটি প্রক্রিয়া করতে চান তবে পরিসংখ্যানের জন্য বলুন।
আপনি যদি অগ্রাধিকার প্রাপ্ত কাজগুলি ব্যবহার না করেন তবে আপনি যদি রেডিস ব্যবহার করছেন তবে এটি আসলে বেশ সহজ । কাজ গণনা করতে:
redis-cli -h HOST -p PORT -n DATABASE_NUMBER llen QUEUE_NAME
তবে, অগ্রাধিকার প্রাপ্ত কাজগুলি রেডিসে আলাদা কী ব্যবহার করে , তাই পুরো ছবিটি কিছুটা জটিল complicated সম্পূর্ণ চিত্রটি হ'ল আপনাকে কাজের প্রতিটি অগ্রাধিকারের জন্য পুনরায় জিজ্ঞাসা করতে হবে। পাইথনে (এবং ফ্লাওয়ার প্রকল্প থেকে) এটিকে দেখতে দেখতে:
PRIORITY_SEP = '\x06\x16'
DEFAULT_PRIORITY_STEPS = [0, 3, 6, 9]
def make_queue_name_for_pri(queue, pri):
"""Make a queue name for redis
Celery uses PRIORITY_SEP to separate different priorities of tasks into
different queues in Redis. Each queue-priority combination becomes a key in
redis with names like:
- batch1\x06\x163 <-- P3 queue named batch1
There's more information about this in Github, but it doesn't look like it
will change any time soon:
- https://github.com/celery/kombu/issues/422
In that ticket the code below, from the Flower project, is referenced:
- https://github.com/mher/flower/blob/master/flower/utils/broker.py#L135
:param queue: The name of the queue to make a name for.
:param pri: The priority to make a name with.
:return: A name for the queue-priority pair.
"""
if pri not in DEFAULT_PRIORITY_STEPS:
raise ValueError('Priority not in priority steps')
return '{0}{1}{2}'.format(*((queue, PRIORITY_SEP, pri) if pri else
(queue, '', '')))
def get_queue_length(queue_name='celery'):
"""Get the number of tasks in a celery queue.
:param queue_name: The name of the queue you want to inspect.
:return: the number of items in the queue.
"""
priority_names = [make_queue_name_for_pri(queue_name, pri) for pri in
DEFAULT_PRIORITY_STEPS]
r = redis.StrictRedis(
host=settings.REDIS_HOST,
port=settings.REDIS_PORT,
db=settings.REDIS_DATABASES['CELERY'],
)
return sum([r.llen(x) for x in priority_names])
আপনি যদি কোনও আসল কাজ পেতে চান তবে আপনি এর মতো কিছু ব্যবহার করতে পারেন:
redis-cli -h HOST -p PORT -n DATABASE_NUMBER lrange QUEUE_NAME 0 -1
সেখান থেকে আপনাকে প্রত্যাবর্তিত তালিকার ডিজিটালাইজ করতে হবে। আমার ক্ষেত্রে আমি এই জাতীয় কিছু দিয়ে এটি সম্পাদন করতে সক্ষম হয়েছি:
r = redis.StrictRedis(
host=settings.REDIS_HOST,
port=settings.REDIS_PORT,
db=settings.REDIS_DATABASES['CELERY'],
)
l = r.lrange('celery', 0, -1)
pickle.loads(base64.decodestring(json.loads(l[0])['body']))
কেবল সাবধান করে দিন যে ডিসরিয়ালাইজেশন কিছুটা সময় নিতে পারে এবং বিভিন্ন অগ্রাধিকারের সাথে কাজ করতে আপনাকে উপরের কমান্ডগুলি সামঞ্জস্য করতে হবে।
DATABASE_NUMBER
ডিফল্টরূপে ব্যবহৃত হয় 0
এবং QUEUE_NAME
হয় celery
, তাই redis-cli -n 0 llen celery
সারিযুক্ত বার্তাগুলির সংখ্যা ফিরে আসবে।
'{{{0}}}{1}{2}'
পরিবর্তে '{0}{1}{2}'
। তা ছাড়া, এটি পুরোপুরি কাজ করে!
ব্যাকএন্ড থেকে কাজগুলি পুনরুদ্ধার করতে, এটি ব্যবহার করুন
from amqplib import client_0_8 as amqp
conn = amqp.Connection(host="localhost:5672 ", userid="guest",
password="guest", virtual_host="/", insist=False)
chan = conn.channel()
name, jobs, consumers = chan.queue_declare(queue="queue_name", passive=True)
আপনি যদি ভার্চুয়াল পরিবেশে আপনার টার্মিনাল থেকে সরাসরি কমান্ডগুলি ব্যবহার করে বা সেলারিটির পুরো পথ ব্যবহার করে সিলারি + জ্যাঙ্গো সহজ উপায় ব্যবহার করছেন তবে :
$ celery inspect reserved
$ celery inspect active
$ celery inspect registered
$ celery inspect scheduled
এছাড়াও আপনি যদি সেলারি + র্যাবিট এমকিউ ব্যবহার করছেন তবে নীচের কমান্ডটি ব্যবহার করে আপনি সারিগুলির তালিকাটি পরীক্ষা করতে পারেন :
আরও তথ্য : https://linux.die.net/man/1/rabbitmqctl
$ sudo rabbitmqctl list_queues
celery -A my_proj inspect reserved
জিসন সিরিয়ালাইজেশন সহ রেডিসের জন্য একটি অনুলিপি-পেস্ট সমাধান:
def get_celery_queue_items(queue_name):
import base64
import json
# Get a configured instance of a celery app:
from yourproject.celery import app as celery_app
with celery_app.pool.acquire(block=True) as conn:
tasks = conn.default_channel.client.lrange(queue_name, 0, -1)
decoded_tasks = []
for task in tasks:
j = json.loads(task)
body = json.loads(base64.b64decode(j['body']))
decoded_tasks.append(body)
return decoded_tasks
এটি জ্যাঙ্গোর সাথে কাজ করে। শুধু পরিবর্তন করতে ভুলবেন না yourproject.celery
।
body =
লাইনটি এতে পরিবর্তন করতে পারেন body = pickle.loads(base64.b64decode(j['body']))
।
সেলারি পরিদর্শন মডিউলটি কেবল শ্রমিক দৃষ্টিকোণ থেকে কার্যগুলি সম্পর্কে সচেতন বলে মনে হয়। আপনি যদি কাতারে থাকা বার্তাগুলি দেখতে চান (তবে এখনও শ্রমিকরা টানতে পারেন) আমি পাইরবিট ব্যবহার করার পরামর্শ দিচ্ছি , যা সারি থেকে সমস্ত ধরণের তথ্য পুনরুদ্ধার করতে রাবিটম্যাক এইচপি এপিআইয়ের সাথে ইন্টারফেস করতে পারে।
একটি উদাহরণ এখানে পাওয়া যেতে পারে: সিলারি (রেবিটএমকিউ, জাঙ্গো) দিয়ে সারির দৈর্ঘ্য পুনরুদ্ধার করুন
আমি মনে করি যে কাজগুলির জন্য অপেক্ষা করা হচ্ছে তার একমাত্র উপায় হ'ল আপনি যে কাজ শুরু করেছেন তার একটি তালিকা রাখা এবং কাজটি শুরু হওয়ার সাথে সাথে তালিকাগুলি থেকে নিজেকে সরিয়ে দেওয়া।
খরগোশমেক্টিটেল এবং list_queues এর সাহায্যে আপনি কত টাস্ক অপেক্ষা করছেন তার একটি ওভারভিউ পেতে পারেন, তবে নিজেই এই কাজগুলি নয়: http://www.rabbitmq.com/man/rabbitmqctl.1.man.html
আপনি যা চান তা যদি কাজটি প্রক্রিয়াজাতকরণের অন্তর্ভুক্ত থাকে তবে এখনও শেষ না হয়, আপনি আপনার কার্যগুলির একটি তালিকা রাখতে পারেন এবং তাদের অবস্থা পরীক্ষা করতে পারেন:
from tasks import add
result = add.delay(4, 4)
result.ready() # True if finished
অথবা আপনি সেলারি ফলাফলগুলি CELERY museT_BACKEND এর সাথে সঞ্চয় করতে দিন এবং আপনার কোন কাজ সেখানে নেই তা পরীক্ষা করুন।
এটি আমার আবেদনে আমার পক্ষে কাজ করেছে:
def get_celery_queue_active_jobs(queue_name):
connection = <CELERY_APP_INSTANCE>.connection()
try:
channel = connection.channel()
name, jobs, consumers = channel.queue_declare(queue=queue_name, passive=True)
active_jobs = []
def dump_message(message):
active_jobs.append(message.properties['application_headers']['task'])
channel.basic_consume(queue=queue_name, callback=dump_message)
for job in range(jobs):
connection.drain_events()
return active_jobs
finally:
connection.close()
active_jobs
সারিগুলির কার্যগুলির সাথে মিলিত স্ট্রিংগুলির একটি তালিকা হবে।
আপনার নিজের সাথে CELERY_APP_INSTANCE স্যুপ আউট করতে ভুলবেন না।
উত্তরটি এখানে উত্তর দিয়ে আমাকে সঠিক দিকে নির্দেশ করার জন্য @ আশিষকে ধন্যবাদ: https://stackoverflow.com/a/19465670/9843399
jobs
সবসময় শূন্য ... কোন ধারণা?
আমি যতদূর জানি সেলারি কাতারে অপেক্ষা করা কাজগুলি পরীক্ষা করার জন্য এপিআই দেয় না। এটি ব্রোকার-নির্দিষ্ট। যদি আপনি উদাহরণস্বরূপ রেডিসকে ব্রোকার হিসাবে ব্যবহার করেন, তবে celery
(ডিফল্ট) কাতারে অপেক্ষা করা কার্যগুলি পরীক্ষা করা এতটা সহজ:
celery
তালিকাবদ্ধ করুন (উদাহরণের জন্য LRANGE কমান্ড)মনে রাখবেন যে এগুলি উপলভ্য কর্মীদের দ্বারা অপেক্ষা করা কাজগুলি। আপনার ক্লাস্টারে কিছু কাজ চলতে পারে - সেগুলি ইতিমধ্যে বাছাই করা হওয়ায় তারা এই তালিকায় থাকবে না।
আমি উপসংহারে এসে পৌঁছেছি যে একটি সারিতে চাকরির সংখ্যা পাওয়ার সর্বোত্তম উপায়টি rabbitmqctl
এখানে বেশ কয়েকবার প্রস্তাবিত হিসাবে ব্যবহার করা। যে কোনও নির্বাচিত ব্যবহারকারীর সাথে কমান্ডটি চালানোর অনুমতি দেওয়ার জন্য sudo
আমি এখানে নির্দেশাবলী অনুসরণ করেছি (কমান্ডের আগে সুডো টাইপ করতে আমার আপত্তি নেই বলে আমি প্রোফাইল অংশটি সম্পাদনা এড়িয়ে গিয়েছি))
আমি জামেস্ক grep
এবং স্নিপেটও ধরেছিলাম এবং cut
এটিকে সাবপ্রসেস কলগুলিতে গুটিয়ে রেখেছি।
from subprocess import Popen, PIPE
p1 = Popen(["sudo", "rabbitmqctl", "list_queues", "-p", "[name of your virtula host"], stdout=PIPE)
p2 = Popen(["grep", "-e", "^celery\s"], stdin=p1.stdout, stdout=PIPE)
p3 = Popen(["cut", "-f2"], stdin=p2.stdout, stdout=PIPE)
p1.stdout.close()
p2.stdout.close()
print("number of jobs on queue: %i" % int(p3.communicate()[0]))
আপনি যদি কার্যগুলির কোডটি নিয়ন্ত্রণ করেন তবে আপনি কোনও কাজকে প্রথমবারের মতো সঞ্চালনের সময় তুচ্ছ পুনরায় চেষ্টা করার পরে তদন্ত করে সমস্যাটি ঘিরে কাজ করতে পারেন inspect().reserved()
। পুনরায় চেষ্টা ফলাফলের ব্যাকএন্ডের সাথে কাজটি নিবন্ধভুক্ত করে এবং সেলারি এটি দেখতে পারে can টাস্কটি অবশ্যই প্রথম প্যারামিটার হিসাবে গ্রহণ করতে হবে self
বা context
যাতে আমরা পুনরায় চেষ্টা গণনা করতে পারি।
@task(bind=True)
def mytask(self):
if self.request.retries == 0:
raise self.retry(exc=MyTrivialError(), countdown=1)
...
এই সমাধানটি ব্রোকার অগ্নিস্টিক, অর্থাৎ। আপনি টাস্কগুলি সংরক্ষণ করার জন্য রাবিট এমকিউ বা রেডিস ব্যবহার করছেন কিনা তা নিয়ে আপনাকে চিন্তা করার দরকার নেই।
সম্পাদনা: পরীক্ষার পরে আমি এটি কেবল একটি আংশিক সমাধান হিসাবে খুঁজে পেয়েছি। সংরক্ষিত আকারটি কর্মীর জন্য প্রিফেচ সেটিংয়ের মধ্যে সীমাবদ্ধ।
সহ subprocess.run
:
import subprocess
import re
active_process_txt = subprocess.run(['celery', '-A', 'my_proj', 'inspect', 'active'],
stdout=subprocess.PIPE).stdout.decode('utf-8')
return len(re.findall(r'worker_pid', active_process_txt))
my_proj
সঙ্গে পরিবর্তন করতে সাবধান হনyour_proj