{"id":372442,"date":"2024-05-21T05:12:21","date_gmt":"2024-05-21T05:12:21","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=372442"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-05-21T05:12:21","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=372442","title":{"rendered":"<span>\u041c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 Celery<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/c70\/ae1\/351\/c70ae135171f7d05c0ef97e09cfbfe34.jpeg\" width=\"2048\" height=\"1153\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c70\/ae1\/351\/c70ae135171f7d05c0ef97e09cfbfe34.jpeg\" data-blurred=\"true\"\/><\/figure>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u043f\u043e\u043a\u0440\u044b\u0442\u0438\u044e \u043c\u0435\u0442\u0440\u0438\u043a\u0430\u043c\u0438 Celery: \u043e\u043d \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043b\u0443\u0448\u0430\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438\u0437 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u044d\u0442\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043c\u0435\u0442\u0440\u0438\u043a, \u0430 \u0444\u043e\u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043e\u0442\u0434\u0430\u0451\u0442 \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0441\u043a\u0440\u0430\u043f\u0435\u0440\u0443. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u0438\u0445 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b, \u043e\u0442\u043a\u0443\u0434\u0430 \u0438 \u043a\u0430\u043a \u0438\u0445 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c. \u0422\u0430\u043a\u0436\u0435 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043f\u0440\u043e \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0443\u0434\u0430\u043b\u0451\u043d\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f (remote control), \u043a\u0430\u043a\u0438\u0435 \u0443 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438 \u043a\u0430\u043a \u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f. \u041e\u0431\u0441\u0443\u0434\u0438\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u0447\u0435\u043c \u043e\u043d\u0438 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f, \u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u0432\u0430\u043c, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043e\u0434\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u0451. <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/567\/c5e\/290\/567c5e2904d6ebc2780fca3e004c4344.jpg\" width=\"1931\" height=\"1005\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/567\/c5e\/290\/567c5e2904d6ebc2780fca3e004c4344.jpg\" data-blurred=\"true\"\/><\/figure>\n<h2>\u0421\u043e\u0431\u044b\u0442\u0438\u044f Celery<\/h2>\n<p>\u0423 celery \u0435\u0441\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0433\u0438\u0431\u043a\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043d\u0430 \u0434\u0432\u0435 \u0433\u0440\u0443\u043f\u043f\u044b: <code>task<\/code> \u0438 <code>worker<\/code>.  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u0445. <\/p>\n<h3>\u0413\u0440\u0443\u043f\u043f\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 task<\/h3>\n<ul>\n<li>\n<p><code>task-sent<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 (producer), \u043a\u043e\u0433\u0434\u0430 task \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d \u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <a href=\"https:\/\/docs.celeryq.dev\/en\/v5.3.6\/userguide\/configuration.html#task-send-sent-event\"><strong>task_send_sent_event<\/strong><\/a>.<\/p>\n<\/li>\n<li>\n<p><code>task-received<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 worker \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0443.<\/p>\n<\/li>\n<li>\n<p><code>task-started<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a worker \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442 \u0437\u0430\u0434\u0430\u0447\u0443.<\/p>\n<\/li>\n<li>\n<p><code>task-succeeded<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e. \u0412 \u044d\u0442\u043e\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0438  \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438 (\u0430\u0442\u0440\u0438\u0431\u0443\u0442 <code>runtime<\/code>). <\/p>\n<\/li>\n<li>\n<p><code>task-failed<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u043e\u0441\u044c \u043d\u0435\u0443\u0434\u0430\u0447\u0435\u0439.<\/p>\n<\/li>\n<li>\n<p><code>task-rejected<\/code>. \u0417\u0430\u0434\u0430\u0447\u0430 \u0431\u044b\u043b\u0430 \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u0430 worker-\u043e\u043c, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0434\u043b\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0432 dead letter queue.<\/p>\n<\/li>\n<li>\n<p><code>task-revoked<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0431\u044b\u043b\u0430 \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u0430. \u0417\u0434\u0435\u0441\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u043e\u0434\u043d\u0438\u043c \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u043c.<\/p>\n<\/li>\n<li>\n<p><code>task-retried<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0430\u0441\u044c \u043d\u0435\u0443\u0434\u0430\u0447\u0435\u0439, \u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c.<\/p>\n<\/li>\n<\/ul>\n<p><a class=\"anchor\" name=\"task_events_examples\" id=\"task_events_examples\"><\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0441\u043e\u0431\u044b\u0442\u0438\u0439<\/summary>\n<div class=\"spoiler__content\">\n<h4>task-sent<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"gen7460@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 7460,   \"clock\": 6,   \"uuid\": \"4e71454e-e0bf-477c-8abf-9559721de49d\",   \"root_id\": \"4e71454e-e0bf-477c-8abf-9559721de49d\",   \"parent_id\": null,   \"name\": \"tasks.foo\",   \"args\": \"()\",   \"kwargs\": \"{}\",   \"retries\": 0,   \"eta\": null,   \"expires\": null,   \"queue\": \"celery\",   \"exchange\": \"\",   \"routing_key\": \"celery\",   \"timestamp\": 1712401950.239082,   \"type\": \"task-sent\",   \"local_received\": 1712401950.245164 } <\/code><\/pre>\n<h4>task-received<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 7226,   \"clock\": 6,   \"uuid\": \"4e71454e-e0bf-477c-8abf-9559721de49d\",   \"name\": \"tasks.foo\",   \"args\": \"()\",   \"kwargs\": \"{}\",   \"root_id\": \"4e71454e-e0bf-477c-8abf-9559721de49d\",   \"parent_id\": null,   \"retries\": 0,   \"eta\": null,   \"expires\": null,   \"timestamp\": 1712401950.2415,   \"type\": \"task-received\",   \"local_received\": 1712401950.244245 } <\/code><\/pre>\n<h4>task-started<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 7226,   \"clock\": 7,   \"uuid\": \"4e71454e-e0bf-477c-8abf-9559721de49d\",   \"timestamp\": 1712401950.243285,   \"type\": \"task-started\",   \"local_received\": 1712401950.24531 } <\/code><\/pre>\n<h4>task-succeeded<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 7226,   \"clock\": 8,   \"uuid\": \"4e71454e-e0bf-477c-8abf-9559721de49d\",   \"result\": \"None\",   \"runtime\": 0.0063114170043263584,   \"timestamp\": 1712401950.2501838,   \"type\": \"task-succeeded\",   \"local_received\": 1712401950.2526982 } <\/code><\/pre>\n<h4>task-failed<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 8704,   \"clock\": 3,   \"uuid\": \"3ca9b52f-3a6b-4780-bf51-24bdc92a1076\",   \"exception\": \"RuntimeError(\\\"Can\\\"t process task\\\")\",   \"traceback\": \"Traceback (most recent call last):\\n  File \\\"\/Users\/aszubarev\/Library\/Caches\/pypoetry\/virtualenvs\/celery-exporter-ISWk3u3R-py3.10\/lib\/python3.10\/site-packages\/celery\/app\/trace.py\\\", line 477, in trace_task\\n    R = retval = fun(*args, **kwargs)\\n  File \\\"\/Users\/aszubarev\/Library\/Caches\/pypoetry\/virtualenvs\/celery-exporter-ISWk3u3R-py3.10\/lib\/python3.10\/site-packages\/celery\/app\/trace.py\\\", line 760, in __protected_call__\\n    return self.run(*args, **kwargs)\\n  File \\\"\/Users\/aszubarev\/projects\/aszubarev\/celery-exporter\/examples\/tasks.py\\\", line 20, in test_failed\\n    raise RuntimeError(\\\"Can\\\"t process task\\\")\\nRuntimeError: Can\\\"t process task\\n\",   \"timestamp\": 1712402513.966636,   \"type\": \"task-failed\",   \"local_received\": 1712402513.9687 } <\/code><\/pre>\n<h4>task-rejected<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 10821,   \"clock\": 13,   \"uuid\": \"5be96332-3f69-4b59-8590-b6ecce54ffaf\",   \"requeue\": false,   \"timestamp\": 1712403556.524642,   \"type\": \"task-rejected\",   \"local_received\": 1712403556.527313 } <\/code><\/pre>\n<h4>task-revoked<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 14394,   \"clock\": 30,   \"uuid\": \"6d2f6d38-7378-461f-8e25-1cfc4aceb307\",   \"terminated\": false,   \"signum\": null,   \"expired\": false,   \"timestamp\": 1712405361.334489,   \"type\": \"task-revoked\",   \"local_received\": 1712405362.687277 } <\/code><\/pre>\n<h4>task-retried<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 13657,   \"clock\": 12,   \"uuid\": \"904dc2f6-6aa7-49e0-acb2-7fe241563be6\",   \"exception\": \"RuntimeError(\\\"Can\\\"t process task\\\")\",   \"traceback\": \"Traceback (most recent call last):\\n  File \\\"\/Users\/aszubarev\/Library\/Caches\/pypoetry\/virtualenvs\/celery-exporter-ISWk3u3R-py3.10\/lib\/python3.10\/site-packages\/celery\/app\/autoretry.py\\\", line 38, in run\\n    return task._orig_run(*args, **kwargs)\\n  File \\\"\/Users\/aszubarev\/projects\/aszubarev\/celery-exporter\/examples\/tasks.py\\\", line 36, in test_retried\\n    raise RuntimeError(\\\"Can\\\"t process task\\\")\\nRuntimeError: Can\\\"t process task\\n\\nDuring handling of the above exception, another exception occurred:\\n\\nTraceback (most recent call last):\\n  File \\\"\/Users\/aszubarev\/Library\/Caches\/pypoetry\/virtualenvs\/celery-exporter-ISWk3u3R-py3.10\/lib\/python3.10\/site-packages\/celery\/app\/trace.py\\\", line 477, in trace_task\\n    R = retval = fun(*args, **kwargs)\\n  File \\\"\/Users\/aszubarev\/Library\/Caches\/pypoetry\/virtualenvs\/celery-exporter-ISWk3u3R-py3.10\/lib\/python3.10\/site-packages\/celery\/app\/trace.py\\\", line 760, in __protected_call__\\n    return self.run(*args, **kwargs)\\n  File \\\"\/Users\/aszubarev\/Library\/Caches\/pypoetry\/virtualenvs\/celery-exporter-ISWk3u3R-py3.10\/lib\/python3.10\/site-packages\/celery\/app\/autoretry.py\\\", line 60, in run\\n    ret = task.retry(exc=exc, **retry_kwargs)\\n  File \\\"\/Users\/aszubarev\/Library\/Caches\/pypoetry\/virtualenvs\/celery-exporter-ISWk3u3R-py3.10\/lib\/python3.10\/site-packages\/celery\/app\/task.py\\\", line 757, in retry\\n    raise ret\\ncelery.exceptions.Retry: Retry in 5s: RuntimeError(\\\"Can\\\"t process task\\\")\\n\",   \"timestamp\": 1712404792.764382,   \"type\": \"task-retried\",   \"local_received\": 1712404792.767023 } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u0413\u0440\u0443\u043f\u043f\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 worker<\/h3>\n<ul>\n<li>\n<p><code>worker-online<\/code><strong>.<\/strong> Worker \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043b\u0441\u044f \u043a \u0431\u0440\u043e\u043a\u0435\u0440\u0443 \u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0441\u0435\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p><code>worker-offline<\/code>. Worker \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u043b\u0441\u044f \u043e\u0442 \u0431\u0440\u043e\u043a\u0435\u0440\u0430.<\/p>\n<\/li>\n<li>\n<p><code>worker-heartbeat<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u043c. <\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0441\u043e\u0431\u044b\u0442\u0438\u0439<\/summary>\n<div class=\"spoiler__content\">\n<h4>worker-online<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 21516,   \"clock\": 1,   \"freq\": 2.0,   \"active\": 0,   \"processed\": 0,   \"loadavg\": [     7.61,     7.72,     7.12   ],   \"sw_ident\": \"py-celery\",   \"sw_ver\": \"5.3.6\",   \"sw_sys\": \"Darwin\",   \"timestamp\": 1712408762.006613,   \"type\": \"worker-online\",   \"local_received\": 1712408762.01629 } <\/code><\/pre>\n<h4>worker-offline<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 21516,   \"clock\": 71,   \"freq\": 2.0,   \"active\": 0,   \"processed\": 0,   \"loadavg\": [     4.64,     6.81,     6.82   ],   \"sw_ident\": \"py-celery\",   \"sw_ver\": \"5.3.6\",   \"sw_sys\": \"Darwin\",   \"timestamp\": 1712408827.013207,   \"type\": \"worker-offline\",   \"local_received\": 1712408827.0157518 } <\/code><\/pre>\n<h3>worker-heartbeat<\/h3>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 21516,   \"clock\": 53,   \"freq\": 2.0,   \"active\": 10,   \"processed\": 80,   \"loadavg\": [     3.75,     4.21,     3.86   ],   \"sw_ident\": \"py-celery\",   \"sw_ver\": \"5.3.6\",   \"sw_sys\": \"Darwin\",   \"timestamp\": 1712407095.393169,   \"type\": \"worker-heartbeat\",   \"local_received\": 1712407095.3960378 } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u0441\u044f \u0441 \u043d\u0438\u043c\u0438 \u0432 <a href=\"https:\/\/docs.celeryq.dev\/en\/v5.3.6\/userguide\/monitoring.html#event-reference\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>. <\/p>\n<p>\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b <code>task<\/code> \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c, \u043d\u0443\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043e\u043f\u0446\u0438\u044e <a href=\"https:\/\/worker_send_task_events\"><strong>worker_send_task_events<\/strong><\/a>. \u041d\u043e \u044d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0441\u043e\u0437\u043d\u0430\u043d\u043d\u043e. \u0416\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c \u044d\u0442\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439. <\/p>\n<p>\u0421\u043e\u0431\u044b\u0442\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b <code>worker<\/code>, \u043d\u0430\u043f\u0440\u043e\u0442\u0438\u0432, \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u0430\u044f <a href=\"https:\/\/www.cloudamqp.com\/blog\/identify-and-protect-against-high-cpu-and-memory-usage.html#python-celery\">\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u044f<\/a> \u0434\u043b\u044f \u0441\u043d\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432\u00a0\u2014 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043e\u043f\u0446\u0438\u0439 <code>gossip<\/code>, <code>mingle<\/code> \u0438 <code>heartbeat<\/code>. \u0421\u0447\u0438\u0442\u0430\u044e \u044d\u0442\u0443 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u044e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439. \u041d\u043e \u043a\u043e\u0433\u0434\u0430 <code>heartbeat<\/code> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c, \u0441\u043e\u0432\u0435\u0442\u0443\u044e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043e\u043f\u0446\u0438\u044e <code>--heartbeat-interval<\/code> \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438. <\/p>\n<p><a class=\"anchor\" name=\"exchanges_and_queues\" id=\"exchanges_and_queues\"><\/a><\/p>\n<h2>Exchanges \u0438 Queues<\/h2>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f RabbitMQ \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0431\u0440\u043e\u043a\u0435\u0440\u0430, Celery \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0447\u0435\u0442\u044b\u0440\u0435 exchange. \u0418\u0445 \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0414\u0430\u043b\u0435\u0435 \u043f\u043e \u0441\u0442\u0430\u0442\u044c\u0435 \u0432\u0441\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0431\u0443\u0434\u0443\u0442 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 RabbitMQ. <\/p>\n<ul>\n<li>\n<p><code>celery<\/code>. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0437\u0430\u0434\u0430\u0447.<\/p>\n<\/li>\n<li>\n<p><code>celeryev<\/code>. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439.<\/p>\n<\/li>\n<li>\n<p><code>celery.pidbox<\/code>. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u043c\u0430\u043d\u0434 \u0432\u043e\u0440\u043a\u0435\u0440\u0430\u043c.<\/p>\n<\/li>\n<li>\n<p><code>reply.celery.pidbox<\/code>. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>Exchanges \u0438 Queues \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c8c\/fc7\/730\/c8cfc773004c7bd6643960676c1b3d5c.png\" width=\"1156\" height=\"960\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c8c\/fc7\/730\/c8cfc773004c7bd6643960676c1b3d5c.png\"\/><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f43\/9d0\/a51\/f439d0a51b129eb5b568a7391a6fe0d5.png\" width=\"2378\" height=\"738\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f43\/9d0\/a51\/f439d0a51b129eb5b568a7391a6fe0d5.png\"\/><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0437 <a href=\"https:\/\/docs.celeryq.dev\/en\/v5.3.6\/userguide\/monitoring.html#real-time-processing\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a> \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u044c <strong>celeryev.*<\/strong>, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u043f\u0430\u0434\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438\u0437 exchange <code>celeryev<\/code> \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u041e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u0441 \u0442\u0430\u043a\u0438\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 routing key <code>worker.#<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f gossip. <\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0430\u043d\u0435\u043b\u044c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d45\/d65\/8b6\/d45d658b6d5c6640fe3fcba2da170309.png\" width=\"1178\" height=\"1180\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d45\/d65\/8b6\/d45d658b6d5c6640fe3fcba2da170309.png\"\/><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/97b\/577\/c67\/97b577c679b1191a38d6b4f7e2586e83.png\" width=\"2662\" height=\"1160\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/97b\/577\/c67\/97b577c679b1191a38d6b4f7e2586e83.png\"\/><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u042d\u0442\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438:<\/p>\n<ul>\n<li>\n<p><code>auto-delete: true<\/code>. \u041e\u0447\u0435\u0440\u0435\u0434\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0434\u0430\u043b\u0438\u0442\u0441\u044f \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f. <\/p>\n<\/li>\n<li>\n<p><code>x-message-ttl: 5000<\/code>.<strong> <\/strong>\u0427\u0435\u0440\u0435\u0437 5 \u0441\u0435\u043a\u0443\u043d\u0434 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e \u0438 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044e.<\/p>\n<\/li>\n<li>\n<p><code>x-expires: 60000<\/code>. \u041e\u0447\u0435\u0440\u0435\u0434\u044c \u0443\u0434\u0430\u043b\u0438\u0442\u0441\u044f \u0441\u043f\u0443\u0441\u0442\u044f 60 \u0441\u0435\u043a\u0443\u043d\u0434 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f. <\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043e\u0431\u044b\u0442\u0438\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044e \u0431\u0435\u0437 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f <code>ack<\/code><strong> <\/strong>(\u00ab\u0432\u044b\u0441\u0442\u0440\u0435\u043b\u0438\u043b \u0438 \u0437\u0430\u0431\u044b\u043b\u00bb). \u042d\u0442\u043e \u0432\u0438\u0434\u043d\u043e \u043d\u0430 \u0433\u0440\u0430\u0444\u0438\u043a\u0435 \u0432 \u043f\u0430\u043d\u0435\u043b\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u043d\u0430 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0443 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044e. \u041d\u043e \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0440\u0438\u0441\u043a\u0438 \u043f\u043e\u0442\u0435\u0440\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u041d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u044d\u0442\u043e \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430. <\/p>\n<h2>\u0413\u043e\u0442\u043e\u0432\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f<\/h2>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0433\u043e\u0442\u043e\u0432\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 \u0432\u0438\u0434\u0435 <a href=\"https:\/\/flower.readthedocs.io\/en\/2.0\/\">Flower<\/a>. \u0423 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0432\u0435\u0441\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 <a href=\"https:\/\/flower.readthedocs.io\/en\/2.0\/prometheus-integration.html#available-metrics\">\u043d\u0430\u0431\u043e\u0440<\/a> \u043c\u0435\u0442\u0440\u0438\u043a. \u0415\u0441\u0442\u044c \u0441\u0432\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 Tornado, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043c\u0435\u0435\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e. \u041e\u043d \u0443\u043c\u0435\u0435\u0442 \u0434\u0430\u0436\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043f\u043e \u0437\u0430\u0434\u0430\u0447\u0430\u043c \u0432 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435. \u041e\u0442\u043b\u0438\u0447\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435. <\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u0431\u044b\u0432\u0430\u044e\u0442 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 Flower \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e. \u0418\u0437 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0433\u043e: \u043d\u0435\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u043e <code>exception<\/code> \u0432 \u043c\u0435\u0442\u0440\u0438\u043a\u0435 <code>flower_events_total<\/code>; \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0433\u0440\u0430\u0444\u0438\u043a \u043e\u0448\u0438\u0431\u043e\u043a \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443 \u0441 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u043e \u0442\u0438\u043f\u0443 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f. \u0420\u0430\u0437\u043d\u044b\u0435 \u0430\u0432\u0442\u043e\u0440\u044b \u043d\u0430 Github \u0440\u0435\u0448\u0430\u044e\u0442 \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u043f\u043e-\u0440\u0430\u0437\u043d\u043e\u043c\u0443. \u041d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0438\u0445 \u0432\u0441\u0435\u0445 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0442\u043e, \u0447\u0442\u043e \u0438\u043c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0432\u0432\u0438\u0434\u0443 \u0434\u0435\u0444\u0438\u0446\u0438\u0442\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445, \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0438\u0445 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u0438. \u0418 \u043c\u044b \u043d\u0435 \u0441\u0442\u0430\u043b\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c. <\/p>\n<p><a class=\"anchor\" name=\"projects_are_many_and_celery_is_single\" id=\"projects_are_many_and_celery_is_single\"><\/a><\/p>\n<h2>\u041f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043c\u043d\u043e\u0433\u043e, Celery \u00ab\u043e\u0434\u0438\u043d\u00bb<\/h2>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e, \u0447\u0442\u043e \u0432\u0430\u0448\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432. \u041d\u0430\u0437\u043e\u0432\u0451\u043c \u0438\u0445 <strong>serviceA<\/strong> \u0438 <strong>serviceB<\/strong>. \u0412 \u043a\u0430\u0436\u0434\u043e\u043c \u0438\u0437 \u043d\u0438\u0445 \u0432\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Celery \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u0434\u0430\u0447. \u0421 \u0443\u0447\u0451\u0442\u043e\u043c \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e <a href=\"#exchanges_and_queues\">\u0432\u044b\u0448\u0435<\/a> \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0434\u043d\u0438\u0445 \u0438 \u0442\u0435\u0445 \u0436\u0435 exchange \u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c\u0438. <\/p>\n<p>\u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f celery worker-\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c\u0438. <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/f60\/254\/db7\/f60254db71d832c426066518705f2e66.jpg\" width=\"1988\" height=\"758\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f60\/254\/db7\/f60254db71d832c426066518705f2e66.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441\u0432\u043e\u0439 <strong>vhost<\/strong> \u0432 <strong>RabbitMQ<\/strong>. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 Celery \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e. \u0415\u0441\u043b\u0438 \u043d\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438\u043b\u0438 \u0436\u0435\u043b\u0430\u043d\u0438\u044f \u0432\u044b\u0434\u0435\u043b\u044f\u0442\u044c vhost \u043f\u043e\u0434 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0430\u0431\u043e\u0440\u044b exchange \u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u043f\u043e\u0434 \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0441\u043e \u0441\u0432\u043e\u0438\u043c\u0438 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u043c\u0438, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u043c \u044d\u0442\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043e\u043f\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/docs.celeryq.dev\/en\/v5.3.6\/userguide\/configuration.html#task-default-exchange\">task_default_exchange<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.celeryq.dev\/en\/v5.3.6\/userguide\/configuration.html#task-default-queue\">task_default_queue<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.celeryq.dev\/en\/v5.3.6\/userguide\/configuration.html#event-exchange\">event_exchange<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.celeryq.dev\/en\/v5.3.6\/userguide\/configuration.html#event-queue-prefix\">event_queue_prefix<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.celeryq.dev\/en\/v5.3.6\/userguide\/configuration.html#control-exchange\">control_exchange<\/a><\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043d\u0438\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 exchange \u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c <strong>serviceA<\/strong>. <\/p>\n<pre><code class=\"python\">import os  from celery import Celery  BROKER_URL = os.environ.get('BROKER_URL', 'amqp:\/\/guest:guest@localhost:8672')  app = Celery(     broker=BROKER_URL,     task_send_sent_event=True,     worker_send_task_events=True,     worker_enable_remote_control=True,     task_default_exchange='service_a',     task_default_queue='service_a',     event_exchange='service_a.celeryev',     event_queue_prefix='service_a.celeryev',     control_exchange='service_a', )   if __name__ == '__main__':     app.start() <\/code><\/pre>\n<p><code>EventReceiver<\/code><strong> <\/strong>\u0438 remote control \u043f\u0440\u0438 \u0442\u0435\u0445 \u0436\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 Celery App \u0442\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0441 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u043c\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>Exchanges \u0438 Queues \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/835\/5ca\/801\/8355ca8010e571d46f1e5513ee2c7a27.png\" width=\"1184\" height=\"590\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/835\/5ca\/801\/8355ca8010e571d46f1e5513ee2c7a27.png\"\/><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5de\/523\/979\/5de523979d11796fa3c0d1b652ae0159.png\" width=\"2392\" height=\"734\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5de\/523\/979\/5de523979d11796fa3c0d1b652ae0159.png\"\/><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0451\u0440\u0430<\/h2>\n<p>\u0420\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 Flower. \u0417\u0430\u043f\u0443\u0441\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"bash\">celery -A tasks flower<\/code><\/pre>\n<p>\u0424\u0430\u0439\u043b <strong>tasks.py <\/strong>\u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 app Celery. \u0418 \u0442\u0443\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0432\u043e\u043f\u0440\u043e\u0441: \u0433\u0434\u0435 \u0438 \u043a\u0430\u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c Flower? \u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432. <\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c Flower \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u043e\u0442 \u0436\u0435 app, \u0447\u0442\u043e \u0438 \u0434\u043b\u044f \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432. \u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b: \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u0445 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b, \u0432\u0435\u0440\u0441\u0438\u044f Celery \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043c\u043e\u0436\u0435\u0442 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u043e\u0432\u0430\u0442\u044c \u0441 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 \u0434\u043b\u044f Flower, \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0451\u0440\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d \u043a \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u043c\u0443 \u0446\u0438\u043a\u043b\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. <\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u00a0\u2014 \u043e\u0442\u0434\u0435\u043b\u0438\u0442\u044c \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u043e\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041c\u043e\u0436\u043d\u043e \u0437\u0430\u0432\u0435\u0441\u0442\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u043f\u043e\u0434 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441\u043e \u0441\u0432\u043e\u0438\u043c\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c\u0438, \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u0438 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u043c \u0446\u0438\u043a\u043b\u043e\u043c. \u041d\u043e \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u043b\u0438\u0447\u0438\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u043e\u0434 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0441\u0435\u0440\u0432\u0438\u0441, \u0438 \u043d\u0430\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0440\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u0432 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0451\u0440\u0430 \u0441 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a. <\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0438\u0434\u0435\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0451\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434 \u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b, c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0435\u0442 \u0432\u043e Flower.<\/p>\n<h2>\u041c\u0435\u0442\u0440\u0438\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439<\/h2>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e \u0442\u0435\u043c \u0438\u043b\u0438 \u0438\u043d\u044b\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u0432\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f. \u0412\u0441\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/aszubarev\/celery-exporter\">\u0442\u0443\u0442<\/a>.<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c. \u0418\u0437 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0433\u043e: \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u0438 \u0432\u0441\u0435\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0433\u0440\u0443\u043f\u043f\u044b task, \u0433\u0438\u0441\u0442\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 gauge \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438 \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432. \u041d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433, \u043d\u0443\u0436\u043d\u043e \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u044f \u043c\u0435\u0442\u0440\u0438\u043a \u043c\u0435\u0436\u0434\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u0441\u0435\u043c \u043c\u0435\u0442\u0440\u0438\u043a\u0430\u043c \u043c\u0435\u0442\u043a\u0443 <code>service_name<\/code>. <\/p>\n<h3>\u041c\u0435\u0442\u0440\u0438\u043a\u0438 \u0433\u0440\u0443\u043f\u043f\u044b task<\/h3>\n<p>\u0421\u0447\u0451\u0442\u0447\u0438\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e-\u0440\u0430\u0437\u043d\u043e\u043c\u0443. \u041c\u043e\u0436\u043d\u043e \u0438\u0434\u0442\u0438 \u043f\u043e \u043f\u0443\u0442\u0438 Flower \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0441\u0447\u0451\u0442\u0447\u0438\u043a <code>flower_events_total<\/code> \u0440\u0430\u0437\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043a\u0430\u043c\u0438 <code>task<\/code>, <code>type<\/code> \u0438 <code>worker<\/code>. \u041d\u043e \u0440\u0430\u0437 \u0443\u0436 \u043c\u044b \u0437\u0434\u0435\u0441\u044c, \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443. \u0411\u0443\u0434\u0435\u043c \u0432\u0435\u0441\u0442\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f:<\/p>\n<ul>\n<li>\n<p><code>celery_task_sent_total<\/code><\/p>\n<\/li>\n<li>\n<p><code>celery_task_received_total<\/code><\/p>\n<\/li>\n<li>\n<p><code>celery_task_started_total<\/code><\/p>\n<\/li>\n<li>\n<p><code>celery_task_succeeded_total<\/code><\/p>\n<\/li>\n<li>\n<p><code>celery_task_failed_total<\/code><\/p>\n<\/li>\n<li>\n<p><code>celery_task_rejected_total<\/code><\/p>\n<\/li>\n<li>\n<p><code>celery_task_revoked_total<\/code><\/p>\n<\/li>\n<li>\n<p><code>celery_task_retried_total<\/code><\/p>\n<\/li>\n<\/ul>\n<p>\u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u0434\u043b\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u0437 \u043d\u0438\u0445 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043a\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u0430\u043a \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u043d\u0435\u0435, \u0434\u043b\u044f \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u0430 \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043c\u0435\u0442\u043a\u0443 <code>exception<\/code><em>\u00a0\u2014 <\/em>\u0442\u043e, \u0447\u0435\u0433\u043e \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u0432\u043e Flower. \u041e\u0434\u043d\u0430\u043a\u043e \u0443 Flower \u043d\u0430 \u044d\u0442\u043e \u0435\u0441\u0442\u044c \u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u044b. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u0435\u0442\u043a\u0430 <code>exception<\/code> \u0431\u044b\u043b\u0430 \u0431\u044b \u0443 \u0432\u0441\u0435\u0445 \u043c\u0435\u0442\u0440\u0438\u043a \u043f\u043e\u043c\u0438\u043c\u043e \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a. <\/p>\n<p>\u0421\u043e\u0431\u044b\u0442\u0438\u0435 <code>task-succeeded<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 <code>runtime<\/code>. \u041f\u043e \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e \u0431\u0443\u0434\u0435\u043c \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0433\u0438\u0441\u0442\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447 <code>celery_task_runtime_bucket<\/code>. \u0412\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 BUCKETS, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0441\u043b\u0438 \u0432 \u0432\u0430\u0448\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u0435 \u0435\u0441\u0442\u044c \u0434\u043e\u043b\u0433\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438.  <\/p>\n<p>\u0414\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043c\u0435\u0442\u0440\u0438\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043c\u0435\u0442\u0440\u0438\u043a\u0438 <code>_created<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>celery_exporter\/metrics.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">from celery_exporter.conf import settings from prometheus_client import CollectorRegistry, Counter, Gauge, Histogram, disable_created_metrics  if settings.PROMETHEUS_CLIENT_DISABLE_CREATED_METRICS:     disable_created_metrics()  BUCKETS = (                                                     # noqa: WPS317     .005, .01, .025, .05, .075, .1, .25, .5, .75, 1.0,          # noqa: WPS304     2.5, 5.0, 7.5, 10.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0,     50.0, 60.0, 70.0, 80.0, 90.0, 100.0, )   registry = CollectorRegistry(auto_describe=True)  events_state_counters = {     'task-sent': Counter(         'celery_task_sent',         'Sent when a task message is published.',         ['task', 'worker', 'service_name'],         registry=registry,     ),     'task-received': Counter(         'celery_task_received',         'Sent when the worker receives a task.',         ['task', 'worker', 'service_name'],         registry=registry,     ),     'task-started': Counter(         'celery_task_started',         'Sent just before the worker executes the task.',         ['task', 'worker', 'service_name'],         registry=registry,     ),     'task-succeeded': Counter(         'celery_task_succeeded',         'Sent if the task executed successfully.',         ['task', 'worker', 'service_name'],         registry=registry,     ),     'task-failed': Counter(         'celery_task_failed',         'Sent if the execution of the task failed.',         ['task', 'worker', 'exception', 'service_name'],         registry=registry,     ),     'task-rejected': Counter(         'celery_task_rejected',         'The task was rejected by the worker, possibly to be re-queued or moved to a dead letter queue.',         ['task', 'worker', 'service_name'],         registry=registry,     ),     'task-revoked': Counter(         'celery_task_revoked',         'Sent if the task has been revoked.',         ['task', 'worker', 'service_name'],         registry=registry,     ),     'task-retried': Counter(         'celery_task_retried',         'Sent if the task failed, but will be retried in the future.',         ['task', 'worker', 'service_name'],         registry=registry,     ), }  celery_task_runtime = Histogram(     'celery_task_runtime',     'Histogram of task runtime measurements.',     ['task', 'worker', 'service_name'],     registry=registry,     buckets=BUCKETS, )  ...<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u041c\u0435\u0442\u0440\u0438\u043a\u0438 \u0433\u0440\u0443\u043f\u043f\u044b worker<\/h3>\n<p>\u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0432\u043e\u0439 \u0430\u043d\u0430\u043b\u043e\u0433 \u043c\u0435\u0442\u0440\u0438\u043a Flower \u0441 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430:<\/p>\n<ul>\n<li>\n<p><code>celery_worker_up<\/code>. \u041f\u0440\u0438\u0437\u043d\u0430\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438 \u0432\u043e\u0440\u043a\u0435\u0440\u0430.<\/p>\n<\/li>\n<li>\n<p><code>celery_worker_tasks_active<\/code>. \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447.<\/p>\n<\/li>\n<\/ul>\n<p>\u041c\u0435\u0442\u0440\u0438\u043a\u0430 <code>celery_worker_up<\/code> \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u0438\u043f\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u0415\u0441\u043b\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <code>worker-online<\/code> \u0438\u043b\u0438 <code>worker-heartbeat<\/code>, \u0442\u043e \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 1. \u0415\u0441\u043b\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <code>worker-offline<\/code>, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f 0. <\/p>\n<p>\u041c\u0435\u0442\u0440\u0438\u043a\u0430 <code>celery_worker_tasks_active<\/code><strong> <\/strong>\u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <code>worker-heartbeat<\/code>. \u0412 \u043d\u0451\u043c \u0435\u0441\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 <code>active<\/code>. \u041a\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <code>worker-offline<\/code>, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f 0.  <\/p>\n<details class=\"spoiler\">\n<summary>celery_exporter\/metrics.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">...  celery_worker_up = Gauge(     'celery_worker_up',     'Indicates if a worker has recently sent a heartbeat.',     ['worker', 'service_name'],     registry=registry, ) celery_worker_tasks_active = Gauge(     'celery_worker_tasks_active',     'The number of tasks the worker is currently processing',     ['worker', 'service_name'],     registry=registry, )  ...<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>State \u0441\u043e\u0431\u044b\u0442\u0438\u0439<\/h2>\n<p>\u0414\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f <code>celery.events.state.State<\/code>. \u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u043b\u043e\u0432\u0430\u0440\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0437\u0430\u0434\u0430\u0447 \u0438 \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432. \u042d\u0442\u0438 \u0441\u043b\u043e\u0432\u0430\u0440\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f LRU-\u043a\u0435\u0448\u0435\u043c \u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438\u043c\u0435\u044e\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 10 \u0442\u044b\u0441. \u0434\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u044b <code>task<\/code> \u0438 5 \u0442\u044b\u0441. \u0434\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u044b <code>worker<\/code>. <\/p>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0435, \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0435\u0433\u043e \u0432 State. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0440\u0435\u0448\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 <a href=\"#task_events_examples\">\u043f\u0440\u0438\u043c\u0435\u0440<\/a> \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0433\u0440\u0443\u043f\u043f\u044b <code>task<\/code>, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445 <code>task-sent<\/code> \u0438 <code>task-received<\/code>. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u043c\u0435\u043d\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u0447\u0442\u043e\u0431\u044b \u0432 \u043a\u0435\u0448\u0435 \u0431\u044b\u043b \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>celery.events.state.Task<\/code>  c \u0443\u0436\u0435 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0437\u0430\u0434\u0430\u0447\u0438. <\/p>\n<p>\u0421\u043e\u0431\u044b\u0442\u0438\u044f <code>task-sent<\/code> \u0438 <code>task-received<\/code> \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u0439\u0442\u0438 \u0432 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 <code>task-sent<\/code> \u043f\u0440\u0438\u0434\u0451\u0442 \u043f\u043e\u0441\u043b\u0435 <code>task-received<\/code> \u044d\u0442\u043e \u0435\u0449\u0451 <strong>\u043d\u0435<\/strong> \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0441\u0442\u0430\u0442\u0443\u0441 \u0437\u0430\u0434\u0430\u0447\u0438 PENDING. <\/p>\n<details class=\"spoiler\">\n<summary>examples\/race_condition.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">from celery.events.state import State, Task  task_sent_event = {   \"hostname\": \"gen7460@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 7460,   \"clock\": 6,   \"uuid\": \"4e71454e-e0bf-477c-8abf-9559721de49d\",   \"root_id\": \"4e71454e-e0bf-477c-8abf-9559721de49d\",   \"parent_id\": None,   \"name\": \"tasks.foo\",   \"args\": \"()\",   \"kwargs\": \"{}\",   \"retries\": 0,   \"eta\": None,   \"expires\": None,   \"queue\": \"celery\",   \"exchange\": \"\",   \"routing_key\": \"celery\",   \"timestamp\": 1712401950.239082,   \"type\": \"task-sent\",   \"local_received\": 1712401950.245164 } task_received_event = {   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 7226,   \"clock\": 6,   \"uuid\": \"4e71454e-e0bf-477c-8abf-9559721de49d\",   \"name\": \"tasks.foo\",   \"args\": \"()\",   \"kwargs\": \"{}\",   \"root_id\": \"4e71454e-e0bf-477c-8abf-9559721de49d\",   \"parent_id\": None,   \"retries\": 0,   \"eta\": None,   \"expires\": None,   \"timestamp\": 1712401950.2415,   \"type\": \"task-received\",   \"local_received\": 1712401950.244245 }  state = State()  state.event(task_received_event) state.event(task_sent_event)  task: Task = state.tasks.get(\"4e71454e-e0bf-477c-8abf-9559721de49d\")  print(task.state)  # RECEIVED <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h2>\n<p>\u041f\u043e\u043b\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/aszubarev\/celery-exporter\">\u0442\u0443\u0442<\/a>. \u041f\u0440\u0438\u0432\u0435\u0434\u0443 \u043b\u0438\u0448\u044c \u0432\u044b\u0436\u0438\u043c\u043a\u0443, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u043e\u0442\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u0432\u0435\u0447\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u043a\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u0439. \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 <code>handlers<\/code>. \u0412 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u043b\u044f \u043e\u0442\u0434\u0430\u0447\u0438 \u043c\u0435\u0442\u0440\u0438\u043a, \u0443 prometheus_client \u0442\u0430\u043a\u043e\u0439 \u0435\u0441\u0442\u044c \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438. \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 <code>event<\/code>. \u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043d\u0430\u0448\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 <code>service_name<\/code>. \u041e\u0434\u043d\u0430\u043a\u043e Receiver \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u043f\u0440\u043e <code>service_name<\/code><strong>. <\/strong>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0451 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c partial.<\/p>\n<p>\u041f\u043e\u043c\u043d\u0438\u043c \u043f\u0440\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 State. \u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0432\u044b\u043d\u0435\u0441 \u044d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 <code>receive_event<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>celery_exporter\/exporter.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import time from functools import partial from threading import Thread  import structlog from celery import Celery from celery_exporter import metrics, track from celery_exporter.conf import settings from celery_exporter.utils.celery_app_settings import CeleryAppSettings from prometheus_client import start_http_server  logger = structlog.get_logger()   class Exporter:      CONFIGURATION: dict[str, CeleryAppSettings] = {         'default': CeleryAppSettings(             broker_url=settings.BROKER_URL,         ),         'service_a': CeleryAppSettings(             broker_url=settings.BROKER_URL,             task_default_exchange='service_a',             task_default_queue='service_a',             event_exchange='service_a.celeryev',             event_queue_prefix='service_a.celeryev',             control_exchange='service_a',         ),     }      def run(self) -> None:         for service_name in self.CONFIGURATION:             Thread(target=self.collect_worker_metrics, args=(service_name,)).start()          logger.info('Starting http server. http:\/\/0.0.0.0:%s\/metrics', settings.PORT)         start_http_server(port=settings.PORT, registry=metrics.registry)      @classmethod     def collect_worker_metrics(cls, service_name: str) -> None:                                     # noqa: C901         app = cls._create_celery_app(service_name)          if settings.COLLECT_WORKER_METRICS_RETRY_INTERVAL:             logger.debug('Using retry_interval of %s seconds', settings.COLLECT_WORKER_METRICS_RETRY_INTERVAL)          handlers = {             'worker-heartbeat': partial(track.track_worker_heartbeat, service_name=service_name),             'worker-online': partial(track.track_worker_status, service_name=service_name),             'worker-offline': partial(track.track_worker_status, service_name=service_name),         }         track_task_event = partial(track.track_task_event, service_name=service_name)          for key in metrics.events_state_counters:             handlers[key] = track_task_event          with app.connection() as connection:             while True:                 try:                     recv = app.events.Receiver(connection, handlers=handlers)                     recv.capture(limit=None, timeout=None, wakeup=True)                 except (KeyboardInterrupt, SystemExit) as ex:  # noqa: WPS329                     raise ex                 except Exception:                     logger.exception(                         'Handle exception',                          retry_interval=settings.COLLECT_WORKER_METRICS_RETRY_INTERVAL,                     )                  time.sleep(settings.COLLECT_WORKER_METRICS_RETRY_INTERVAL)      @classmethod     def _create_celery_app(cls, service_name: str) -> Celery:         celery_app_settings = cls.CONFIGURATION[service_name].dict(exclude_unset=True)         logger.debug('Create celery app', service_name=service_name, celery_app_settings=celery_app_settings)         return Celery(**celery_app_settings) <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>celery_exporter\/track.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import re from typing import Any, Callable, TypeVar  import structlog from celery.events.state import Task, Worker from celery_exporter import metrics, state from celery_exporter.conf import settings  logger = structlog.get_logger()  EventType = TypeVar('EventType', bound=dict[str, Any])   def receive_event(func: Callable[[EventType, str], None]) -> Callable[[EventType, str], None]:      def wrapper(event: EventType, service_name: str) -> None:         # put event to celery.events.state.State         (obj, _), _ = state.events_state.event(event)          contextvars = {             'event_type': event['type'],             'service_name': service_name,             'worker': getattr(obj, 'hostname', 'unknown'),         }          if isinstance(obj, Task):             contextvars['task_uuid'] = obj.uuid             contextvars['task_name'] = obj.name             contextvars['task_state'] = obj.state          with structlog.contextvars.bound_contextvars(**contextvars):             logger.debug('Received event')             func(event, service_name)      return wrapper   @receive_event def track_task_event(event: EventType, service_name: str) -> None:      # noqa: C901,WPS231     task: Task = state.events_state.tasks.get(event['uuid'])      worker_name = task.hostname     if event['type'] == 'task-sent' and settings.GENERIC_HOSTNAME_TASK_SENT_METRIC:         worker_name = 'generic'      labels = {'task': task.name, 'worker': worker_name, 'service_name': service_name}     if event['type'] == 'task-failed':         labels['exception'] = _get_exception_class_name(task.exception)      counter = metrics.events_state_counters.get(event['type'])     if counter:         counter.labels(**labels).inc()         # noinspection PyProtectedMember         logger.debug('Increment counter', metric_name=counter._name, labels=labels)     else:         logger.warning(\"Can't get counter\")      if event['type'] == 'task-succeeded':         metrics.celery_task_runtime.labels(**labels).observe(task.runtime)         # noinspection PyProtectedMember         logger.debug('Observe', metric_name=metrics.celery_task_runtime._name, task_runtime=task.runtime)   @receive_event def track_worker_heartbeat(event: EventType, service_name: str) -> None:     worker_name = event['hostname']      state.worker_last_seen[(worker_name, service_name)] = event['timestamp']      worker: Worker = state.events_state.event(event)[0][0]      active = worker.active or 0     up = 1 if worker.alive else 0      metrics.celery_worker_up.labels(worker=worker_name, service_name=service_name).set(up)     metrics.celery_worker_tasks_active.labels(worker=worker_name, service_name=service_name).set(active)      # noinspection PyProtectedMember     logger.debug('Update gauge', metric_name=metrics.celery_worker_up._name, value=up)     # noinspection PyProtectedMember     logger.debug('Update gauge', metric_name=metrics.celery_worker_tasks_active._name, value=active)   @receive_event def track_worker_status(event: EventType, service_name: str) -> None:     is_online = event['type'] == 'worker-online'     value = 1 if is_online else 0      worker_name = event['hostname']      metrics.celery_worker_up.labels(worker=worker_name, service_name=service_name).set(value)     # noinspection PyProtectedMember     logger.debug('Update gauge', metric_name=metrics.celery_worker_up._name, value=value)      if event['type'] == 'worker-online':         state.worker_last_seen[(worker_name, service_name)] = event['timestamp']     else:         _reset_worker_metrics(worker_name, service_name)   def _reset_worker_metrics(worker_name: str, service_name: str) -> None:     if (worker_name, service_name) not in state.worker_last_seen:         return      metrics.celery_worker_up.labels(worker=worker_name, service_name=service_name).set(0)     metrics.celery_worker_tasks_active.labels(worker=worker_name, service_name=service_name).set(0)     # noinspection PyProtectedMember     logger.debug(         'Update gauge',         worker=worker_name,         service_name=service_name,         metric_name=metrics.celery_worker_up._name,         value=0,     )     # noinspection PyProtectedMember     logger.debug(         'Update gauge',         worker=worker_name,         service_name=service_name,         metric_name=metrics.celery_worker_tasks_active._name,         value=0,     )   _exception_pattern = re.compile(r'^(\\w+)\\(')   def _get_exception_class_name(exception_name: str) -> str:     match = _exception_pattern.match(exception_name)     if match:         return match.group(1)     return 'UnknownException' <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/h2>\n<h3>Worker timeout<\/h3>\n<p>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c, \u0447\u0442\u043e \u0432\u043e\u0440\u043a\u0435\u0440 \u0431\u043e\u043b\u0435\u0435 \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d, \u0438 \u043e\u0442\u0440\u0430\u0437\u0438\u0442\u044c \u044d\u0442\u0443 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0432 \u043c\u0435\u0442\u0440\u0438\u043a\u0430\u0445 <code>celery_worker_up<\/code><strong> <\/strong>\u0438<strong> <\/strong><code>celery_worker_tasks_active<\/code>. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u0441\u043b\u043e\u0432\u0430\u0440\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e heartbeat<strong>.<\/strong> \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043b\u044e\u0447\u0430 \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 <code>(worker_name, service_name)<\/code>. \u0412 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0431\u0443\u0434\u0435\u043c \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043d\u0438\u0446\u0443 \u043c\u0435\u0436\u0434\u0443 \u0442\u0435\u043a\u0443\u0449\u0438\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e heartbeat. \u041f\u0440\u0438 \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u0438 \u043f\u043e\u0440\u043e\u0433\u0430 \u043e\u0431\u043d\u0443\u043b\u0438\u043c \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044b\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438. <\/p>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u0435\u043c, \u0447\u0442\u043e \u0432\u043e\u0440\u043a\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0431\u044b\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0435 Celery \u0432 K8s \u0438 \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u043a\u0430\u0442\u0438\u043b\u0438 \u043d\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <code>hostname<\/code> \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u0438\u043c\u044f \u043f\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0440\u0430\u0437\u043d\u043e\u0435. \u0421\u0442\u0430\u0440\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442 heartbeat. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u043c\u0438\u043c\u043e \u043e\u0431\u043d\u0443\u043b\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u0440\u0438\u043a \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0445 \u0443\u0434\u0430\u043b\u0438\u0442\u044c, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u044d\u0442\u0438\u043c \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u043c. <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/0dd\/090\/b0c\/0dd090b0ced798838c5e2f8d24373113.jpeg\" width=\"681\" height=\"695\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0dd\/090\/b0c\/0dd090b0ced798838c5e2f8d24373113.jpeg\" data-blurred=\"true\"\/><\/figure>\n<p>\u0425\u0440\u0430\u043d\u0438\u0442\u044c \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u044d\u0442\u043e\u0433\u043e \u0432\u043e\u0440\u043a\u0435\u0440\u0430 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043e\u043d\u0438 \u0437\u0430\u0441\u043e\u0440\u044f\u044e\u0442 Prometheus. \u0414\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442, \u043e\u0434\u043d\u0430\u043a\u043e \u0431\u0443\u0434\u0443\u0442 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u043a\u0440\u0430\u043f\u0435\u0440\u043e\u043c. \u0420\u0430\u0437\u0443\u043c\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0440\u043e\u0433, \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0443\u0434\u0430\u043b\u044f\u0442\u044c\u0441\u044f. \u0423 Flower \u0435\u0441\u0442\u044c \u043e\u043f\u0446\u0438\u044f <a href=\"https:\/\/flower.readthedocs.io\/en\/2.0\/config.html#purge-offline-workers\"><strong>purge-offline-workers<\/strong><\/a>, \u043e\u0434\u043d\u0430\u043a\u043e \u043e\u043d\u0430 <a href=\"https:\/\/github.com\/mher\/flower\/blob\/v2.0.1\/flower\/views\/workers.py#L54\">\u0432\u043b\u0438\u044f\u0435\u0442<\/a> \u043b\u0438\u0448\u044c \u043d\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432, \u043d\u043e \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u0440\u0438\u043a \u0438\u0437 \u043f\u0430\u043c\u044f\u0442\u0438. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0435\u0449\u0451 \u043e\u0434\u043d\u0443 \u043f\u0440\u0438\u0447\u0438\u043d\u0443 \u0432 \u043f\u043e\u043b\u044c\u0437\u0443 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f.   <\/p>\n<details class=\"spoiler\">\n<summary>celery_exporter\/exporter.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">class Exporter:      ...      @classmethod     def collect_worker_timeout(cls) -> None:         while True:             try:                 track.track_worker_timeout()             except (KeyboardInterrupt, SystemExit) as ex:                                           # noqa: WPS329                 raise ex             except Exception:                 logger.exception(\"Can't track timed_out_workers\")              time.sleep(settings.COLLECT_WORKER_TIMEOUT_METRICS_INTERVAL) <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>celery_exporter\/track.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">from celery_exporter.utils.timezone import localtime  ...   def track_worker_timeout() -> None:     current_time = localtime().timestamp()     # Make a copy of the last seen dict, so we can delete from the dict with no issues     worker_last_seen_copy = state.worker_last_seen.copy()      for worker_name, service_name in worker_last_seen_copy.keys():         since = current_time - worker_last_seen_copy[(worker_name, service_name)]         if since > settings.WORKER_TIMEOUT_SECONDS:             logger.info('Worker timeout. Resetting metrics', worker=worker_name, service_name=service_name, since=since)              _reset_worker_metrics(worker_name, service_name)          if since > settings.PURGE_OFFLINE_WORKER_METRICS_AFTER_SECONDS:             logger.info('Worker timeout. Purging metrics', worker=worker_name, service_name=service_name, since=since)              _purge_worker_metrics(worker_name, service_name)   def _reset_worker_metrics(worker_name: str, service_name: str) -> None:     if (worker_name, service_name) not in state.worker_last_seen:         return      metrics.celery_worker_up.labels(worker=worker_name, service_name=service_name).set(0)     metrics.celery_worker_tasks_active.labels(worker=worker_name, service_name=service_name).set(0)     # noinspection PyProtectedMember     logger.debug(         'Update gauge',         worker=worker_name,         service_name=service_name,         metric_name=metrics.celery_worker_up._name,         value=0,     )     # noinspection PyProtectedMember     logger.debug(         'Update gauge',         worker=worker_name,         service_name=service_name,         metric_name=metrics.celery_worker_tasks_active._name,         value=0,     )   def _purge_worker_metrics(worker_name: str, service_name: str) -> None:                         # noqa: C901,WPS231     # Prometheus stores a copy of the metrics in memory, so we need to remove them     # The key of the metrics is a string sequence e.g ('celery(queue_name)', 'host-1(hostname)')     # noinspection PyProtectedMember     for label_seq in list(metrics.celery_worker_tasks_active._metrics.keys()):         if worker_name in label_seq and service_name in label_seq:             metrics.celery_worker_tasks_active.remove(*label_seq)      # noinspection PyProtectedMember     for label_seq in list(metrics.celery_worker_up._metrics.keys()):                            # noqa: WPS440         if worker_name in label_seq and service_name in label_seq:             metrics.celery_worker_up.remove(*label_seq)      for counter in metrics.events_state_counters.values():         # noinspection PyProtectedMember         for label_seq in list(counter._metrics.keys()):                                         # noqa: WPS440             if worker_name in label_seq and service_name in label_seq:                 counter.remove(*label_seq)      # noinspection PyProtectedMember     for label_seq in list(metrics.celery_task_runtime._metrics.keys()):                         # noqa: WPS440         if worker_name in label_seq and service_name in label_seq:             metrics.celery_task_runtime.remove(*label_seq)      del state.worker_last_seen[(worker_name, service_name)]                                     # noqa: WPS420    ...   <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u041f\u0443\u0441\u0442\u044b\u0435 task.name<\/h3>\n<p>\u042d\u0442\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0435\u0441\u0442\u044c \u0438 \u0443 Flower, \u043f\u0440\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c. \u041f\u0440\u0438\u0445\u043e\u0434\u0438\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <code>task-succeeded<\/code>, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0448\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u0437\u0430\u0434\u0430\u0447\u0438 \u0438\u0437 State, \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0448\u044c \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u043c\u0435\u0442\u0440\u0438\u043a\u0438\u00a0\u2014 \u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u0435\u0448\u044c \u0432 \u043c\u0435\u0442\u043a\u0435 <code>task<\/code> \u043f\u0443\u0441\u0442\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443. <\/p>\n<pre><code>flower_events_total{task=\"\",type=\"task-succeeded\",worker=\"celery@aszubarev-mac.local\"} 2.0<\/code><\/pre>\n<p>\u042d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0432\u043e\u0440\u043a\u0435\u0440 <strong>\u043d\u0435<\/strong> \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0440\u0430\u043d\u0435\u0435 \u043e\u0434\u043d\u043e \u0438\u0437 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 <code>task-sent<\/code> \u0438\u043b\u0438 <code>task-received<\/code>, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u043e\u043d\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 <code>name<\/code>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0435 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0451\u0440, \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0437\u0430\u0434\u0430\u0447\u0438 \u0443\u0436\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442, \u0438 \u043f\u043e \u0438\u0445 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f <code>task-succeeded<\/code>. \u0410 \u0441\u043e\u0431\u044b\u0442\u0438\u044f <code>task-received<\/code> \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u043b\u0438\u0441\u044c \u0432 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442, \u043a\u043e\u0433\u0434\u0430 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0451\u0440 \u0435\u0449\u0451 \u043d\u0435 \u0431\u044b\u043b \u0433\u043e\u0442\u043e\u0432 \u0438\u0445 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c. <\/p>\n<h3>\u0412\u0430\u0440\u0438\u0430\u0446\u0438\u0438 event[&#8216;hostname&#8217;]<\/h3>\n<p>\u0410\u0442\u0440\u0438\u0431\u0443\u0442 <code>hostname<\/code> \u0432 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445 \u0438\u043c\u0435\u0435\u0442 \u0444\u043e\u0440\u043c\u0430\u0442 <code>worker_name@worker_hostname<\/code>, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>celery@aszubarev-mac.local<\/code><em>. <\/em>\u0418\u0437 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u044b\u0432\u043e\u0434, \u0447\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0445\u043e\u0441\u0442\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432 Celery \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0438\u043c\u0435\u043d\u0430\u043c\u0438, \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0432\u043e\u0440\u043a\u0435\u0440\u0443. \u0422\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0443 Flower. \u041c\u0435\u0442\u043a\u0430 <a href=\"https:\/\/flower.readthedocs.io\/en\/latest\/prometheus-integration.html#available-metrics\"><strong>worker<\/strong><\/a> \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0437 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 <code>hostname<\/code> \u043a\u0430\u043a \u0435\u0441\u0442\u044c. <\/p>\n<p>\u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u041c\u043e\u0436\u043d\u043e \u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u0430\u043a\u043e\u0439 \u0438\u043c\u0435\u043d\u043d\u043e \u0438\u0437 \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432 \u043d\u0430 \u0445\u043e\u0441\u0442\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b \u0441\u043e\u0431\u044b\u0442\u0438\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0442\u0434\u0435\u043b\u0438\u0442\u044c <code>worker_name<\/code><strong><em> <\/em><\/strong>\u043e\u0442 <code>worker_hostname<\/code>,<em> <\/em>\u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0432 \u043c\u0435\u0442\u043a\u0430\u0445 \u0442\u043e\u043b\u044c\u043a\u043e <code>worker_hostname<\/code>. <\/p>\n<pre><code class=\"python\">from celery.utils import nodesplit   def get_hostname(name: str) -> str:     _, hostname = nodesplit(name)     return hostname  get_hostname(\"celery@aszubarev-mac.local\")  # aszubarev-mac.local get_hostname(\"aszubarev-mac.local\")         # aszubarev-mac.local<\/code><\/pre>\n<p>\u0412 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445 <code>task-sent<\/code> \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 <code>hostname<\/code><strong> <\/strong>\u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <code>worker_name<\/code>. \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0432 <a href=\"#task_events_examples\">\u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445<\/a> \u0441\u043e\u0431\u044b\u0442\u0438\u0439.  <code>Hostname<\/code> \u043f\u043e \u0442\u0438\u043f\u0443 <code>gen90436@aszubarev-mac.local<\/code> \u043c\u043e\u0436\u0435\u0442 \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0440\u0430\u0437\u043c\u0435\u0440\u0435 \u043c\u0435\u0442\u0440\u0438\u043a. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u0435\u0441\u043b\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0432 K8s, \u0441 \u043a\u0430\u0436\u0434\u043e\u0439 \u043d\u043e\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044f \u0442\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f <code>worker_hostname<\/code><em>. <\/em>\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u0430\u0440\u0438\u0430\u0446\u0438\u0439 \u0442\u0430\u043a\u0438\u0445 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u0435\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0440\u0430\u0441\u0442\u0438. <\/p>\n<p>\u0412 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u043d\u0435 \u0442\u0430\u043a \u0432\u0430\u0436\u043d\u043e \u0441 \u043a\u0430\u043a\u043e\u0433\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0445\u043e\u0441\u0442\u0430 \u0431\u044b\u043b\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u0435\u0441\u043b\u0438 \u0432\u0430\u0448\u0438 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0432 \u043c\u0435\u0442\u043a\u0430\u0445 \u043b\u0438\u0431\u043e <code>worker<\/code> \u043b\u0438\u0431\u043e <code>worker_hostname<\/code>, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u0434\u043b\u044f \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u0430 <code>celery_task_sent_total<\/code> \u0432 \u043c\u0435\u0442\u043a\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u00abgeneric\u00bb. \u042d\u0442\u043e \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u0438\u0437 \u043f\u0440\u0438\u0447\u0438\u043d, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u0451 \u0440\u0435\u0448\u0435\u043d\u0438\u0435.  <\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0439\u0442\u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u0438 \u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0434\u0430\u0436\u0435 \u043e\u0442 \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0445\u043e\u0441\u0442\u0430. \u0415\u0441\u043b\u0438 \u0434\u043b\u044f \u0432\u0430\u0448\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0442\u044c \u0433\u0440\u0430\u0444\u0438\u043a\u0438 \u043f\u043e \u0445\u043e\u0441\u0442\u0430\u043c, \u0442\u043e \u043e\u0442\u043a\u0430\u0437 \u043e\u0442 \u043c\u0435\u0442\u043a\u0438 <code>worker_hostname<\/code> \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0435\u0442\u0440\u0438\u043a.  <\/p>\n<h3>\u0423\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438<\/h3>\n<p>\u0421\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u044e\u0442\u0441\u044f. \u041a\u0430\u043a\u0438\u0435-\u0442\u043e \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f, \u043d\u043e\u0432\u044b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f, \u0441\u0442\u0430\u0440\u044b\u0435 \u0443\u0434\u0430\u043b\u044f\u044e\u0442\u0441\u044f. \u041d\u0435\u0442\u0440\u0443\u0434\u043d\u043e \u0434\u043e\u0433\u0430\u0434\u0430\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0434\u043b\u044f \u043d\u043e\u0432\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u043e\u0432\u044b\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438, \u0430 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0441\u0442\u0430\u0440\u044b\u0445 \u0437\u0430\u0434\u0430\u0447\u0438 \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u043f\u043e\u0434\u0432\u0435\u0448\u0435\u043d\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438. \u0415\u0441\u043b\u0438 \u0432\u0430\u0448 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0451\u0440 \u043f\u0435\u0440\u0435\u0436\u0438\u0432\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u0439 \u0432\u0430\u0448\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u0443 \u043d\u0435\u0433\u043e \u043c\u043e\u0436\u0435\u0442 \u0441\u043a\u043e\u043f\u0438\u0442\u044c\u0441\u044f \u0432 \u043c\u0435\u0442\u0440\u0438\u043a\u0430\u0445 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u0438\u043b\u0438\u0447\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0445 \u0437\u0430\u0434\u0430\u0447. \u041c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u044e \u0441 worker timeout, \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043a\u0440\u0430\u0442\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0439. \u0415\u0441\u043b\u0438 \u0443\u0436 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438\u0441\u044c \u0441 \u044d\u0442\u0438\u043c, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0451\u0440. <\/p>\n<h2>Remote control<\/h2>\n<p><a href=\"https:\/\/docs.celeryq.dev\/en\/v5.3.6\/userguide\/configuration.html#worker-enable-remote-control\">\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e<\/a> \u0432\u043e\u0440\u043a\u0435\u0440 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c remote control. \u041f\u0440\u0438\u043d\u0446\u0438\u043f \u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439. \u041f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code>celery@worker_hostname.worker_name.pidbox<\/code> (\u0441\u043c\u043e\u0442\u0440\u0438 \u0440\u0430\u0437\u0434\u0435\u043b <a href=\"#exchanges_and_queues\">Exchanges \u0438 Queues<\/a>). \u0412\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0432 <strong>celery.pidbox<\/strong>, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>ping<\/code>.<\/p>\n<pre><code class=\"json\">{   \"method\": \"ping\",   \"arguments\": {},   \"destination\": null,   \"pattern\": null,   \"matcher\": null,   \"ticket\": \"10ed2733-2a7e-4293-8325-bfe900f3595f\",   \"reply_to\": {     \"exchange\": \"reply.celery.pidbox\",     \"routing_key\": \"2a63faeb-64b2-327e-809d-c76f31423cf5\"   } }<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u0430 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043e\u0442\u0432\u0435\u0442 \u043e\u0442 \u0432\u043e\u0440\u043a\u0435\u0440\u0430, \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code>oid@reply.celery.pidbox<\/code>. \u042d\u0442\u043e\u0442 <code>oid<\/code><strong><em> <\/em><\/strong>\u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 <a href=\"https:\/\/github.com\/celery\/kombu\/blob\/3547628f4d994b19661ed3f498a60a28d0f072dc\/kombu\/common.py#L51\">\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439<\/a> UUID \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u0443\u0437\u043b\u0430, \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430, \u043f\u043e\u0442\u043e\u043a\u0430, \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 Mailbox. \u041e\u043d \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>routing_key<\/code> \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c \u043f\u043e\u043b\u0435 \u0432 <code>reply_to<\/code> \u0432 \u0442\u0435\u043b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 <a href=\"https:\/\/docs.celeryq.dev\/en\/v5.3.6\/userguide\/configuration.html#control-queue-expires\">control_queue_expires<\/a>, \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0440\u0430\u0432\u043d\u043e\u0439 10 \u0441\u0435\u043a. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 <code>ping<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c timeout \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438. <\/p>\n<p>\u0412\u043e\u0440\u043a\u0435\u0440 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0438\u0437 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0438 \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0442\u0432\u0435\u0442 \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0438 exchange \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c <code>routing_key<\/code>. <\/p>\n<pre><code class=\"json\">{   \"celery@aszubarev-mac.local\": {     \"ok\": \"pong\"   } }<\/code><\/pre>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u0442\u0432\u0435\u0442 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. <\/p>\n<h3>Inspect<\/h3>\n<p><code>app.control.inspect<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u043c\u0430\u043d\u0434:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/docs.celeryq.dev\/en\/stable\/userguide\/workers.html#queues-list-of-active-queues\">active_queues<\/a>. \u041e\u0447\u0435\u0440\u0435\u0434\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0432\u043e\u0440\u043a\u0435\u0440.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.celeryq.dev\/en\/stable\/userguide\/workers.html#dump-of-registered-tasks\">registered<\/a>. \u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u0432\u043e\u0440\u043a\u0435\u0440\u0435. <\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.celeryq.dev\/en\/stable\/userguide\/workers.html#dump-of-currently-executing-tasks\">active<\/a>. \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0435\u0441\u044f \u0432 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0437\u0430\u0434\u0430\u0447\u0438.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.celeryq.dev\/en\/stable\/userguide\/workers.html#dump-of-scheduled-eta-tasks\">scheduled<\/a>. \u041e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447\u0438 (eta). <\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.celeryq.dev\/en\/stable\/userguide\/workers.html#dump-of-reserved-tasks\">reserved<\/a>. \u0417\u0430\u0434\u0430\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b, \u043d\u043e \u0432\u0441\u0451 \u0435\u0449\u0451 \u043e\u0436\u0438\u0434\u0430\u044e\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.celeryq.dev\/en\/stable\/userguide\/workers.html#statistics\">stats<\/a>. \u0414\u043b\u0438\u043d\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 (\u0438\u043b\u0438 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c) \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u0441\u0435 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b Flower \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043b\u0438\u0448\u044c \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0432 \u0441\u0432\u043e\u0435\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. <\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0430\u043d\u0435\u043b\u044c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f flower<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c3f\/b8d\/046\/c3fb8d046d2f08baab96fca5ef6a46a5.png\" width=\"3388\" height=\"1194\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c3f\/b8d\/046\/c3fb8d046d2f08baab96fca5ef6a46a5.png\"\/><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a8c\/94b\/b95\/a8c94bb95a45bddf721c127f24852451.png\" width=\"3388\" height=\"746\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a8c\/94b\/b95\/a8c94bb95a45bddf721c127f24852451.png\"\/><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/037\/9f8\/01b\/0379f801b1a5043740ab45859c8193fd.png\" width=\"3388\" height=\"1774\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/037\/9f8\/01b\/0379f801b1a5043740ab45859c8193fd.png\"\/><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u0432\u0441\u0435 \u044d\u0442\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u0440\u0438\u043a. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u044f \u043e\u0442\u0432\u0435\u0442 \u043e\u0442 <a href=\"https:\/\/docs.celeryq.dev\/en\/stable\/userguide\/workers.html#queues-list-of-active-queues\">active_queues<\/a> \u0438 <a href=\"https:\/\/docs.celeryq.dev\/en\/stable\/userguide\/workers.html#statistics\">stats<\/a>, \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438:<\/p>\n<ul>\n<li>\n<p><code>celery_active_worker_count<\/code>. \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432 \u043d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u044c. <\/p>\n<\/li>\n<li>\n<p><code>celery_active_process_count<\/code>. \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432 \u043d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u044c. <\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u0437 \u043e\u0442\u0432\u0435\u0442\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>stats<\/code> \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u043e\u0440\u043a\u0435\u0440\u0430. \u0418\u0437 \u043e\u0442\u0432\u0435\u0442\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>active_queues<\/code> \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432 \u043d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u044c. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043e\u0431\u0430, \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432 \u043d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u044c. \u041f\u0440\u043e\u0439\u0434\u044f \u043f\u043e \u0441\u043f\u0438\u0441\u043a\u0443 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439, \u043e\u0431\u043d\u043e\u0432\u0438\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438.<\/p>\n<p>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439. \u0415\u0441\u043b\u0438 \u0432\u043e\u0440\u043a\u0435\u0440\u044b \u0431\u0443\u0434\u0443\u0442 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b, \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043e\u0431\u043d\u0443\u043b\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u044d\u0442\u043e \u043d\u0430 \u0433\u0440\u0430\u0444\u0438\u043a\u0430\u0445. \u0412\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u043c \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432 \u0438 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u043c\u0438 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438. \u0417\u0434\u0435\u0441\u044c \u043e\u043d\u0430 \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c. \u0415\u0441\u043b\u0438 \u0432 \u0445\u043e\u0434\u0435 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u044b\u043b \u043f\u0435\u0440\u0435\u0435\u0437\u0434 \u0441 \u043e\u0434\u043d\u043e\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043d\u0430 \u0434\u0440\u0443\u0433\u0443\u044e, \u0442\u043e \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0430\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0431\u0443\u0434\u0435\u0442 \u043e\u0441\u0442\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u0432 \u043c\u0435\u0442\u0440\u0438\u043a\u0430\u0445. <\/p>\n<pre><code class=\"python\">from celery_exporter import metrics, state  ...   def track_queue_metrics(     app: Celery,      connection: Connection,      service_name: str, ) -> None:      inspect = app.control.inspect()          inspect_stats = inspect.stats() or {}          inspect_active_queues = inspect.active_queues() or {}          concurrency_per_worker = {         worker: len(stats['pool'].get('processes', []))         for worker, stats in inspect_stats.items()     }          processes_per_queue: dict[str, int] = defaultdict(int)     workers_per_queue: dict[str, int] = defaultdict(int)       for worker, info_list in inspect_active_queues.items():         for queue_info in info_list:             queue_name = queue_info['name']              state.queues[service_name].add(queue_name)                          concurrency = concurrency_per_worker.get(worker, 0)                          workers_per_queue[queue_name] += 1             processes_per_queue[queue_name] += concurrency      for queue in state.queues[service_name]:         metrics.celery_active_process_count.labels(             queue_name=queue,              service_name=service_name         ).set(processes_per_queue[queue])                  metrics.celery_active_worker_count.labels(             queue_name=queue,              service_name=service_name,         ).set(workers_per_queue[queue])<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442\u0432\u0435\u0442\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b stats<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"json\">{   \"celery@aszubarev-mac.local\": {     \"total\": {},     \"pid\": 34389,     \"clock\": \"5693\",     \"uptime\": 14933,     \"pool\": {       \"implementation\": \"celery.concurrency.prefork:TaskPool\",       \"max-concurrency\": 10,       \"processes\": [         34397,         34398,         34399,         34400,         34401,         34403,         34404,         34405,         34406,         34407       ],       \"max-tasks-per-child\": \"N\/A\",       \"put-guarded-by-semaphore\": false,       \"timeouts\": [         0,         0       ],       \"writes\": {         \"total\": 0,         \"avg\": \"0.00\",         \"all\": \"\",         \"raw\": \"\",         \"strategy\": \"fair\",         \"inqueues\": {           \"total\": 10,           \"active\": 0         }       }     },     \"broker\": {       \"hostname\": \"127.0.0.1\",       \"userid\": \"guest\",       \"virtual_host\": \"\/\",       \"port\": 8672,       \"insist\": false,       \"ssl\": false,       \"transport\": \"amqp\",       \"connect_timeout\": 4,       \"transport_options\": {},       \"login_method\": \"PLAIN\",       \"uri_prefix\": null,       \"heartbeat\": 120.0,       \"failover_strategy\": \"round-robin\",       \"alternates\": []     },     \"prefetch_count\": 40,     \"rusage\": {       \"utime\": 10.662461,       \"stime\": 2.223827,       \"maxrss\": 51179520,       \"ixrss\": 0,       \"idrss\": 0,       \"isrss\": 0,       \"minflt\": 79384,       \"majflt\": 25,       \"nswap\": 0,       \"inblock\": 0,       \"oublock\": 0,       \"msgsnd\": 3032,       \"msgrcv\": 25751,       \"nsignals\": 0,       \"nvcsw\": 1227,       \"nivcsw\": 39649     }   } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442\u0432\u0435\u0442\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b active_queues<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"json\">{   \"celery@aszubarev-mac.local\": [     {       \"name\": \"celery\",       \"exchange\": {         \"name\": \"celery\",         \"type\": \"direct\",         \"arguments\": null,         \"durable\": true,         \"passive\": false,         \"auto_delete\": false,         \"delivery_mode\": null,         \"no_declare\": false       },       \"routing_key\": \"celery\",       \"queue_arguments\": null,       \"binding_arguments\": null,       \"consumer_arguments\": null,       \"durable\": true,       \"exclusive\": false,       \"auto_delete\": false,       \"no_ack\": false,       \"alias\": null,       \"bindings\": [],       \"no_declare\": null,       \"expires\": null,       \"message_ttl\": null,       \"max_length\": null,       \"max_length_bytes\": null,       \"max_priority\": null     }   ] } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>celery_exporter\/metrics.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">...  celery_active_worker_count = Gauge(     'celery_active_worker_count',     'The number of active workers in broker queue.',     ['queue_name', 'service_name'],     registry=registry, ) celery_active_process_count = Gauge(     'celery_active_process_count',     'The number of active processes in broker queue.',     ['queue_name', 'service_name'],     registry=registry, )<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u041c\u0435\u0442\u0440\u0438\u043a\u0438 \u0431\u0440\u043e\u043a\u0435\u0440\u0430<\/h2>\n<p>\u041c\u043e\u0436\u043d\u043e \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0443 \u0431\u0440\u043e\u043a\u0435\u0440\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0435\u0439. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 <code>Connection<\/code> \u0441 RabbitMQ, \u043c\u043e\u0436\u043d\u043e \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <code>queue_declare_ok_t<\/code> c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c\u0438 <code>message_count<\/code> \u0438 <code>consumer_count<\/code>. <\/p>\n<pre><code class=\"python\">from amqp import ChannelError from amqp.protocol import queue_declare_ok_t  ...   def track_queue_metrics(     app: Celery,      connection: Connection,      service_name: str, ) -> None:      ...      for queue in state.queues[service_name]:                  ...          consumer_count = 0         message_count = 0          rabbitmq_queue_info = _rabbitmq_queue_info(connection, queue)          if rabbitmq_queue_info:             consumer_count = rabbitmq_queue_info.consumer_count             message_count = rabbitmq_queue_info.message_count                          metrics.celery_active_consumer_count.labels(             queue_name=queue,             service_name=service_name,         ).set(consumer_count)          metrics.celery_queue_length.labels(             queue_name=queue,             service_name=service_name,         ).set(message_count)          def _rabbitmq_queue_info(     connection: Connection,      queue: str, ) -> queue_declare_ok_t | None:     try:         return connection.default_channel.queue_declare(             queue=queue,              passive=True,         )     except ChannelError as ex:         if 'NOT_FOUND' in ex.message:             logger.debug('Queue not found', queue=queue)             return None         raise ex   <\/code><\/pre>\n<details class=\"spoiler\">\n<summary>celery_exporter\/metrics.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">...  celery_queue_length = Gauge(     'celery_queue_length',     'The number of message in broker queue.',     ['queue_name', 'service_name'],     registry=registry, ) celery_active_consumer_count = Gauge(     'celery_active_consumer_count',     'The number of active consumer in broker queue.',     ['queue_name', 'service_name'],     registry=registry, )<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u0414\u0430\u0448\u0431\u043e\u0440\u0434<\/h2>\n<p>\u0421\u043e\u0431\u0440\u0430\u0432 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438, \u043f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0430\u0448\u0431\u043e\u0440\u0434. \u0422\u0443\u0442 \u0443 \u0432\u0441\u0435\u0445 \u0432\u043a\u0443\u0441\u044b \u0440\u0430\u0437\u043d\u044b\u0435, \u043a\u0430\u0436\u0434\u044b\u0439 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u0434 \u0441\u0435\u0431\u044f. \u041c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043d\u0430\u0431\u043e\u0440 \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u043d\u0430 \u043d\u0430\u0448 \u0432\u0437\u0433\u043b\u044f\u0434, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0432\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0442 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430: <\/p>\n<ul>\n<li>\n<p><strong>Tasks per seconds<\/strong> c \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u043e \u0442\u0438\u043f\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u0439.<\/p>\n<\/li>\n<li>\n<p><strong>Latency<\/strong> \u0441 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u043e \u043f\u0435\u0440\u0446\u0435\u043d\u0442\u0438\u043b\u044f\u043c. <\/p>\n<\/li>\n<li>\n<p><strong>Tasks per seconds<\/strong> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0441 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u043e \u0437\u0430\u0434\u0430\u0447\u0430\u043c. \u0414\u043b\u044f \u043e\u0448\u0438\u0431\u043e\u043a \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c \u043f\u043e \u0442\u0438\u043f\u0443 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f. <\/p>\n<\/li>\n<li>\n<p><strong>Latency<\/strong> \u0441 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u043e \u0437\u0430\u0434\u0430\u0447\u0430\u043c \u0434\u043b\u044f 95-\u0433\u043e \u0438 50-\u0433\u043e \u043f\u0435\u0440\u0446\u0435\u043d\u0442\u0438\u043b\u0435\u0439. <\/p>\n<\/li>\n<li>\n<p><strong>Queue Length<\/strong> c \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>Active consumers count<\/strong> c \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>Active workers count<\/strong> c \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>Active processes count<\/strong> c \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u0434\u0435\u043b\u0430\u043b \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 <a href=\"https:\/\/github.com\/aszubarev\/celery-exporter\/blob\/master\/docker-compose.yaml\">\u0441\u0442\u0435\u043d\u0434<\/a>. \u041e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0430\u0431\u043e\u0440 \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432, \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0451\u0440, \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440, RabbitMQ, Prometheus \u0438 Grafana. \u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043f\u0430\u043d\u0435\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c \u0438\u0437 <a href=\"https:\/\/github.com\/aszubarev\/celery-exporter\/blob\/master\/examples\/dashboards\/worker_tasks.json\">worker_tasks.json<\/a>. \u041f\u0440\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 <code>namespace<\/code> \u0438 <code>service_name<\/code>. \u0412\u043e\u0442 \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c:<\/p>\n<details class=\"spoiler\">\n<summary>\u0414\u0430\u0448\u0431\u043e\u0440\u0434<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f08\/33d\/be9\/f0833dbe9d7819646583e5060f2b549d.png\" alt=\"\" title=\"\" width=\"3408\" height=\"1064\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f08\/33d\/be9\/f0833dbe9d7819646583e5060f2b549d.png\"\/><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e41\/a82\/788\/e41a82788eef1c7c7273db38db5d9763.png\" width=\"3408\" height=\"1064\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e41\/a82\/788\/e41a82788eef1c7c7273db38db5d9763.png\"\/><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/824\/1b1\/18d\/8241b118d86ff4663634b5a1bd6ccfff.png\" width=\"3408\" height=\"1598\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/824\/1b1\/18d\/8241b118d86ff4663634b5a1bd6ccfff.png\"\/><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/158\/df3\/d1c\/158df3d1c243b7acae2f82355198645b.png\" width=\"3408\" height=\"1598\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/158\/df3\/d1c\/158df3d1c243b7acae2f82355198645b.png\"\/><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a71\/1f0\/713\/a711f0713e1b04bf611abb1d16927fe6.png\" width=\"3408\" height=\"1598\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a71\/1f0\/713\/a711f0713e1b04bf611abb1d16927fe6.png\"\/><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9bc\/e76\/00f\/9bce7600f009bff2cd404591971f201e.png\" width=\"3408\" height=\"1598\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9bc\/e76\/00f\/9bce7600f009bff2cd404591971f201e.png\"\/><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u041c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433<\/h2>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u0438\u0441\u044c \u0442\u0430\u043a\u0438\u0435 \u0432\u0435\u0449\u0438 \u043a\u0430\u043a State, \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u0435\u0439, \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0445 \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432, \u0437\u0430\u0434\u0430\u0447 \u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439. \u0412\u0441\u0451 \u044d\u0442\u043e \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u043f\u0430\u043c\u044f\u0442\u044c. \u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 \u0433\u043e\u043b\u043e\u0432\u0435, \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0435 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 Celery, \u043f\u0440\u0438\u0447\u0451\u043c \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0442\u043e\u0433\u043e, \u0431\u0435\u0440\u0451\u0442\u0435 \u0432\u044b \u0433\u043e\u0442\u043e\u0432\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0435 \u0441\u0432\u043e\u0451. \u0412\u0441\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043d\u043e\u0441\u044f\u0442 \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440. \u041d\u0443\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u0445\u0432\u0430\u0442\u0438\u0442 \u043b\u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u0447\u0442\u043e <strong>ack<\/strong> \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f. \u041d\u0443\u0436\u043d\u043e \u0437\u0430\u0434\u0443\u043c\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u0434 \u0442\u0435\u043c, \u0445\u0432\u0430\u0442\u0438\u0442 \u043b\u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 LRU-\u043a\u0435\u0448\u0430 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u0441\u043f\u043b\u0435\u0441\u043a\u0430 \u0442\u0440\u0430\u0444\u0438\u043a\u0430. \u0418\u043b\u0438, \u043c\u043e\u0436\u0435\u0442, \u0443\u043a\u0430\u0437\u0430\u043b\u0438 \u0442\u0430\u043a\u043e\u0435 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u043f\u0430\u043c\u044f\u0442\u044c \u043a\u043e\u043d\u0447\u0438\u0442\u0441\u044f \u0440\u0430\u043d\u044c\u0448\u0435, \u0447\u0435\u043c \u043d\u0430\u0447\u043d\u0443\u0442 \u0437\u0430\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0441\u0442\u0430\u0440\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438. <\/p>\n<p>\u0412\u0441\u0451 \u044d\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043e\u0441\u043e\u0431\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0438, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430. <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/147\/7e6\/b09\/1477e6b09df9ee1f52e9213adbd74d05.jpeg\" width=\"1000\" height=\"504\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/147\/7e6\/b09\/1477e6b09df9ee1f52e9213adbd74d05.jpeg\" data-blurred=\"true\"\/><\/figure>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 Celery\u00a0\u2014 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0431\u0448\u0438\u0440\u043d\u0430\u044f \u0442\u0435\u043c\u0430. \u041b\u0438\u0448\u044c \u0437\u043d\u0430\u044f \u0442\u043e\u043d\u043a\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0443\u043c\u043d\u043e \u043f\u043e\u0434\u043e\u0439\u0442\u0438 \u043a \u0432\u044b\u0431\u043e\u0440\u0443 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e. <\/p>\n<p>\u0425\u043e\u0442\u0435\u043b \u0431\u044b \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u043b\u044f\u043b\u0441\u044f \u043f\u0440\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0441\u0442\u0430\u0442\u044c\u0438:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/github.com\/danihodovic\/celery-exporter\/\">celery-exporter<\/a> \u043e\u0442 <a href=\"https:\/\/github.com\/danihodovic\">Dani Hodovic<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/Bahus\/celery-prometheus-exporter\">celery-prometheus-exporter<\/a> \u043e\u0442 <a href=\"https:\/\/habr.com\/ru\/users\/Bahusss\/\">@Bahusss<\/a><\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u0441\u0435\u043c \u0441\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435! \u041f\u0438\u0448\u0438\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445, \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043b\u0438\u0441\u044c \u043b\u0438 \u0432\u044b \u0441 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439 \u0438 \u043a\u0430\u043a \u0432\u044b \u0435\u0451 \u0440\u0435\u0448\u0430\u043b\u0438 \u0432 \u0441\u0432\u043e\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/804535\/\"> https:\/\/habr.com\/ru\/articles\/804535\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><\/figure>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u043f\u043e\u043a\u0440\u044b\u0442\u0438\u044e \u043c\u0435\u0442\u0440\u0438\u043a\u0430\u043c\u0438 Celery: \u043e\u043d \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043b\u0443\u0448\u0430\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438\u0437 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u044d\u0442\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043c\u0435\u0442\u0440\u0438\u043a, \u0430 \u0444\u043e\u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043e\u0442\u0434\u0430\u0451\u0442 \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0441\u043a\u0440\u0430\u043f\u0435\u0440\u0443. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u0438\u0445 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b, \u043e\u0442\u043a\u0443\u0434\u0430 \u0438 \u043a\u0430\u043a \u0438\u0445 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c. \u0422\u0430\u043a\u0436\u0435 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043f\u0440\u043e \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0443\u0434\u0430\u043b\u0451\u043d\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f (remote control), \u043a\u0430\u043a\u0438\u0435 \u0443 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438 \u043a\u0430\u043a \u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f. \u041e\u0431\u0441\u0443\u0434\u0438\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u0447\u0435\u043c \u043e\u043d\u0438 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f, \u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u0432\u0430\u043c, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043e\u0434\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u0451. <\/p>\n<figure class=\"full-width\"><\/figure>\n<h2>\u0421\u043e\u0431\u044b\u0442\u0438\u044f Celery<\/h2>\n<p>\u0423 celery \u0435\u0441\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0433\u0438\u0431\u043a\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043d\u0430 \u0434\u0432\u0435 \u0433\u0440\u0443\u043f\u043f\u044b: <code>task<\/code> \u0438 <code>worker<\/code>.  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u0445. <\/p>\n<h3>\u0413\u0440\u0443\u043f\u043f\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 task<\/h3>\n<ul>\n<li>\n<p><code>task-sent<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 (producer), \u043a\u043e\u0433\u0434\u0430 task \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d \u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <a href=\"https:\/\/docs.celeryq.dev\/en\/v5.3.6\/userguide\/configuration.html#task-send-sent-event\"><strong>task_send_sent_event<\/strong><\/a>.<\/p>\n<\/li>\n<li>\n<p><code>task-received<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 worker \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0443.<\/p>\n<\/li>\n<li>\n<p><code>task-started<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a worker \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442 \u0437\u0430\u0434\u0430\u0447\u0443.<\/p>\n<\/li>\n<li>\n<p><code>task-succeeded<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e. \u0412 \u044d\u0442\u043e\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0438  \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438 (\u0430\u0442\u0440\u0438\u0431\u0443\u0442 <code>runtime<\/code>). <\/p>\n<\/li>\n<li>\n<p><code>task-failed<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u043e\u0441\u044c \u043d\u0435\u0443\u0434\u0430\u0447\u0435\u0439.<\/p>\n<\/li>\n<li>\n<p><code>task-rejected<\/code>. \u0417\u0430\u0434\u0430\u0447\u0430 \u0431\u044b\u043b\u0430 \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u0430 worker-\u043e\u043c, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0434\u043b\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0432 dead letter queue.<\/p>\n<\/li>\n<li>\n<p><code>task-revoked<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0431\u044b\u043b\u0430 \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u0430. \u0417\u0434\u0435\u0441\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u043e\u0434\u043d\u0438\u043c \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u043c.<\/p>\n<\/li>\n<li>\n<p><code>task-retried<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0430\u0441\u044c \u043d\u0435\u0443\u0434\u0430\u0447\u0435\u0439, \u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c.<\/p>\n<\/li>\n<\/ul>\n<p><a class=\"anchor\" name=\"task_events_examples\" id=\"task_events_examples\"><\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0441\u043e\u0431\u044b\u0442\u0438\u0439<\/summary>\n<div class=\"spoiler__content\">\n<h4>task-sent<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"gen7460@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 7460,   \"clock\": 6,   \"uuid\": \"4e71454e-e0bf-477c-8abf-9559721de49d\",   \"root_id\": \"4e71454e-e0bf-477c-8abf-9559721de49d\",   \"parent_id\": null,   \"name\": \"tasks.foo\",   \"args\": \"()\",   \"kwargs\": \"{}\",   \"retries\": 0,   \"eta\": null,   \"expires\": null,   \"queue\": \"celery\",   \"exchange\": \"\",   \"routing_key\": \"celery\",   \"timestamp\": 1712401950.239082,   \"type\": \"task-sent\",   \"local_received\": 1712401950.245164 } <\/code><\/pre>\n<h4>task-received<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 7226,   \"clock\": 6,   \"uuid\": \"4e71454e-e0bf-477c-8abf-9559721de49d\",   \"name\": \"tasks.foo\",   \"args\": \"()\",   \"kwargs\": \"{}\",   \"root_id\": \"4e71454e-e0bf-477c-8abf-9559721de49d\",   \"parent_id\": null,   \"retries\": 0,   \"eta\": null,   \"expires\": null,   \"timestamp\": 1712401950.2415,   \"type\": \"task-received\",   \"local_received\": 1712401950.244245 } <\/code><\/pre>\n<h4>task-started<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 7226,   \"clock\": 7,   \"uuid\": \"4e71454e-e0bf-477c-8abf-9559721de49d\",   \"timestamp\": 1712401950.243285,   \"type\": \"task-started\",   \"local_received\": 1712401950.24531 } <\/code><\/pre>\n<h4>task-succeeded<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 7226,   \"clock\": 8,   \"uuid\": \"4e71454e-e0bf-477c-8abf-9559721de49d\",   \"result\": \"None\",   \"runtime\": 0.0063114170043263584,   \"timestamp\": 1712401950.2501838,   \"type\": \"task-succeeded\",   \"local_received\": 1712401950.2526982 } <\/code><\/pre>\n<h4>task-failed<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 8704,   \"clock\": 3,   \"uuid\": \"3ca9b52f-3a6b-4780-bf51-24bdc92a1076\",   \"exception\": \"RuntimeError(\\\"Can\\\"t process task\\\")\",   \"traceback\": \"Traceback (most recent call last):\\n  File \\\"\/Users\/aszubarev\/Library\/Caches\/pypoetry\/virtualenvs\/celery-exporter-ISWk3u3R-py3.10\/lib\/python3.10\/site-packages\/celery\/app\/trace.py\\\", line 477, in trace_task\\n    R = retval = fun(*args, **kwargs)\\n  File \\\"\/Users\/aszubarev\/Library\/Caches\/pypoetry\/virtualenvs\/celery-exporter-ISWk3u3R-py3.10\/lib\/python3.10\/site-packages\/celery\/app\/trace.py\\\", line 760, in __protected_call__\\n    return self.run(*args, **kwargs)\\n  File \\\"\/Users\/aszubarev\/projects\/aszubarev\/celery-exporter\/examples\/tasks.py\\\", line 20, in test_failed\\n    raise RuntimeError(\\\"Can\\\"t process task\\\")\\nRuntimeError: Can\\\"t process task\\n\",   \"timestamp\": 1712402513.966636,   \"type\": \"task-failed\",   \"local_received\": 1712402513.9687 } <\/code><\/pre>\n<h4>task-rejected<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 10821,   \"clock\": 13,   \"uuid\": \"5be96332-3f69-4b59-8590-b6ecce54ffaf\",   \"requeue\": false,   \"timestamp\": 1712403556.524642,   \"type\": \"task-rejected\",   \"local_received\": 1712403556.527313 } <\/code><\/pre>\n<h4>task-revoked<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 14394,   \"clock\": 30,   \"uuid\": \"6d2f6d38-7378-461f-8e25-1cfc4aceb307\",   \"terminated\": false,   \"signum\": null,   \"expired\": false,   \"timestamp\": 1712405361.334489,   \"type\": \"task-revoked\",   \"local_received\": 1712405362.687277 } <\/code><\/pre>\n<h4>task-retried<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 13657,   \"clock\": 12,   \"uuid\": \"904dc2f6-6aa7-49e0-acb2-7fe241563be6\",   \"exception\": \"RuntimeError(\\\"Can\\\"t process task\\\")\",   \"traceback\": \"Traceback (most recent call last):\\n  File \\\"\/Users\/aszubarev\/Library\/Caches\/pypoetry\/virtualenvs\/celery-exporter-ISWk3u3R-py3.10\/lib\/python3.10\/site-packages\/celery\/app\/autoretry.py\\\", line 38, in run\\n    return task._orig_run(*args, **kwargs)\\n  File \\\"\/Users\/aszubarev\/projects\/aszubarev\/celery-exporter\/examples\/tasks.py\\\", line 36, in test_retried\\n    raise RuntimeError(\\\"Can\\\"t process task\\\")\\nRuntimeError: Can\\\"t process task\\n\\nDuring handling of the above exception, another exception occurred:\\n\\nTraceback (most recent call last):\\n  File \\\"\/Users\/aszubarev\/Library\/Caches\/pypoetry\/virtualenvs\/celery-exporter-ISWk3u3R-py3.10\/lib\/python3.10\/site-packages\/celery\/app\/trace.py\\\", line 477, in trace_task\\n    R = retval = fun(*args, **kwargs)\\n  File \\\"\/Users\/aszubarev\/Library\/Caches\/pypoetry\/virtualenvs\/celery-exporter-ISWk3u3R-py3.10\/lib\/python3.10\/site-packages\/celery\/app\/trace.py\\\", line 760, in __protected_call__\\n    return self.run(*args, **kwargs)\\n  File \\\"\/Users\/aszubarev\/Library\/Caches\/pypoetry\/virtualenvs\/celery-exporter-ISWk3u3R-py3.10\/lib\/python3.10\/site-packages\/celery\/app\/autoretry.py\\\", line 60, in run\\n    ret = task.retry(exc=exc, **retry_kwargs)\\n  File \\\"\/Users\/aszubarev\/Library\/Caches\/pypoetry\/virtualenvs\/celery-exporter-ISWk3u3R-py3.10\/lib\/python3.10\/site-packages\/celery\/app\/task.py\\\", line 757, in retry\\n    raise ret\\ncelery.exceptions.Retry: Retry in 5s: RuntimeError(\\\"Can\\\"t process task\\\")\\n\",   \"timestamp\": 1712404792.764382,   \"type\": \"task-retried\",   \"local_received\": 1712404792.767023 } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u0413\u0440\u0443\u043f\u043f\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 worker<\/h3>\n<ul>\n<li>\n<p><code>worker-online<\/code><strong>.<\/strong> Worker \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043b\u0441\u044f \u043a \u0431\u0440\u043e\u043a\u0435\u0440\u0443 \u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0441\u0435\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p><code>worker-offline<\/code>. Worker \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u043b\u0441\u044f \u043e\u0442 \u0431\u0440\u043e\u043a\u0435\u0440\u0430.<\/p>\n<\/li>\n<li>\n<p><code>worker-heartbeat<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u043c. <\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0441\u043e\u0431\u044b\u0442\u0438\u0439<\/summary>\n<div class=\"spoiler__content\">\n<h4>worker-online<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 21516,   \"clock\": 1,   \"freq\": 2.0,   \"active\": 0,   \"processed\": 0,   \"loadavg\": [     7.61,     7.72,     7.12   ],   \"sw_ident\": \"py-celery\",   \"sw_ver\": \"5.3.6\",   \"sw_sys\": \"Darwin\",   \"timestamp\": 1712408762.006613,   \"type\": \"worker-online\",   \"local_received\": 1712408762.01629 } <\/code><\/pre>\n<h4>worker-offline<\/h4>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 21516,   \"clock\": 71,   \"freq\": 2.0,   \"active\": 0,   \"processed\": 0,   \"loadavg\": [     4.64,     6.81,     6.82   ],   \"sw_ident\": \"py-celery\",   \"sw_ver\": \"5.3.6\",   \"sw_sys\": \"Darwin\",   \"timestamp\": 1712408827.013207,   \"type\": \"worker-offline\",   \"local_received\": 1712408827.0157518 } <\/code><\/pre>\n<h3>worker-heartbeat<\/h3>\n<pre><code class=\"json\">{   \"hostname\": \"celery@aszubarev-mac.local\",   \"utcoffset\": -3,   \"pid\": 21516,   \"clock\": 53,   \"freq\": 2.0,   \"active\": 10,   \"processed\": 80,   \"loadavg\": [     3.75,     4.21,     3.86   ],   \"sw_ident\": \"py-celery\",   \"sw_ver\": \"5.3.6\",   \"sw_sys\": \"Darwin\",   \"timestamp\": 1712407095.393169,   \"type\": \"worker-heartbeat\",   \"local_received\": 1712407095.3960378 } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u0441\u044f \u0441 \u043d\u0438\u043c\u0438 \u0432 <a href=\"https:\/\/docs.celeryq.dev\/en\/v5.3.6\/userguide\/monitoring.html#event-reference\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>. <\/p>\n<p>\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b <code>task<\/code> \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c, \u043d\u0443\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043e\u043f\u0446\u0438\u044e <a href=\"https:\/\/worker_send_task_events\"><strong>worker_send_task_events<\/strong><\/a>. \u041d\u043e \u044d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0441\u043e\u0437\u043d\u0430\u043d\u043d\u043e. \u0416\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c \u044d\u0442\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439. <\/p>\n<p>\u0421\u043e\u0431\u044b\u0442\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b <code>worker<\/code>, \u043d\u0430\u043f\u0440\u043e\u0442\u0438\u0432, \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u0430\u044f <a href=\"https:\/\/www.cloudamqp.com\/blog\/identify-and-protect-against-high-cpu-and-memory-usage.html#python-celery\">\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u044f<\/a> \u0434\u043b\u044f \u0441\u043d\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432\u00a0\u2014 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043e\u043f\u0446\u0438\u0439 <code>gossip<\/code>, <code>mingle<\/code> \u0438 <code>heartbeat<\/code>. \u0421\u0447\u0438\u0442\u0430\u044e \u044d\u0442\u0443 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u044e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439. \u041d\u043e \u043a\u043e\u0433\u0434\u0430 <code>heartbeat<\/code> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c, \u0441\u043e\u0432\u0435\u0442\u0443\u044e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043e\u043f\u0446\u0438\u044e <code>--heartbeat-interval<\/code> \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438. <\/p>\n<p><a class=\"anchor\" name=\"exchanges_and_queues\" id=\"exchanges_and_queues\"><\/a><\/p>\n<h2>Exchanges \u0438 Queues<\/h2>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f RabbitMQ \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0431\u0440\u043e\u043a\u0435\u0440\u0430, Celery \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0447\u0435\u0442\u044b\u0440\u0435 exchange. \u0418\u0445 \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0414\u0430\u043b\u0435\u0435 \u043f\u043e \u0441\u0442\u0430\u0442\u044c\u0435 \u0432\u0441\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0431\u0443\u0434\u0443\u0442 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 RabbitMQ. <\/p>\n<ul>\n<li>\n<p><code>celery<\/code>. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0437\u0430\u0434\u0430\u0447.<\/p>\n<\/li>\n<li>\n<p><code>celeryev<\/code>. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439.<\/p>\n<\/li>\n<li>\n<p><code>celery.pidbox<\/code>. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u043c\u0430\u043d\u0434 \u0432\u043e\u0440\u043a\u0435\u0440\u0430\u043c.<\/p>\n<\/li>\n<li>\n<p><code>reply.celery.pidbox<\/code>. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>Exchanges \u0438 Queues \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><\/figure>\n<figure class=\"full-width\"><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0437 <a href=\"https:\/\/docs.celeryq.dev\/en\/v5.3.6\/userguide\/monitoring.html#real-time-processing\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a> \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u044c <strong>celeryev.*<\/strong>, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u043f\u0430\u0434\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438\u0437 exchange <code>celeryev<\/code> \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u041e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u0441 \u0442\u0430\u043a\u0438\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 routing key <code>worker.#<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f gossip. <\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0430\u043d\u0435\u043b\u044c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><\/figure>\n<figure class=\"full-width\"><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u042d\u0442\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438:<\/p>\n<ul>\n<li>\n<p><code>auto-delete: true<\/code>. \u041e\u0447\u0435\u0440\u0435\u0434\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0434\u0430\u043b\u0438\u0442\u0441\u044f \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f. <\/p>\n<\/li>\n<li>\n<p><code>x-message-ttl: 5000<\/code>.<strong> <\/strong>\u0427\u0435\u0440\u0435\u0437 5 \u0441\u0435\u043a\u0443\u043d\u0434 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e \u0438 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044e.<\/p>\n<\/li>\n<li>\n<p><code>x-expires: 60000<\/code>. \u041e\u0447\u0435\u0440\u0435\u0434\u044c \u0443\u0434\u0430\u043b\u0438\u0442\u0441\u044f \u0441\u043f\u0443\u0441\u0442\u044f 60 \u0441\u0435\u043a\u0443\u043d\u0434 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f. <\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043e\u0431\u044b\u0442\u0438\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044e \u0431\u0435\u0437 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f <code>ack<\/code><strong> <\/strong>(\u00ab\u0432\u044b\u0441\u0442\u0440\u0435\u043b\u0438\u043b \u0438 \u0437\u0430\u0431\u044b\u043b\u00bb). \u042d\u0442\u043e \u0432\u0438\u0434\u043d\u043e \u043d\u0430 \u0433\u0440\u0430\u0444\u0438\u043a\u0435 \u0432 \u043f\u0430\u043d\u0435\u043b\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u043d\u0430 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0443 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044e. \u041d\u043e \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0440\u0438\u0441\u043a\u0438 \u043f\u043e\u0442\u0435\u0440\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u041d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u044d\u0442\u043e \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430. <\/p>\n<h2>\u0413\u043e\u0442\u043e\u0432\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f<\/h2>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0433\u043e\u0442\u043e\u0432\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 \u0432\u0438\u0434\u0435 <a href=\"https:\/\/flower.readthedocs.io\/en\/2.0\/\">Flower<\/a>. \u0423 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0432\u0435\u0441\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 <a href=\"https:\/\/flower.readthedocs.io\/en\/2.0\/prometheus-integration.html#available-metrics\">\u043d\u0430\u0431\u043e\u0440<\/a> \u043c\u0435\u0442\u0440\u0438\u043a. \u0415\u0441\u0442\u044c \u0441\u0432\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-372442","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/372442","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=372442"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/372442\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=372442"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=372442"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=372442"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}