Dalam siaran ini kita akan belajar cara menggunakan penyelia untuk mengendalikan pelaksanaan arahan symfony. Pada asasnya, penyelia akan membenarkan kami:
Kadangkala kami menggunakan crontab unix untuk mengautomasikan pelaksanaan proses. Ini mungkin berkesan pada kebanyakan masa tetapi mungkin terdapat situasi yang boleh menyebabkan masalah.
Mari bayangkan kita mempunyai jadual pangkalan data yang merekodkan pemberitahuan pengguna. Jadual menyimpan maklumat berikut:
Sebaliknya, kami telah mengekodkan arahan yang pelaksanaannya mengikut langkah seterusnya:
Kami menetapkan arahan ini dalam crontab linux untuk dijalankan setiap kali (1 minit, 2 minit dll). Setakat ini bagus.
Sekarang mari bayangkan bahawa proses semasa telah menanyakan 500 pemberitahuan dan apabila ia telah menghantar 400, proses baharu bermula. Ini bermakna proses baharu akan menanyakan 100 pemberitahuan yang belum dikemas kini oleh proses terakhir serta yang baharu:
Ini boleh menyebabkan 100 pemberitahuan itu dihantar dua kali kerana kedua-dua proses telah menanyakannya.
Sebagai penyelesaian, kita boleh menggunakan penyelia. Ia akan memastikan proses kami berjalan dan akan memulakannya semula apabila diperlukan. Dengan cara ini, kami hanya menyimpan satu proses dan mengelakkan pertindihan. Mari analisa bagaimana arahan itu sepatutnya kelihatan seperti:
#[AsCommand( name: 'app:notification' )] class NotificationCommand extends Command { private bool $forceFinish = false; protected function configure(): void { $this ->addOption('time-limit', null, InputOption::VALUE_OPTIONAL, 'Max time alive in seconds') ->addOption('time-between-calls', null, InputOption::VALUE_OPTIONAL, 'Time between every loop call') ; } protected function execute(InputInterface $input, OutputInterface $output): int { $this->forceFinish = false; pcntl_signal(SIGTERM, [$this, 'signalHandler']); pcntl_signal(SIGINT, [$this, 'signalHandler']); $timeLimit = $input->getOption('time-limit'); $timeBetweenCalls = $input->getOption('time-between-calls'); $dtMax = (new \DateTimeImmutable())->add(\DateInterval::createFromDateString("+ {$timeLimit} seconds")); do{ // Here we should execute a service to query and send notifications // ...... sleep($timeBetweenCalls); $dtCurrent = new \DateTimeImmutable(); }while($dtCurrent < $dtMax && !$this->forceFinish); return Command::SUCCESS; } public function signalHandler(int $signalNumber): void { echo 'Signal catch: ' . $signalNumber . PHP_EOL; match ($signalNumber) { SIGTERM, SIGINT => $this->forceFinish = true, default => null }; } }
Mari terangkan arahan langkah demi langkah:
Kaedah konfigurasi mengisytiharkan kepada pilihan input:
Kaedah laksana berkelakuan seperti berikut:
Fungsi signalHandler menangkap isyarat SIGTERM dan SIGINT Unix. SIGINT ialah isyarat yang dihantar apabila kita menekan Ctrl+C dan SIGTERM ialah isyarat lalai apabila kita menggunakan arahan bunuh. Apabila fungsi signalHandler mengesannya, ia menetapkan pembolehubah forceFinish kepada benar supaya, apabila gelung semasa selesai, arahan akan tamat kerana pembolehubah forceFinish ialah tidak lagi palsu. Ini membolehkan pengguna menamatkan proses tanpa perlu menunggu sehingga tarikh maksimum selesai.
Setakat ini, kami telah mencipta arahan. Kini tiba masanya untuk menyediakan penyelia supaya ia boleh mengendalikannya. Sebelum memulakan konfigurasi, kita mesti memasang penyelia. Anda boleh melakukannya dengan menjalankan arahan berikut:
sudo apt update && sudo apt install supervisor
Selepas memasang, anda boleh memastikan penyelia berjalan dengan melaksanakan arahan seterusnya:
sudo systemctl status supervisor
Fail konfigurasi penyelia diletakkan dalam folder berikut: /etc/supervisor/conf.d. Mari buat fail bernama notif.conf dan tampal kandungan berikut:
command=php <your_project_folder>/bin/console app:notifications --time-limit=120 --time-between-calls=10 user=<your_user> numprocs=1 autostart=true autorestart=true process_name=%(program_name)s_%(process_num)02d
Mari terangkan setiap kunci:
Dengan konfigurasi ini, perintah app:notifications akan berjalan selama maksimum 120 saat dan, ia akan tidur selama 10 saat selepas setiap gelung. Selepas melepasi 120 saat atau menyimpan isyarat unix, arahan akan keluar dari gelung dan selesai. Kemudian, penyelia akan memulakannya semula.
Kami telah belajar cara menggunakan penyelia untuk memastikan arahan berjalan tanpa perlu menggunakan crontab. Ini boleh berguna apabila proses yang dilancarkan oleh crontab mungkin bertindih, menyebabkan kerosakan data.
Dalam buku terakhir yang saya tulis, saya menunjukkan cara menggunakan penyelia untuk memastikan pekerja symfony messenger berjalan. Jika anda ingin mengetahui lebih lanjut, anda boleh mencari buku di sini: Membina Api Berorientasikan Operasi menggunakan PHP dan Rangka Kerja Symfony: Panduan langkah demi langkah
Atas ialah kandungan terperinci Menggunakan Penyelia untuk mengendalikan pelaksanaan Perintah Symfony. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!