İletileri çeşitli hizmetler yoluyla işleriz (bir ileti, her biri belirli bir G / Ç ile ilgili işlevi yerine getirmeden önce muhtemelen 9 hizmete dokunacaktır). Şu anda performans için en kötü durum (XML veri sözleşmesi serileştirme) ve en iyi durum (bellek içi MSMQ) kombinasyonuna sahibiz.
Mesajın doğası, serileştirilmiş verilerimizin yaklaşık 12-15 kilobayt olduğu anlamına geliyor ve haftada yaklaşık 4 milyon mesaj işliyoruz. MSMQ'daki kalıcı mesajlar bizim için çok yavaştı ve veriler büyüdükçe MSMQ'nun bellek eşlemeli dosyalarından gelen baskıyı hissediyoruz. Sunucu sadece kuyruk için 16 GB bellek kullanımı ve büyüyor. Makine değişmeye başladığı için bellek kullanımı yüksek olduğunda da performans düşer. Zaten MSMQ kendi kendini temizleme davranışı yapıyoruz.
Burada yanlış yaptığımız bir kısım varmış gibi hissediyorum. Mesajları devam ettirmek ve sadece bir tanımlayıcıyı sıraya koymak için RavenDB'yi kullanmayı denedim, ancak performans çok yavaştı (en iyi dakikada 1000 mesaj). Bunun geliştirme sürümünü veya neyi kullanmanın bir sonucu olup olmadığından emin değilim, ancak kesinlikle daha yüksek bir verime ihtiyacımız var [1]. Kavram teoride çok işe yaradı, ancak performans bu görevi yerine getirmedi.
Kullanım modelinin, tüm okumaları yapan bir yönlendirici gibi davranan bir servisi vardır. Diğer hizmetler 3. taraf kancalarına göre bilgi ekler ve yönlendiriciye iletir. Çoğu nesneye 9-12 kez dokunulur, ancak yaklaşık% 10'unun 3. taraflar uygun şekilde yanıt verene kadar bir süre bu sistemde dolaşmaya zorlanır. Hizmetler şu anda bunu açıklıyor ve bu nedenle mesajın öncelik alanını kullandığımız için uygun uyku davranışlarına sahipler.
Benim sorum, bir C # / Windows ortamında ayrık ama LAN'ed makineleri arasında iletmek için ideal bir yığın nedir? Normalde XML serileştirme yerine BinaryFormatter ile başlıyorum, ancak daha iyi bir yol serileştirmeyi bir belge deposuna boşaltmaksa bu bir tavşan deliği. Dolayısıyla sorum.
[1]: İşimizin doğası, mesajları ne kadar erken işleme koyarsak o kadar çok para kazanmamız anlamına gelir. Haftanın ilerleyen saatlerinde bir mesajın işlenmesinin bu parayı kazanma olasılığımızın daha düşük olduğu anlamına geldiğini ampirik olarak kanıtladık. "Dakikada 1000" performansı oldukça hızlı görünse de, bu rakamı 10k / dakikadan daha fazla artırmamız gerekiyor. Haftalık mesajlarda rakam verdiğim için, bu mesajları işlemek için bir haftamız olduğu anlamına gelmez.
=============== düzenlemek:
Ek bilgi
Yorumlara dayanarak, biraz açıklama ekleyeceğim:
Serileştirmenin bizim darboğazımız olduğundan emin değilim. Uygulamayı karşılaştırdım ve serileştirme ısı grafiğinde görünmesine rağmen, hizmetin CPU kullanımının sadece% 2.5-3'ünden sorumlu.
Çoğunlukla mesajlarımızın kalıcılığı ve MSMQ'nun olası kötüye kullanımı konusunda endişeliyim. İşlemsel olmayan, kalıcı olmayan mesajlar kullanıyoruz, böylece kuyruk performansını yükseltmeye devam edebiliyoruz ve gerçekten en azından kalıcı mesajlara sahip olmak istiyorum, böylece yeniden başlatmadan sağ kalsınlar.
Daha fazla RAM eklemek bir stopgap ölçümüdür. Makine zaten 4GB -> 16GB RAM'den gitti ve daha fazla eklemeye devam etmek için onu aşağı çekmek zorlaşıyor.
Uygulamanın yıldız yönlendirme modeli nedeniyle, bir nesnenin açıldığı sürenin yarısı kadar sonra hiç değişmediği bir kuyruğa itilir. Bu, kendisini (IMO) başka bir yerde bir tür anahtar / değer deposunda depolamaya ve sadece mesaj tanımlayıcılarını geçirmeye borç verir.
Yıldız yönlendirme modeli uygulamanın ayrılmaz bir parçasıdır ve değişmez. Uygulamaya merkezileştiremeyiz çünkü yol boyunca her parça eşzamansız (yoklama şeklinde) çalışır ve yeniden deneme davranışını tek bir yerde merkezileştirmek isteriz.
Uygulama mantığı C # ile yazılmıştır, nesneler değişmez POCO'lardır, hedef dağıtım ortamı Windows Server 2012'dir ve belirli bir yazılım parçası yalnızca Linux'ta destekleniyorsa ek makineler üretmemize izin verilir.
Hedeflerim, bellek ayak izini azaltırken ve minimum sermaye harcamasıyla hata toleransını arttırırken mevcut verimliliği korumaktır.