2015-04-23 20 views
6

Üretim node.js uygulamalarını çalıştırmakta nispeten yeniyim ve son zamanlarda sunucum zaman aşımıyla ilgili sorunlar yaşadım.Node.js Sunucu Zaman Aşımı Sorunları (EC2 + Express + PM2)

Temel olarak, belirli bir miktarda kullanımdan sonra & node.js uygulamam, isteklere yanıt vermiyor. Artık konsolumda ateş açılmış yollar görmüyorum - her şey bir anda durdu ve istemcimden (AFNetworking çalıştıran iPhone) artık sunucuya ulaşmadığı gibi. Ama eğer node.js uygulama sunucumu yeniden başlatırsam, her şey tekrar çalışmaya başlayana kadar her şey tekrar çalışmaya başlar. Uygulama asla çökmez, sadece isteklere cevap vermiyor.

Hata alıyorum ve tüm DB bağlantı hatalarını işlemeye ve kaydetmeye dikkat ettim, böylece nereden başlayacağımı bilmiyorum. Bellek sızıntılarıyla ilgili bir şey olabileceğini düşündüm, bu yüzden node-memwatch yükledim ve bellek sızıntıları için bir dinleyici ayarladı, ancak sunucum istekleri yanıt vermeyi durdurmadan önce çağrılmadı.

Neler olabileceğine dair bir ipucu ve bu sorunu nasıl çözebilirim?

  • AWS EC2 Mikro Derece üzerinde node.js (Express 4.0 + PM2 kullanarak) MySQL çalışan AWS RDS hacmine
  • Veritabanı
  • (düğüm-mysql kullanarak): Burada

    benim yığını var Oturum depolanan
  • Müşteriler
012 AFNetworking ile sunucuya erişim iPhone'lar olan node.js uygulamayla aynı EC2 örneğinde/REDIS ağırlık

Bir kez daha, yukarıda belirtilen modüllerden herhangi biriyle hata atılmıyor.

+0

Bazı rotalarınız yanıt vermiyor ve bu nedenle her şeyi asıyormuş gibi geliyor –

cevap

1

Her şeyden önce zaman aşımları hakkında biraz daha açık olmanız gerekir.

  • TCP aşımları: TCP teker teker gönderilen paketler halinde bir ileti böler. Alıcı, paketi aldığını kabul etmelidir. Alıcı, belirli bir süre zarfında paketi aldığını kabul etmezse, aynı paketi tekrar gönderen bir TCP yeniden aktarımı gerçekleşir. Bu birkaç kez daha gerçekleşirse gönderen pes eder ve bağlantıyı öldürür.

  • HTTP zaman aşımı: Bir tarayıcı gibi bir HTTP istemcisi veya istemci gibi davranırken sunucu (örneğin: diğer HTTP sunucularına istek gönderme), keyfi bir zaman aşımı ayarlayabilirsiniz. Bu süre içinde bir cevap alınmazsa, bağlantı kesilir ve zaman aşımı olarak adlandırılır.

Şimdi, daha az önemsiz daha önemsiz gelen ... Bunun için birçok, birçok olası nedeni vardır:

  • Yanlış İçerik-Uzunluk hesaplama: Bir ile bir istek gönderirseniz Content-Length: 20 başlığı, "Size 20 bayt göndereceğim" anlamına gelir. 19 gönderirseniz, diğer son kalan 1 için bekleyecektir. Bu çok uzun sürerse ... zaman aşımı.

  • Yeterli altyapı yok: Belki uygulamanıza daha fazla makine atamalısınız. (total load/# of CPU cores) 1'in üzerindeyse veya bellek kullanımınız yüksekse, sisteminiz kapasite üzerinde olabilir. Ancak okumaya devam et ...

  • Sessiz istisna: Bir hata atıldı ancak hiçbir yerde oturum açılmadı. İstek, bir sonraki öğeye götüren işlemeyi tamamlamadı.

  • Kaynak sızıntıları: Her isteğin tamamlanmaya kadar ele alınması gerekir. Bunu yapmazsanız, bağlantı açık kalacaktır. Buna ek olarak, IncomingMesage nesnesi (aka: genellikle ifade kodunda req olarak adlandırılır) diğer nesneler tarafından referans olarak gösterilecektir (ör: ifade kendini). Bu nesnelerin her biri çok fazla bellek kullanabilir.

  • Düğüm olay döngüsü açlığı: Sonuna ulaşacağım.

bellek sızıntılar için

semptomlar olacaktır: düğüm işleminin bellek artan bir miktarı kullanılarak olacaktır.

Bazı şeyleri daha kötü duruma getirmek için, kullanılabilir bellek azsa ve sunucunuz takas kullanmak için yanlış yapılandırılmışsa, Linux belleği çok fazla I/O ve CPU yoğun olan diske (takas) taşımaya başlayacaktır. Sunucular etkinleştirilmiş olmalıdır.

cat /proc/sys/vm/swappiness 

size sisteminizde yapılandırılmış swappiness seviyesini dönecektir (0 ile 100 gider). Sen /etc/sysctl.conf yoluyla kalıcı bir şekilde değiştirmeye (yeniden gerektirir) veya uçucu bir şekilde kullanarak yapabilirsiniz: sysctl vm.swappiness=10 Eğer bir bellek sızıntısı var oluşturduktan sonra

, bir çekirdek dökümü almak ve analiz için indirmek gerekir. Bunu yapmanın bir yolu, diğer Stackoverflow yanıtında bulunabilir: Bağlantı sızıntıları için (bir bağlantıyı tamamlanma isteğiyle taşımadıysanız), sunucunuza artan sayıda bağlantı kurmuş olursunuz. Kurulmuş bağlantıları kontrol etmek için netstat -a -p tcp | grep ESTABLISHED | wc -l ile kurulan bağlantılarınızı kontrol edebilirsiniz.

Şimdi olay döngü açlık kötü sorundur. Kısa ömürlü kod kodunuz çok iyi çalışıyorsa. Ancak, CPU yoğun şeyler yaparsanız ve CPU'yu çok uzun süre meşgul eden bir işleviniz varsa ... 50 ms (50 ms katı, engelleme, senkronize CPU zamanı, 50 ms alarak eşzamanlı olmayan kod), işlemler HTTP isteklerinin işlenmesi gibi olay döngüsü tarafından ele alınan, geride kalmaya ve sonuçta zaman aşımına uğramaya başlar.

Bir CPU darboğaz bulmanın yolu bir performans profiler kullanıyor. nodegrind/qcachegrind tercih ettiğim profil oluşturma araçlarımdır, ancak diğerleri alev işaretlerini ve benzerlerini tercih eder. Bununla birlikte, üretimde bir profiler çalıştırmak zor olabilir. Sadece bir geliştirme sunucusu alın ve isteklerle çarpın. aka: bir yük testi. Bunun için birçok araç var.


Son olarak, sorunu hata ayıklamak için başka bir yoludur:

env NODE_DEBUG=tls,net node <...arguments for your app>

düğüm NODE_DEBUG ortam değişkeni aracılığıyla etkinleştirilen opsiyonel ayıklama ifadeleri vardır. NODE_DEBUG'un tls,net'a ayarlanması, düğümü tls ve net modüller için hata ayıklama bilgisi verir ... böylece temel olarak gönderilen veya alınan her şey. Bir zaman aşımı varsa, nereden geldiğini göreceksiniz.

Kaynak: yıllardır düğüm hizmetlerinin büyük dağıtımları sürdürmenin deneyimi.