Saya perlu menjalankan skrip php sebagai proses daemon (menunggu instruksi dan melakukan hal-hal). pekerjaan cron tidak akan melakukannya untuk saya karena tindakan harus diambil segera setelah instruksi tiba. Saya tahu PHP sebenarnya bukan pilihan terbaik untuk proses daemon karena masalah manajemen memori, tetapi karena berbagai alasan saya harus menggunakan PHP dalam kasus ini. Saya menemukan alat oleh libslack bernama Daemon ( http://libslack.org/daemon ) sepertinya membantu saya mengelola proses daemon, tetapi belum ada pembaruan dalam 5 tahun terakhir, jadi saya ingin tahu apakah Anda tahu beberapa alternatif lain yang cocok untuk kasus saya. Setiap informasi akan sangat dihargai.
154
Jawaban:
Anda bisa memulai skrip php dari baris perintah (yaitu bash) dengan menggunakan
nohup php myscript.php &
itu
&
menempatkan proses Anda di latar belakang.Sunting:
Ya, ada beberapa kekurangan, tetapi tidak mungkin dikendalikan? Itu salah.
Sederhana
kill processid
akan menghentikannya. Dan itu masih solusi terbaik dan paling sederhana.sumber
nohup
dan&
melakukan hal yang sama: melepaskan proses yang diluncurkan dari maksud shell saat ini. Mengapa saya membutuhkan keduanya? Bisakah saya tidak hanya melakukanphp myscript.php &
ataunohup myscript.php
?? Terima kasihnohup php myscript.php > myscript.log &
Pilihan lain adalah menggunakan Pemula . Ini awalnya dikembangkan untuk Ubuntu (dan dikemas dengan itu secara default), tetapi dimaksudkan untuk cocok untuk semua distro Linux.
Pendekatan ini mirip dengan Supervisord dan daemontools , dalam hal ini secara otomatis memulai daemon pada boot sistem dan respawn pada penyelesaian skrip.
Cara mengaturnya:
Buat file skrip baru di
/etc/init/myphpworker.conf
. Berikut ini sebuah contoh:Mulai & hentikan dasmon Anda:
Periksa apakah daemon Anda sedang berjalan:
Terima kasih
Terima kasih banyak kepada Kevin van Zonneveld , tempat saya belajar teknik ini.
sumber
sudo service myphpworker start/stop/status
hanya bekerja dengan layanan yang tidak dalam/etc/init.d
layanan pemula. @ matt-sich tampaknya telah mengungkap sintaks yang benar. Pilihan lain adalah menggunakan Gearman atau Resque, yang memungkinkan pemrosesan latar belakang & deamonisasi.Dengan systemd baru Anda dapat membuat layanan.
Anda harus membuat file atau symlink di
/etc/systemd/system/
, misalnya. myphpdaemon.service dan tempatkan konten seperti ini, myphpdaemon akan menjadi nama layanan:Anda akan dapat memulai, mendapatkan status, memulai kembali, dan menghentikan layanan menggunakan perintah
systemctl <start|status|restart|stop|enable> myphpdaemon
Skrip PHP harus memiliki semacam "lingkaran" untuk terus berjalan.
Contoh kerja:
Jika rutin PHP Anda harus dijalankan sekali dalam satu siklus (seperti diggest), Anda dapat menggunakan shell atau skrip bash untuk dipanggil ke file layanan systemd alih-alih PHP secara langsung, misalnya:
Jika Anda memilih opsi ini, Anda harus mengubah KillMode ke
mixed
ke proses, bash (utama) dan PHP (anak) terbunuh.This method also is effective if you're facing a memory leak.
sumber
systemctl status <your_service_name> -l
output, itu akan memberi Anda petunjuk apa yang terjadi.Jika Anda dapat - ambil salinan Pemrograman Tingkat Lanjut di Lingkungan UNIX . Seluruh bab 13 dikhususkan untuk pemrograman daemon. Contohnya adalah di C, tapi semua fungsi yang Anda perlu memiliki pembungkus di PHP (pada dasarnya pcntl dan POSIX ekstensi).
Dalam beberapa kata - menulis daemon (ini hanya dimungkinkan pada * nix OS-es berbasis - Windows menggunakan layanan) adalah seperti ini:
umask(0)
untuk mencegah masalah izin.fork()
dan minta orang tua keluar.setsid()
.SIGHUP
(biasanya diabaikan atau digunakan untuk memberi sinyal daemon untuk memuat ulang konfigurasinya) danSIGTERM
(untuk memberi tahu proses untuk keluar dengan anggun).fork()
lagi dan minta orang tua keluar.chdir()
.fclose()
stdin
,stdout
danstderr
dan jangan menulis kepada mereka. Cara yang benar adalah dengan mengarahkan mereka ke salah satunya/dev/null
atau file, tetapi saya tidak dapat menemukan cara untuk melakukannya dalam PHP. Mungkin saja ketika Anda meluncurkan daemon untuk mengarahkan mereka menggunakan shell (Anda harus mencari tahu sendiri bagaimana melakukan itu, saya tidak tahu :).Juga, karena Anda menggunakan PHP, berhati-hatilah untuk referensi siklik, karena pemulung sampah PHP, sebelum PHP 5.3, tidak memiliki cara untuk mengumpulkan referensi tersebut dan proses kehabisan memori akan bocor, sampai akhirnya crash.
sumber
Saya menjalankan sejumlah besar daemon PHP.
Saya setuju dengan Anda bahwa PHP bukan bahasa yang terbaik (atau bahkan bahasa yang baik) untuk melakukan ini, tetapi daemon berbagi kode dengan komponen yang menghadap web sehingga secara keseluruhan itu adalah solusi yang baik bagi kami.
Kami menggunakan daemontools untuk ini. Ini cerdas, bersih dan dapat diandalkan. Sebenarnya kita menggunakannya untuk menjalankan semua daemon kita.
Anda dapat melihatnya di http://cr.yp.to/daemontools.html .
EDIT: Daftar fitur yang cepat.
sumber
Kamu bisa
nohup
seperti yang disarankan Henrik.screen
dan jalankan program PHP Anda sebagai proses reguler di dalamnya. Ini memberi Anda lebih banyak kontrol daripada menggunakannohup
.Saya akan merekomendasikan metode paling sederhana (layar menurut saya) dan kemudian jika Anda ingin lebih banyak fitur atau fungsi, pindah ke metode yang lebih kompleks.
sumber
Ada lebih dari satu cara untuk menyelesaikan masalah ini.
Saya tidak tahu secara spesifik, tetapi mungkin ada cara lain untuk memicu proses PHP. Misalnya jika Anda memerlukan kode untuk menjalankan berdasarkan peristiwa dalam database SQL Anda bisa mengatur pemicu untuk mengeksekusi skrip Anda. Ini sangat mudah dilakukan di bawah PostgreSQL: http://www.postgresql.org/docs/current/static/external-pl.html .
Jujur saya pikir taruhan terbaik Anda adalah membuat proses Damon menggunakan nohup. nohup memungkinkan perintah untuk terus mengeksekusi bahkan setelah pengguna keluar:
Namun ada masalah yang sangat serius. Seperti yang Anda katakan, manajer memori PHP adalah sampah lengkap, itu dibangun dengan asumsi bahwa skrip hanya dijalankan selama beberapa detik dan kemudian ada. Skrip PHP Anda akan mulai menggunakan GIGABYTES memori setelah hanya beberapa hari. Anda HARUS JUGA membuat skrip cron yang berjalan setiap 12 atau mungkin 24 jam yang membunuh dan memunculkan kembali skrip php Anda seperti ini:
Tapi bagaimana jika naskahnya ada di tengah pekerjaan? Well kill -3 adalah interupsi, sama seperti melakukan ctrl + c pada CLI. Script php Anda dapat menangkap interupsi ini dan keluar dengan anggun menggunakan pustaka pcntl PHP: http://php.oregonstate.edu/manual/en/function.pcntl-signal.php
Berikut ini sebuah contoh:
Gagasan di balik $ lock adalah bahwa skrip PHP dapat membuka file dengan fopen ("file", "w") ;. Hanya satu proses yang dapat memiliki kunci tulis pada file, jadi dengan menggunakan ini Anda dapat memastikan bahwa hanya satu salinan skrip PHP Anda yang sedang berjalan.
Semoga berhasil!
sumber
Kevin van Zonneveld menulis artikel terperinci yang sangat bagus tentang ini , dalam contohnya ia menggunakan
System_Daemon
paket PEAR (tanggal rilis terakhir pada 2009-09-02).sumber
Lihat https://github.com/shaneharter/PHP-Daemon
Ini adalah perpustakaan daemon berorientasi objek. Ini memiliki dukungan bawaan untuk hal-hal seperti logging dan pemulihan kesalahan, dan memiliki dukungan untuk menciptakan pekerja latar belakang.
sumber
Baru-baru ini saya membutuhkan solusi lintas platform (Windows, Mac, dan Linux) untuk masalah menjalankan skrip PHP sebagai daemon. Saya memecahkan masalah dengan menulis solusi berbasis C ++ saya sendiri dan membuat binari:
https://github.com/cubiclesoft/service-manager/
Dukungan penuh untuk Linux (via sysvinit), tetapi juga layanan Windows NT dan Mac OSX launchd.
Jika Anda hanya membutuhkan Linux, maka beberapa solusi lain yang disajikan di sini berfungsi dengan baik dan, tergantung pada rasanya. Ada juga pemula dan systemd hari ini, yang memiliki cadangan untuk skrip sysvinit. Tetapi setengah dari titik menggunakan PHP adalah bahwa itu adalah lintas platform, sehingga kode yang ditulis dalam bahasa tersebut memiliki peluang yang cukup bagus untuk bekerja di mana saja sebagaimana adanya. Kekurangan mulai muncul ketika aspek tingkat OS asli eksternal tertentu memasuki gambar seperti layanan sistem, tetapi Anda akan mendapatkan masalah itu dengan sebagian besar bahasa skrip.
Mencoba menangkap sinyal seperti yang disarankan seseorang di sini di PHP userland bukanlah ide yang bagus. Baca dokumentasi dengan
pcntl_signal()
cermat dan Anda akan segera belajar bahwa PHP menangani sinyal menggunakan beberapa metode yang agak tidak menyenangkan (khususnya, 'kutu') yang mengunyah banyak siklus untuk sesuatu yang jarang dilihat oleh proses (yaitu sinyal). Penanganan sinyal dalam PHP juga hampir tidak tersedia pada platform POSIX dan dukungan berbeda berdasarkan versi PHP. Awalnya terdengar seperti solusi yang layak tetapi gagal menjadi sangat berguna.PHP juga menjadi lebih baik tentang masalah kebocoran memori seiring berjalannya waktu. Anda masih harus berhati-hati (parser DOM XML cenderung masih bocor) tapi saya jarang melihat proses pelarian hari ini dan pelacak bug PHP cukup tenang dibandingkan dengan zaman dahulu kala.
sumber
Seperti yang telah disebutkan orang lain, menjalankan PHP sebagai daemon cukup mudah, dan dapat dilakukan dengan menggunakan satu baris perintah. Tetapi masalah sebenarnya adalah membuatnya tetap berjalan dan mengelolanya. Saya memiliki masalah yang sama beberapa waktu lalu dan meskipun ada banyak solusi yang sudah tersedia, kebanyakan dari mereka memiliki banyak dependensi atau sulit digunakan dan tidak cocok untuk penggunaan dasar. Saya menulis skrip shell yang dapat mengelola proses / aplikasi apa pun termasuk skrip PHP cli. Itu dapat diatur sebagai cronjob untuk memulai aplikasi dan akan berisi aplikasi dan mengelolanya. Jika dijalankan lagi, misalnya melalui cronjob yang sama, itu memeriksa apakah aplikasi sedang berjalan atau tidak, jika itu keluar maka cukup keluar dan biarkan instance sebelumnya terus mengelola aplikasi.
Saya mengunggahnya ke github, silakan menggunakannya: https://github.com/sinasalek/EasyDeamonizer
EasyDeamonizer
Cukup mengawasi aplikasi Anda (mulai, mulai ulang, masuk, monitor, dll). skrip generik untuk memastikan aplikasi Anda tetap berjalan dengan baik. Secara sengaja ia menggunakan proses nama instread dari file pid / lock untuk mencegah semua efek sampingnya dan menjaga skrip sesederhana dan sekuat mungkin, sehingga selalu berfungsi bahkan ketika EasyDaemonizer itu sendiri dihidupkan ulang. fitur
sumber
Memperluas jawaban Emil Ivaov , Anda dapat melakukan yang berikut untuk menutup STDIN, STDOUT DAN STDERROR di php
Pada dasarnya Anda menutup stream standar sehingga PHP tidak memiliki tempat untuk menulis.
fopen
Panggilan berikut akan mengatur standar IO ke/dev/null
.Saya telah membaca ini dari buku Rob Aley - PHP di luar web
sumber
Saya menulis dan menggunakan php-daemon sederhana, kode online di sini
https://github.com/jmullee/PhpUnixDaemon
Fitur: menjatuhkan hak istimewa, penanganan sinyal, logging
Saya menggunakannya dalam penangan-antrian (use case: memicu operasi panjang dari halaman web, tanpa membuat php menunggu penghasil-halaman, yaitu meluncurkan operasi asinkron) https://github.com/jmullee/PhpIPCMessageQueue
sumber
Anda dapat memeriksa pm2 di sini adalah, http://pm2.keymetrics.io/
buat file ssh, seperti pekerja.sh dimasukkan ke dalam skrip php Anda yang akan Anda tangani.
pekerja
daemon mulai
Ceria, itu dia.
sumber