Hai,
Saya menggunakan Kubernetes untuk menerapkan aplikasi python saya, Kubernetes menyediakan livenessProbe dan readinessProbe, lihat di sini .
Bagaimana saya dapat memeriksa apakah seledri saya berdetak atau pekerja seledri masih hidup dan dalam keadaan yang benar?
PID bukanlah solusi karena tidak dapat digunakan untuk menangkap deadlock misalnya.
Terima kasih sebelumnya atas bantuan Anda,
Salam Hormat,
Celery memiliki API pemantauan yang dapat Anda gunakan.
Pod harus dianggap hidup jika pekerja Celery mengirimkan detak jantung .
Sebuah pod harus dianggap siap jika pekerja telah mengirim acara pekerja-online .
Jika Anda memiliki masalah khusus atau permintaan fitur, buka masalah terpisah.
Apakah ini akan berhasil?
readinessProbe:
exec:
command:
- "/bin/sh"
- "-c"
- "celery -A path.to.app status | grep -o ': OK'"
initialDelaySeconds: 30
periodSeconds: 10
@ 7wonders Anda harus mengekstrak nama simpul seledri terlebih dahulu. ReadinessProbe ini akan gagal jika ada contoh seledri yang gagal dan bukan itu yang Anda inginkan.
@thedrow Hmm, saya pikir sebenarnya itu akan berhasil bahkan jika node yang sebenarnya telah gagal tetapi yang lain baik-baik saja yang juga bukan hasil yang bagus.
Seperti
/bin/sh -c 'exec celery -A path.to.app inspect ping -d celery@$HOSTNAME'
cukup baik untuk memeriksa kesiapan dan memverifikasi hanya satu node.
Berhati-hatilah karena di beberapa aplikasi, menjalankan perintah ini dapat memakan waktu beberapa detik menggunakan CPU penuh DAN default kubernetes adalah menjalankannya setiap 10 detik.
Dengan demikian, jauh lebih aman untuk memiliki periodSeconds tinggi (periode kami disetel ke 300).
@redbaron apakah perintah itu bekerja untuk Anda? Jika berhasil, lalu apa saja pengaturan untuk masalah keaktifan dan kesiapan?
Untuk beberapa alasan, pemeriksaan kesiapan ini sama sekali tidak memuaskan bagi kami. Inspect merespons secara non-deterministik tanpa beban di cluster kami. Kami menjalankan format seperti ini:
seledri periksa ping -b " redis: // archii-redis-master : 6379" -d celery @ archii-task-crawl-integration-7d96d86b9d-jwtq7
Dan dengan waktu ping normal (10 detik), cluster kita benar-benar mati oleh CPU yang dibutuhkan oleh seledri.
~ Saya menggunakan ini untuk kehidupan dengan interval 30-an: sh -c celery -A path.to.app status | grep "${HOSTNAME}:.*OK"
~
Saya menggunakan ini untuk kehidupan dengan interval 30-an: sh -c celery -A path.to.app inspect ping --destination celery@${HOSTNAME}
Sepertinya tidak menimbulkan beban tambahan, saya menjalankan armada lebih dari 100 pekerja.
Pemeriksaan kesiapan tidak diperlukan, Celery tidak pernah digunakan dalam layanan. Saya baru saja menetapkan minReadySeconds: 10
yang cukup baik untuk menunda startup pekerja dalam menjalankan Deployments, tetapi ini jelas tergantung pada waktu startup Celery untuk proyek Anda, jadi periksa log dan atur sesuai.
Probe kesiapan masih berguna meskipun tidak digunakan dalam layanan. Khususnya, saat Anda melakukan penerapan pekerja dan ingin memastikan penerapan berhasil, Anda biasanya menggunakan kubectl rollout status deployment
. Tanpa uji kesiapan, kami telah menerapkan kode buruk yang tidak memulai seledri dan tidak mengetahuinya.
Solusi saya adalah:
readinessProbe:
exec:
command:
[
"/usr/local/bin/python",
"-c",
"\"import os;from celery.task.control import inspect;from <APP> import celery_app;exit(0 if os.environ['HOSTNAME'] in ','.join(inspect(app=celery_app).stats().keys()) else 1)\""
]
Yang lain sepertinya tidak berfungsi 🤷♂️
Terima kasih @yardensachs!
Luangkan banyak waktu untuk men-debug apa yang salah dengan solusi lain, tetapi tidak mungkin
Sepertinya celery inspect ping
perintah tidak mengembalikan exit (0) atau sesuatu seperti itu
celery inspect ping
berfungsi, tetapi Anda memerlukan bash
untuk mengganti variabel lingkungan seperti ini:
livenessProbe:
exec:
# bash is needed to replace the environment variable
command: [
"bash",
"-c",
"celery inspect ping -A apps -d celery@$HOSTNAME"
]
initialDelaySeconds: 30 # startup takes some time
periodSeconds: 60 # default is quite often and celery uses a lot cpu/ram then.
timeoutSeconds: 10 # default is too low
senang mendengarnya
Kami akhirnya merobek seledri memeriksa ping dari probe kehidupan kami karena kami menemukan bahwa di bawah beban yang lebih berat, ping hanya akan bertahan selama beberapa menit pada suatu waktu meskipun pekerjaan sedang diproses dengan baik dan tidak ada backlog. Saya merasa itu ada hubungannya dengan menggunakan eventlet, tapi kami terus memeriksanya.
@WillPlatnick Itu tidak akan terjadi dengan 5.0 karena Celery akan asinkron sehingga akan ada kapasitas yang dicadangkan untuk coroutine kontrol.
Saya mengalami masalah dengan proses inspect ping
pemijahan mati / zombie:
root 2296 0.0 0.0 0 0 ? Z 16:04 0:00 [python] <defunct>
root 2323 0.0 0.0 0 0 ? Z 16:05 0:00 [python] <defunct>
...
Adakah orang lain yang mengalami ini? Tidak ada argumen --pool
untuk memaksa eksekusi proses tunggal.
Bolehkah saya bertanya apa yang Anda gunakan selain celery inspect ping
@WillPlatnick? Kami mengalami masalah serupa dengan probe gagal karena beban berat.
@mcyprian Kami menyingkirkan probe kehidupan. Naluri saya memberi tahu saya bahwa itu ada hubungannya dengan eventlet, tetapi kami belum menjadikannya prioritas untuk mengetahuinya.
kami menemui masalah CPU yang sama dengan broker Redis
Adakah yang menemukan solusi?
Kami juga bereksperimen dengan penjadwalan "debug_task" pada antrian yang namanya kami berdasarkan nama penampung. Masalahnya adalah kami memiliki banyak antrian lama di RabbitMQ sekarang
Perlu diketahui bahwa menggunakan
sh -c celery -A path.to.app status | grep "${HOSTNAME}:.*OK"
seperti yang disarankan di https://github.com/celery/celery/issues/4079#issuecomment -437415370 akan menyebabkan laporan kesalahan besar-besaran di rabbitmq, lihat https://github.com/celery/celery/issues/4355#issuecomment - 578786369
Saya rasa saya telah menemukan cara untuk mengurangi penggunaan CPU untuk memeriksa ping.
seledri -b amqp: // user: pass @ rabbitmq : 5672 / vhost periksa ping
Tidak memuat konfigurasi seledri menggunakan -A path.to.celery tentu terbantu dengan penggunaan cpu,
dapatkah seseorang memverifikasi.
Saya rasa saya telah menemukan cara untuk mengurangi penggunaan CPU untuk memeriksa ping.
seledri -b amqp: // user: pass @ rabbitmq : 5672 / vhost periksa ping
Tidak memuat konfigurasi seledri menggunakan -A path.to.celery tentu terbantu dengan penggunaan cpu,
dapatkah seseorang memverifikasi.
Bagus! Ini jauh lebih baik daripada dengan aplikasi yang dimuat.
Tapi kami masih mendapatkan biaya besar dari proses python yang dimulai + impor seledri. Saya tetap akan merekomendasikan periode tinggi.
Hai,
seledri periksa ping -A app.tasks -d seledri @ $ HOSTNAME memberi saya "Kesalahan: Siaran tidak didukung oleh transportasi 'sqs'".
Saya menggunakan SQS sebagai broker, jadi ini berarti perintah 'inspect' / 'status' tidak akan berfungsi dengan SQS?
Kami telah menemukan bahwa dalam skala besar, semua fitur kendali jarak jauh menyebabkan instance Redis melonjak di CPU karena perintah yang ditetapkan pada kunci kombu.pidbox
, jadi kami tidak dapat menggunakan ping, atau status atau inspeksi sebagaimana adanya. semua menggunakan remote control dan mencoba menonaktifkan remote control untuk kasus penggunaan produksi.
Sepertinya saya memiliki antrian pemeriksaan kesehatan khusus adalah cara yang benar tetapi saya tidak yakin sama sekali
Adakah yang punya arahan lain yang tidak melibatkan remote control untuk menguji health check?
Kami menggunakan antrian pemeriksaan kesehatan khusus dengan kebijakan penggusuran RabbitMQ (antrian dihapus secara otomatis) dengan sukses untuk beberapa waktu sekarang, dan kami senang dengan solusinya. Sebagian besar karena pemeriksaan ini memang memeriksa bahwa pekerja memproses tugas dan menyelesaikannya. Sejak kami memperkenalkannya, kami tidak memiliki masalah lagi dengan pekerja yang macet.
@bartoszhernas keberatan berbagi beberapa kode untuk itu? apakah Anda mengantri ini melalui beat dan daripada pekerja yang mengambilnya?
ingin melihat kode + bagian probe kehidupan
Hai, kodenya sangat mudah:
Di Kubernetes saya menentukan nama antrian berdasarkan POD_NAME, dan meneruskannya ke skrip pemeriksaan langsung:
livenessProbe:
initialDelaySeconds: 120
periodSeconds: 70
failureThreshold: 1
exec:
command:
- bash
- "-c"
- |
python celery_liveness_probe.py $LIVENESS_QUEUE_NAME
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: LIVENESS_QUEUE_NAME
value: queue-$(MY_POD_NAME)
(Anda perlu menggunakan bash -c, karena Kubernetes tidak memperluas ENV saat mencoba meneruskannya sebagai perintah secara langsung)
maka celery_liveness_probe.py hanya mengatur Django agar dapat menggunakan Celery dan menjadwalkan tugas pada antrian POD
# encoding: utf-8
from __future__ import absolute_import, unicode_literals
import os
import sys
if __name__ == "__main__":
import django
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ahoy.archive.settings")
django.setup()
from ahoy.archive.apps.eventbus.service import eventbus_service
exit(0 if eventbus_service.health_check(sys.argv[1] if sys.argv and len(sys.argv) > 1 else None) else 1)
fungsi health check mengirimkan tugas dan menunggu hasilnya
def health_check(self, queue_name: Optional[str] = None) -> bool:
event = self.celery.send_task(
AhoyEventBusTaskName.LIVENESS_PROBE,
None,
queue=queue_name or self.origin_queue,
ignore_result=False,
acks_late=True,
retry=False,
priority=255
)
try:
is_success = event.get(timeout=10)
except (celery.exceptions.TimeoutError, AttributeError):
is_success = False
return is_success
Jadi pada dasarnya: mengirim tugas, dan jika mengembalikan hasil maka pekerja itu sehat. Jika pekerja mengalami kebuntuan (terjadi berkali-kali) maka tugas tidak pernah selesai, Pod akan dimulai ulang dan semuanya kembali normal.
Satu-satunya peringatan adalah Anda harus berurusan dengan antrian lama, dengan RabbitMQ itu mudah, kami hanya mengatur kebijakan kadaluwarsa pada antrian
https://www.rabbitmq.com/ttl.html#queue -ttl
@bartoszhernas terima kasih telah membagikan kode!
seperti yang Anda katakan, antrean saya dinamis dan kami menggunakan Redis - jadi kami benar-benar perlu menemukan cara untuk menangani nama antrean yang kedaluwarsa di Redis
Ya, kami memiliki masalah serupa dengan BullMQ dengan Redis. Ide saya adalah menulis CronJob untuk Kubernetes yang akan menghapus antrian setiap saat.
Komentar yang paling membantu
celery inspect ping
berfungsi, tetapi Anda memerlukanbash
untuk mengganti variabel lingkungan seperti ini: