Soru LInux OOM özel yanıtı


Apache web sunucusu çalıştırıyorum ve OOM durumunun nasıl ele alınacağını biraz geliştirmek istiyorum.

OOM puanlarından uzaklaşıyorum ve bu konuda bazı özelleştirmeler yaptım, bu yüzden kötü bir şey olduğunda, Linux doğru süreçleri öldürüyor. Ama bu yeterli değil.

Sorun şu ki, OOM meydana geldiğinde, sunucu aşırı yükleniyor ve daha sonra çöküyor ve yeniden başlatılmalı. Sunucunun tam olarak yeniden başlatılmadan halledilmesini istiyorum. Bu yüzden, tüm apache (ve CGIs) süreçlerini öldürecek ve böylece belleği serbest bırakıp (Apache) tekrar başlatacak olan OOM katilinin icadı üzerine bir betiği "çırpmak" zorundayım.

Bunun işe yarayacağını biliyorum, çünkü eğer OOM meydana gelirse ve sunucuya giriş yapmak için yeterince hızlıyım ve Apache'yi manuel olarak öldürdüm, her şey yolunda.

FYI Hemen hemen yüzlerce web sunucusunda çalışıyorum, bu yüzden tam otomatik çözüm arayışındayım.

Olası bir çözüm elbette, syslog'u ayrıştıracak ve OOM'ları bu şekilde algılayacak bazı bekçi köpeği kullanmak olacaktır. Zaten böyle bir şey var, OOM cinayetleri e-posta ile bildiriyor. Bu yaklaşım bazı durumları çözebilir, ancak eğer OOM gerçekten kötü ise, sunucu aşırı yüklenir ve betiğim bile başlamaz (cron tarafından çalıştırılır). Sistem günlüğünü izlemek veya syslog'u doğrudan (yani fifo ile) komut dosyasına aktarmak için inotify kullanarak geliştirilebilir.

Ama yine de merak ediyorum - senaryoyu doğrudan OOM katiline nasıl "bağlayacağım" diye bir yol yok mu? Yani bazı / etc / .. dosyasında böyle bir şey koyardım:

oom_action="sh /path/to/my/script.sh kill"

Ya da bunu böyle yapmak mümkün değil mi?

Ben FastCGI olarak Centos 6, Apache 2.2 ve PHP kullanıyorum.


6
2018-04-28 07:52


Menşei




Cevaplar:


Neden sadece apache süreçlerini izlemiyor ve oom_adj OOM'da ilk feshedeceklerinden emin olmak için 15'e değer mi? İşte Bu ayar hakkında bazı talimatlar vardır.

Yapılandırmanıza bağlı olarak apache başlangıç ​​komut dosyalarını değiştirebilir veya bunu yapmak için basit bir cron görevi ayarlayabilirsiniz.

Komutun çıkışını periyodik olarak da izleyebilirsiniz. dmesg | grep -i oom. Eğer herhangi bir hat olacaksa, OOM katili, sunucu son kez açıldığından beri birini öldürdü. Daha sonra arabelleği temizleyebilirsiniz. dmesg --clear


3
2018-05-05 12:03



Bu şekilde yapılandırılmış OOM-katili zaten var, bu yüzden öncelikle PHP ve HTTP'yi öldürüyor. Yani "normal" durumda, sadece birkaç süreci öldürür ve her şey yolunda. Ancak kritik durumda, yeterli değildir ve tüm HTTP ve PHP işlemlerini (ve sonra tekrar Apache'yi yeniden başlatmayı) gerçekten gerekli kılar. - dave
@dave Ardından, komutun çıkışını periyodik olarak izlemelisiniz dmesg | grep -i oom. Eğer herhangi bir hat olacaksa, OOM katili, sunucu son kez açıldığından beri birini öldürdü. Daha sonra arabelleği temizleyebilirsiniz. dmesg --clear - Vladislav Rastrusny


Vahşi, korkunç bir sürü uygulama var biliyorum, ama bir sürü yok bir şey şeylerin Apache / FastCGI / PHP tarafında yapabilirdiniz? Apache sürekli olarak OOMing, sıklıkla karşılaşmanız gereken bir şey değildir.

Maksimum Apache süreci sayısını ve FastCGI işleyicilerini azaltmaya çalışın ve geçerli php.ini ayarlarınızın komut başına maksimum bellek için çok yüksek olup olmadığını görün.

Ayrıca, kullanımı mükemmel ulimit Apache ile bir işlemin kullanabileceği bellek sayısını sınırlandırır. Sunucu neredeyse ölüme kadar sarmadan önce size yardımcı olabilir.

OOM çok son çare ve ona yol açabilecek her şey denetlenmeli.


0
2018-05-05 13:34



Bu doğru ve tabi ki bu konuda çok fazla şeyim var. Ama aynı zamanda birçok farklı PHP uygulamasına sahip pek çok sunucum var, vb. Bu durumların günlük olarak gerçekleştiğini söylemiyorum, fakat elbette, zaman zaman onlar oluyor. - dave


Daha iyi bir çözüm bulamadığımdan, çekirdek syslog mesajlarını okumak için watchdog'u uyguladı (fifo yoluyla):

/etc/rsyslog.d:

(...)
kern.err         |/path/to/fifo

ve OOM-katil aktivitesi için onları ara:

while read /path/to/fifo; do (..)

ve OOM-katil kitlesel olarak ortaya çıktığında (sadece acil durumlar için kontrol etmem gerekiyor), Apache'yi öldürüp (ve sonra) başlarım.


0
2018-05-05 14:20





Sanırım işleminizi grup belleği alt kümesine koyarsanız ve release_agent bellek gerçekleştiğinde harici bir komut çağırmak için

notify_on_release
    contains a Boolean value, 1 or 0, that either enables or disables the execution of the release agent. If the notify_on_release is enabled, the kernel executes the contents of the release_agent file when a cgroup no longer contains any tasks (that is, the cgroup's tasks file contained some PIDs and those PIDs were removed, leaving the file empty). A path to the empty cgroup is provided as an argument to the release agent. 

release_agent (present in the root cgroup only)
    contains a command to be executed when a “notify on release” is triggered. Once a cgroup is emptied of all processes, and the notify_on_release flag is enabled, the kernel runs the command in the release_agent file and supplies it with a relative path (relative to the root cgroup) to the emptied cgroup as an argument. The release agent can be used, for example, to automatically remove empty cgroups

Grup kullanarak, ne kadar kaynağın işleyebileceğini kontrol edebilir ve sunucunuzu aşırı yük yüklemezsiniz.

Using cgroup you can control the server resources

0
2018-05-05 16:28



C grubu kulağa hoş geliyor. Onlara daha yakından bakmaya ihtiyacım var (çünkü onlarla neredeyse hiçbir expirience yok). Böyle bir şey yapabileceklerini bilmiyorlardı (release_agent). Öte yandan, bazı süreçler tarafından ne kadar bellek kullanılabileceğine dair "katı" sınırlar koyarsam, bazı servislerde "atık" bellekte, diğer hizmetler tarafından kullanılmadığında (ör., Mysql). Bunu iyi bir şekilde kullanmak için, çok iyi ince ayar gerektiriyor ve birçok sunucuda bakımı çok daha zor olurdu. - dave