özet
Yüksek eşzamanlı erişimle büyük miktarda veriye erişildiğinde, hizmetler veya arayüzler, artan talepler karşısında genellikle kullanılamaz hale gelir ve hatta zincir reaksiyonlarını tetikleyerek tüm sistemin çökmesine neden olur. Şu anda kullanmanız gereken teknik yöntemlerden biri mevcut sınırlamadır.İstek belirli bir sayıya veya eşzamanlılık oranına ulaştığında, bekle, sıraya koy, düşür, hizmet reddi vb.
Yüksek eşzamanlı sistemler geliştirirken sistemi korumak için üç keskin araç vardır: önbelleğe alma, sürüm düşürme ve akım sınırlama.
Önbellek
Önbelleğin anlaşılması daha kolaydır Büyük, yüksek eşzamanlı bir sistemde, önbellek veritabanı yoksa, her dakika patlar ve sistem anında felç olur. Önbelleğe alma, yalnızca sistem erişim hızını ve eşzamanlı erişim miktarını artırmakla kalmaz, aynı zamanda veritabanını ve sistemi korumanın etkili bir yoludur. Büyük ölçekli web siteleri genellikle "okunur" ve önbellek kullanımı düşünmek kolaydır. Büyük ölçekli "yazma" sistemlerinde, önbellekler genellikle çok önemli bir rol oynar. Örneğin, bazı veriler gruplar halinde toplanır, bellekteki önbellek kuyruğu (üretim ve tüketim) ve HBase'in veri yazma mekanizması, vb. De sistemin verimini artırmak veya önbellek aracılığıyla sistem koruma önlemlerini uygulamak için kullanılır. Mesaj ara yazılımı bile, onu dağıtılmış bir veri önbelleği olarak da düşünebilirsiniz.
Eski sürüme geç
Hizmet bozulması, çekirdek görevlerin normal çalışmasını sağlamak için sunucu kaynaklarını serbest bırakmak için sunucu baskısı keskin bir şekilde arttığında mevcut iş koşullarına ve trafik akışına dayalı olarak bazı hizmetlerin ve sayfaların stratejik olarak bozulmasını ifade eder. Düşürmeler genellikle farklı seviyeleri belirtir ve farklı anormal seviyeler için farklı işlemler gerçekleştirir. Servis yöntemine göre: Servis reddedilebilir, servis geciktirilebilir ve bazen servis rastgele olabilir. Hizmetin kapsamına göre: belirli bir işlevi veya bazı modülleri kesebilirsiniz. Kısacası, hizmet bozulması, farklı iş gereksinimlerine göre farklı bozunma stratejileri gerektirir. Temel amaç, hizmetin zarar görmesine rağmen, hiç yoktan iyidir.
Sınırlayıcı
Akım sınırlaması bir tür hizmet bozulması olarak kabul edilebilir Akım sınırlaması, sistemi koruma amacına ulaşmak için sistemin giriş ve çıkış trafiğini sınırlandırmaktır. Genel olarak, sistemin verimi ölçülebilir Sistemin kararlı çalışmasını sağlamak için, sınırlandırılması gereken eşiğe ulaşıldığında, akışı kısıtlamak ve akışı kısıtlama amacına ulaşmak için bazı önlemler almak gerekir. Örneğin: gecikmeli işleme, ret işleme veya kısmi ret işleme vb.
Mevcut sınırlama algoritması
Jeton Kovası, sızdıran paket ve sayaç algoritmaları, akım sınırlaması için en yaygın kullanılan üç algoritmadır.
Karşı akım sınırlama algoritması da daha yaygın olarak kullanılır, temelde veritabanı bağlantı havuzu boyutu, iş parçacığı havuzu boyutu, program erişim eşzamanlılığı vb. Gibi toplam eşzamanlılık sayısını sınırlamak için kullanılır, hepsi sayaç algoritmasını kullanır. Aynı zamanda en basit ve kaba algoritmadır.
Sayaç akım sınırı örnek 1'i kullanın:
public class CountRateLimiterDemo { private static AtomicInteger sayısı = new AtomicInteger (0); public static void exec () { eğer (count.get () > = 5) { System.out.println ("Çok fazla kullanıcı talep ediyor, lütfen daha sonra deneyin!" + System.currentTimeMillis () / 1000); } Başka { count.incrementAndGet (); Deneyin { // Temel mantığı işleyin TimeUnit.SECONDS.sleep (1); System.out.println ("-" + System.currentTimeMillis () / 1000); } catch (InterruptedException e) { e.printStackTrace (); } en sonunda { count.decrementAndGet (); } } } }Halihazırda yürütülmekte olan eşzamanlı yürütme sayısını saymak için AomicInteger kullanın. Eşiği aşarsa, basit ve kaba bir şekilde doğrudan kullanıcıya yanıt vererek sistemin meşgul olduğunu belirtir, lütfen daha sonra tekrar deneyin veya işle ilgili diğer bilgiler.
Dezavantajlar: İsteği reddetme eşiğini basit ve kaba bir şekilde aşmak için AomicInteger kullanın. Anlık istek hacmi yüksek olabilir ve istek reddedilebilir.
Sayaç akım sınırı örnek 2'yi kullanın
public class CountRateLimiterDemo { özel statik Semafor semfor = yeni Semafor (50); public static void exec () { eğer (semphore.getQueueLength () > 100){ System.out.println ("Şu anda kuyrukta bekleyen görevlerin sayısı 100'den fazla, lütfen daha sonra tekrar deneyin ..."); } Deneyin { semphore.acquire (); // Temel mantığı işleme TimeUnit.SECONDS.sleep (1); System.out.println ("-" + System.currentTimeMillis () / 1000); } catch (InterruptedException e) { e.printStackTrace (); } en sonunda { semphore.release (); } } }Semafor semafor, eşzamanlı yürütme sayısını kontrol etmek için kullanılır.Eğer eşik semaforu aşılırsa, bloklama kuyruğuna girer ve semaforun yürütülmesini bekler. Engelleme kuyruğunda, sistemin işleme kapasitesinin ötesinde çok fazla istek kuyruğa alınırsa, istekler reddedilebilir.
Göreceli Atomik avantajları: Anlık yüksek eşzamanlılık ise, istek, trafiğin tepe noktasını azaltma amacına ulaşmak için isteği hemen reddetmek yerine engelleme kuyruğunda sıraya alınabilir.
Guava RateLimiter akım sınırlamasını kullanan Örnek 3
Guava'daki açık kaynak araç sınıfı RateLimiter, mevcut sınırlayıcı çalışmayı basitçe uygulayabilen ve jeton oluşturma oranını sistemin gerçek durumuna göre ayarlayabilen jeton kovası algoritmasına dayalı bir uygulama sınıfıdır. RateLimiter, basit belirteç kovası algoritması üzerinde bazı mühendislik optimizasyonları yaptı ve özel uygulama SmoothBursty. RateLimiter'ın başka bir uygulaması olan SmoothWarmingUp'ın bir jeton kovası değil, sızdıran bir kova algoritması olduğuna dikkat edilmelidir. Belki basitlik uğruna, RateLimiter'daki zaman penceresi sadece 1s olabilir ve olabilir.Akımı diğer zaman birimleriyle sınırlamak istiyorsanız, yalnızca tekerlekler oluşturabilirsiniz.
RateLimiter'ın ilginç bir özelliği, "öncekiler çukurları kazıyor ve sonra zıplıyor", yani RateLimiter, kalan jeton sayısını aşan jetonları almak için belirli bir talebe izin veriyor, ancak bir sonraki talep jetona kadar bunu ödeyecek Eksiklik dolduruldu ve kovada bu istek için yeterli sayıda jeton var. Bu, bir önceki isteğin belirtecin gitmesi için yeterli olana kadar beklemesine veya devam etmesine ve sonraki isteği beklemesine izin vermeyi içerir. Guava'nın tasarımcısı ikincisini seçti ve ilk önce acil işi yaptı ve ikincisi hakkında konuştu.
RateLimiter rateLimiter = RateLimiter.create (2);
System.out.println (rateLimiter.acquire (5));
System.out.println (rateLimiter.acquire (2));
System.out.println (rateLimiter.acquire (1));
Çıktı
0.0
2.496889
0.992149
Token kovasının saniyede sadece 2 jeton üretebildiği görülüyor.İlk defa 5 jeton çıkarabiliriz, ancak jetonları ikinci kez aldığımızda ilk jeton olan 2,5 saniye beklememiz gerekiyor. Jetonu aldıktan sonra, jetonu almak için 2,5 saniye beklemeniz gerekir. Benzer şekilde, 1 jetonu üçüncü kez alırken, ikinci kez 1 saniye beklemeniz gerekir. Yani, getirme oranı jeton oluşturma oranını aşabilir, ancak bir dahaki sefere tekrar getirdiğinizde, engellemeniz ve beklemeniz gerekir.
Elbette tryAcquire, engellemeyen edinimler elde etmek için de kullanılabilir ve sonuçlar gerçek zamanlı olarak döndürülebilir. Ek olarak, tryAcquire bekleme süresi olan parametreleri de geçirebilir ve fazla mesai durumunda doğrudan yanlış döndürebilir. Bu, ortak kilitle eşdeğerdir, tryLock.
Sızdıran kova algoritması
Sızdıran kova algoritması veya sızdıran kova, trafik şekillendirme (Trafik Şekillendirme) ve trafik kontrolünü (Trafik Politikası) uygulamak için kullanılabilen çok yaygın olarak kullanılan bir akım sınırlama algoritmasıdır. Herkesin anlamasına yardımcı olmak için şematik bir diyagram yayınladım:
Sızdıran kova algoritmasının ana kavramları aşağıdaki gibidir:
Temel amacı, ağa veri enjeksiyon oranını kontrol etmek, ağdaki yoğun trafiği düzeltmektir ve veriler, herhangi bir hızda sızdıran kovaya akabilir. Sızdıran kova algoritması, ağ için kararlı bir akış sağlamak üzere ani trafiğin şekillendirilebileceği bir mekanizma sağlar. Sızdıran kova, sabit hizmet süresine sahip tek sunuculu bir sıra olarak kabul edilebilir. Sızdıran kova boşsa, su damlacıklarının dışarı akmasına gerek yoktur. Sızdıran kova (paket tampon) taşarsa, su damlacıkları taşar ve atılır.
Sızdıran kova algoritmasının uygulanması daha iyidir. Kuyruklar kullanılarak tek makineli bir sistemde uygulanabilir. Dağıtılmış bir ortamda, ileti ara yazılımı veya Redis isteğe bağlı çözümlerdir.
Jeton grubu algoritması
Jeton paketi algoritmasının prensibi, sistemin jetonları pakete sabit bir oranda koyması ve isteğin işlenmesi gerekiyorsa önce paketten bir jeton alması gerektiğidir. Paket içinde jeton yoksa, o zaman Hizmet reddi. Paket dolduğunda, yeni eklenen jeton atılır veya reddedilir.
Jeton paketi algoritması, sabit kapasiteli bir jeton (jeton) depolayan bir gruptur ve jetonlar, gruba sabit bir oranda eklenir. Jeton grubu algoritması temel olarak aşağıdaki kavramlarla açıklanabilir:
Belirteç algoritması, jetonun koyulduğu hıza göre çıktı hızını kontrol eder, bu, yukarıdaki şekilde ağa olan hızdır. Ağa, belirli bir işi yürüten veya belirli bir RPC'yi çağıran bir mesaj işleme programı olarak anlaşılabilir.
Sızdıran kova ve jeton kovasının karşılaştırılması
Jeton paketi, çalışma süresi sırasında veri işleme hızını kontrol edip ayarlayabilir ve belirli bir zamanda anlık trafiği işleyebilir. Belirteç yayınlama sıklığındaki artış, genel veri işleme hızını artırabilir ve her seferinde elde edilen jeton sayısı, jeton verme hızını artırabilir veya yavaşlatabilir ve genel veri işleme hızını azaltabilir. Sızdıran kova çalışmaz, çünkü çıkış hızı sabittir ve program işleme hızı da sabittir.
Genel olarak belirteç paketi algoritması daha iyidir, ancak uygulama daha karmaşıktır.
Aşağıda, dağıtılmış bir akım sınırlama sistemi uygulamak için guava's RateLimiter ve redis'in kullanımı ayrıntılı olarak tanıtılacaktır.