সেলারিতে একটি কাতারে কাজের তালিকা পুনরুদ্ধার করুন


147

প্রক্রিয়াধীন থাকা সারিগুলির কাজগুলির একটি তালিকা আমি কীভাবে পুনরুদ্ধার করতে পারি?


1
রাবিট এমকিউ, তবে আমি পাইথনের ভিতরে এই তালিকাটি পুনরুদ্ধার করতে চাই।
bradley.ayers

উত্তর:


174

সম্পাদনা: সারি কার্যগুলির তালিকা পাওয়ার জন্য অন্যান্য উত্তরগুলি দেখুন।

আপনার এখানে নজর দেওয়া উচিত: সেলারি গাইড - কর্মীদের পরিদর্শন করা

মূলত এটি:

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()

আপনি যা চান তার উপর নির্ভর করে


9
আমি চেষ্টা করেছিলাম, তবে এটি সত্যই ধীর (1 সেকেন্ডের মতো)। অগ্রগতি পর্যবেক্ষণ করতে আমি টর্নেডো অ্যাপে এটি সিনক্রোনালিভাবে ব্যবহার করছি, তাই এটি দ্রুত হওয়া দরকার।
জুলিয়েনআর

41
এটি এখনও সারিবদ্ধ হওয়ার কাজগুলির তালিকাকে ফিরিয়ে দেবে না।
এড জে

9
i.reserved()সারিবদ্ধ কাজের তালিকা পেতে ব্যবহার করুন ।
কলা

4
কেউ কি অনুভব করেছেন যে i.re محفوظ () এর সক্রিয় কাজের সঠিক তালিকা থাকবে না? আমার কাজগুলি চলছে যা তালিকায় প্রদর্শিত হবে না। আমি জ্যাঙ্গো-সেলারিতে আছি == 3.1.10
সেপম্যান

6
যখন কর্মী উল্লেখ আমি আর্গুমেন্ট হিসাবে একটি তালিকা ব্যবহার করতে ছিল: inspect(['celery@Flatty'])। বিশাল গতির উন্নতি হয়েছে inspect()
অ্যাডভারসাস

42

আপনি যদি খরগোশ এমকিউ ব্যবহার করে থাকেন তবে এটি টার্মিনালে ব্যবহার করুন:

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 টি টেন্ডিংয়ের কাজ রয়েছে।


1
আমার সাথে সুডোর সুবিধাগুলি থাকাকালীন আমি এটির সাথে পরিচিত, তবে আমি চাই একটি অনিবদ্ধ, সিস্টেম ব্যবহারকারী চেক করতে সক্ষম হতে - কোনও পরামর্শ?
ঋষি

এছাড়াও আপনি এটি grep -e "^celery\s" | cut -f2বের করার জন্য পাইপ করতে পারেন 166যদি আপনি পরে এই সংখ্যাটি প্রক্রিয়া করতে চান তবে পরিসংখ্যানের জন্য বলুন।
জামেস্ক

21

আপনি যদি অগ্রাধিকার প্রাপ্ত কাজগুলি ব্যবহার না করেন তবে আপনি যদি রেডিস ব্যবহার করছেন তবে এটি আসলে বেশ সহজ । কাজ গণনা করতে:

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']))

কেবল সাবধান করে দিন যে ডিসরিয়ালাইজেশন কিছুটা সময় নিতে পারে এবং বিভিন্ন অগ্রাধিকারের সাথে কাজ করতে আপনাকে উপরের কমান্ডগুলি সামঞ্জস্য করতে হবে।


উত্পাদনে এটি ব্যবহার করার পরে, আমি শিখেছি সেলারি ডিজাইনের কারণে আপনি অগ্রাধিকার প্রাপ্ত কাজগুলি ব্যবহার করেন তবে এটি ব্যর্থ হয়
mlissner

1
অগ্রাধিকার প্রাপ্ত কাজগুলি হ্যান্ডেল করার জন্য আমি উপরেরটি আপডেট করেছি। অগ্রগতি!
mlissner

1
কেবল জিনিসগুলি বানান করতে, DATABASE_NUMBERডিফল্টরূপে ব্যবহৃত হয় 0এবং QUEUE_NAMEহয় celery, তাই redis-cli -n 0 llen celeryসারিযুক্ত বার্তাগুলির সংখ্যা ফিরে আসবে।
ভিনিত বানসাল

আমার সেলারিগুলির জন্য, কাতারের নামটি '{{{0}}}{1}{2}'পরিবর্তে '{0}{1}{2}'। তা ছাড়া, এটি পুরোপুরি কাজ করে!
জুলু

12

ব্যাকএন্ড থেকে কাজগুলি পুনরুদ্ধার করতে, এটি ব্যবহার করুন

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)

2
তবে 'চাকরিগুলি' কেবল সারিতে বেশ কয়েকটি সংখ্যক কাজ দেয়
বিটনিক

সম্পর্কিত উত্তরের জন্য stackoverflow.com/a/57807913/9843399 দেখুন যা আপনাকে কার্যগুলির নাম দেয়।
কালেব সিরিং

10

আপনি যদি ভার্চুয়াল পরিবেশে আপনার টার্মিনাল থেকে সরাসরি কমান্ডগুলি ব্যবহার করে বা সেলারিটির পুরো পথ ব্যবহার করে সিলারি + জ্যাঙ্গো সহজ উপায় ব্যবহার করছেন তবে :

ডক : http://docs.celeryproject.org/en/latest/userguide/workers.html?hightlight=revoke#inspecting- ওয়ার্কার্স

$ celery inspect reserved
$ celery inspect active
$ celery inspect registered
$ celery inspect scheduled

এছাড়াও আপনি যদি সেলারি + র‌্যাবিট এমকিউ ব্যবহার করছেন তবে নীচের কমান্ডটি ব্যবহার করে আপনি সারিগুলির তালিকাটি পরীক্ষা করতে পারেন :

আরও তথ্য : https://linux.die.net/man/1/rabbitmqctl

$ sudo rabbitmqctl list_queues

4
আপনার যদি একটি সংজ্ঞায়িত প্রকল্প থাকে তবে আপনি ব্যবহার করতে পারেনcelery -A my_proj inspect reserved
সাশাবলৌদগুলি

6

জিসন সিরিয়ালাইজেশন সহ রেডিসের জন্য একটি অনুলিপি-পেস্ট সমাধান:

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


1
আপনি যদি আচার সিরিয়ালাইজারটি ব্যবহার করেন তবে আপনি body =লাইনটি এতে পরিবর্তন করতে পারেন body = pickle.loads(base64.b64decode(j['body']))
জিম হুনজিকার

4

সেলারি পরিদর্শন মডিউলটি কেবল শ্রমিক দৃষ্টিকোণ থেকে কার্যগুলি সম্পর্কে সচেতন বলে মনে হয়। আপনি যদি কাতারে থাকা বার্তাগুলি দেখতে চান (তবে এখনও শ্রমিকরা টানতে পারেন) আমি পাইরবিট ব্যবহার করার পরামর্শ দিচ্ছি , যা সারি থেকে সমস্ত ধরণের তথ্য পুনরুদ্ধার করতে রাবিটম্যাক এইচপি এপিআইয়ের সাথে ইন্টারফেস করতে পারে।

একটি উদাহরণ এখানে পাওয়া যেতে পারে: সিলারি (রেবিটএমকিউ, জাঙ্গো) দিয়ে সারির দৈর্ঘ্য পুনরুদ্ধার করুন


3

আমি মনে করি যে কাজগুলির জন্য অপেক্ষা করা হচ্ছে তার একমাত্র উপায় হ'ল আপনি যে কাজ শুরু করেছেন তার একটি তালিকা রাখা এবং কাজটি শুরু হওয়ার সাথে সাথে তালিকাগুলি থেকে নিজেকে সরিয়ে দেওয়া।

খরগোশমেক্টিটেল এবং 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 এর সাথে সঞ্চয় করতে দিন এবং আপনার কোন কাজ সেখানে নেই তা পরীক্ষা করুন।


3

এটি আমার আবেদনে আমার পক্ষে কাজ করেছে:

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সবসময় শূন্য ... কোন ধারণা?
ডেভনকোড

@ ডেভনকোড আমি মনে করি না যে আমার পক্ষে সহায়কভাবে প্রতিক্রিয়া জানাতে যথেষ্ট তথ্য রয়েছে। আপনি আপনার নিজের প্রশ্ন খুলতে পারে। আমি মনে করি না যে এটি অজানাতে তথ্য পুনরুদ্ধার করতে চান তা উল্লেখ করলে এটি এটির একটি সদৃশ হবে। আমি স্ট্যাকওভারফ্লো.com / a / 19465670 / 9843399 এ ফিরে যেতে চাই , যা আমি আমার উত্তরটির ভিত্তিতে ভিত্তি করেছিলাম এবং নিশ্চিত হয়েছি যে এটি প্রথম কাজ করে।
কালেব সিরিয়িং

@ ক্যালবায়ারিং এটি প্রথম পদ্ধতির যা আমাকে সত্যই সারিবদ্ধ কাজগুলি দেখায়। খুব সুন্দর. আমার জন্য একমাত্র সমস্যা হ'ল তালিকা সংযোজনটি কাজ করছে বলে মনে হয় না। কলব্যাক ফাংশনটি কীভাবে তালিকায় লিখতে পারি তার কোনও ধারণাগুলি?
ভারলার 14

@ ভাররোর আমি দুঃখিত, কেউ আমার উত্তরে একটি অনুপযুক্ত সম্পাদনা করেছেন। আসল উত্তরের জন্য আপনি সম্পাদনা ইতিহাসে সন্ধান করতে পারেন যা সম্ভবত আপনার পক্ষে কাজ করবে। আমি এই ঠিক করার উপর কাজ করছি। (সম্পাদনা: আমি সবেমাত্র প্রবেশ করলাম এবং সম্পাদনাটি প্রত্যাখাত করেছিলাম, যার স্পষ্ট পাইথন ত্রুটি ছিল this এটি আপনার সমস্যার সমাধান করেছে কিনা তা আমাকে জানতে দিন))
কালেব সিরিং

@ কালেবসিরিং আমি এখন আপনার কোডটি ক্লাসে ব্যবহার করেছি, ক্লাস অ্যাট্রিবিউট হিসাবে কাজ করে তালিকা তৈরি করে!
ভার্লোর

2

আমি যতদূর জানি সেলারি কাতারে অপেক্ষা করা কাজগুলি পরীক্ষা করার জন্য এপিআই দেয় না। এটি ব্রোকার-নির্দিষ্ট। যদি আপনি উদাহরণস্বরূপ রেডিসকে ব্রোকার হিসাবে ব্যবহার করেন, তবে celery(ডিফল্ট) কাতারে অপেক্ষা করা কার্যগুলি পরীক্ষা করা এতটা সহজ:

  1. ব্রোকার ডাটাবেসে কানেক্ট করুন
  2. তালিকায় আইটেমগুলি celeryতালিকাবদ্ধ করুন (উদাহরণের জন্য LRANGE কমান্ড)

মনে রাখবেন যে এগুলি উপলভ্য কর্মীদের দ্বারা অপেক্ষা করা কাজগুলি। আপনার ক্লাস্টারে কিছু কাজ চলতে পারে - সেগুলি ইতিমধ্যে বাছাই করা হওয়ায় তারা এই তালিকায় থাকবে না।


1

আমি উপসংহারে এসে পৌঁছেছি যে একটি সারিতে চাকরির সংখ্যা পাওয়ার সর্বোত্তম উপায়টি 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]))

1
from celery.task.control import inspect
def key_in_list(k, l):
    return bool([True for i in l if k in i.values()])

def check_task(task_id):
    task_value_dict = inspect().active().values()
    for task_list in task_value_dict:
        if self.key_in_list(task_id, task_list):
             return True
    return False

0

আপনি যদি কার্যগুলির কোডটি নিয়ন্ত্রণ করেন তবে আপনি কোনও কাজকে প্রথমবারের মতো সঞ্চালনের সময় তুচ্ছ পুনরায় চেষ্টা করার পরে তদন্ত করে সমস্যাটি ঘিরে কাজ করতে পারেন inspect().reserved()। পুনরায় চেষ্টা ফলাফলের ব্যাকএন্ডের সাথে কাজটি নিবন্ধভুক্ত করে এবং সেলারি এটি দেখতে পারে can টাস্কটি অবশ্যই প্রথম প্যারামিটার হিসাবে গ্রহণ করতে হবে selfবা contextযাতে আমরা পুনরায় চেষ্টা গণনা করতে পারি।

@task(bind=True)
def mytask(self):
    if self.request.retries == 0:
        raise self.retry(exc=MyTrivialError(), countdown=1)
    ...

এই সমাধানটি ব্রোকার অগ্নিস্টিক, অর্থাৎ। আপনি টাস্কগুলি সংরক্ষণ করার জন্য রাবিট এমকিউ বা রেডিস ব্যবহার করছেন কিনা তা নিয়ে আপনাকে চিন্তা করার দরকার নেই।

সম্পাদনা: পরীক্ষার পরে আমি এটি কেবল একটি আংশিক সমাধান হিসাবে খুঁজে পেয়েছি। সংরক্ষিত আকারটি কর্মীর জন্য প্রিফেচ সেটিংয়ের মধ্যে সীমাবদ্ধ।


0

সহ 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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.