दिलचस्प पोस्ट
अजीब प्रयास -अनुरोध-शेष-अंतराल वापसी के साथ व्यवहार एपीआई स्तर 4 पर है या नहीं, यह कैसे पता लगा सकता है कि स्क्रीन चालू है या बंद है? ब्लैकबेरी में एचटीपी पोस्ट विश्व स्तर पर निर्देशों और घटकों को उपलब्ध कैसे करें एक numpy.timedelta64 मान से दिन निकालने एक HTML लिंक से URL को निकालने के लिए नियमित अभिव्यक्ति क्या C # समर्थन प्रोजेक्ट-वाइड डिफ़ॉल्ट नेमस्पेस VB.NET जैसे आयात करता है? रेल 3 में सत्र का समय समाप्त करना कैसे PHP में स्कैंडर का उपयोग केवल छवियों को पाने के लिए? Jsonp POST अनुरोध बनाने के लिए कैसे jQuery के साथ contentType निर्दिष्ट करता है? Django कस्टम फॉर्म पैरामीटर फॉर्मसेट को पास करना संगतता: सी ++ 11 मेमोरी मॉडल में परमाणु और अस्थिर पीडीएफ फाइलों से पाठ डेटा को निकालना जावा में तरीके बनाम कन्स्ट्रक्टर्स क्या अंतर्निहित प्रकार डिफ़ॉल्ट कन्स्ट्रक्टर हैं?

थ्रॉटलिंग विधि एन सेकंड में एम अनुरोधों को कॉल करता है

मुझे एक घटक / वर्ग की आवश्यकता है जो कुछ विधि के थ्रॉटल निष्पादन को अधिकतम सेकेंड एन सेकेंड (या एमएस या नैनो में कोई फर्क नहीं पड़ता) में कॉल करता है।

दूसरे शब्दों में मुझे यह सुनिश्चित करने की ज़रूरत है कि मेरी पद्धति N सेकंड के स्लाइडिंग विंडो में एम बार से अधिक नहीं निष्पादित की गई है।

यदि आपको नहीं पता है कि मौजूदा क्लास अपने समाधान / विचारों को पोस्ट करने के लिए स्वतंत्र है कि आप इसे कैसे लागू करेंगे।

Solutions Collecting From Web of "थ्रॉटलिंग विधि एन सेकंड में एम अनुरोधों को कॉल करता है"

मैं एम के एक निश्चित आकार के साथ टाइमस्टैम्प का एक अंगूठी बफर का उपयोग करता हूं। हर बार विधि को बुलाया जाता है, आप सबसे पुरानी प्रविष्टि जांचते हैं, और अगर यह अतीत में एन सेकेंड से कम है, तो आप निष्पादित और दूसरी प्रविष्टि जोड़ते हैं, अन्यथा आप सोते हैं समय के अंतर के लिए

मेरे लिए बॉक्स के बाहर क्या काम किया गया था Google Guava RateLimiter

// Allow one request per second private RateLimiter throttle = RateLimiter.create(1.0); private void someMethod() { throttle.acquire(); // Do something } 

ठोस शब्दों में, आप इसे DelayQueue साथ लागू करने में सक्षम होना चाहिए। M Delayed उदाहरणों के साथ कतार को शुरू करने के साथ-साथ शुरुआत में शून्य पर सेट किया गया। विधि में आने के अनुरोध के रूप में, एक टोकन take , जिससे थ्रॉटलिंग की आवश्यकता पूरी होने तक विधि अवरुद्ध हो जाती है। जब एक टोकन लिया गया है, तो N देरी के साथ कतार में एक नया टोकन add

टोकन बाल्टी एल्गोरिथ्म पर पढ़ें असल में, आपके पास टोकन में एक बाल्टी है हर बार जब आप विधि निष्पादित करते हैं, तो आप टोकन लेते हैं। यदि कोई और टोकन नहीं हैं, तो आप एक को प्राप्त होने तक ब्लॉक करते हैं इस बीच, कुछ बाहरी अभिनेता है जो एक निश्चित अंतराल पर टोकन की प्रतिपूर्ति करता है।

मुझे ऐसा करने के लिए एक पुस्तकालय के बारे में पता नहीं है (या ऐसा कुछ भी) आप इस तर्क को अपने कोड में लिख सकते हैं या व्यवहार जोड़ सकते हैं।

यह आवेदन में निर्भर करता है।

इस मामले की कल्पना करें जिसमें एकाधिक थ्रेड किसी टोकन के साथ कुछ विश्वव्यापी दर-सीमित कार्रवाई करने की अनुमति नहीं देता है (यानी आप प्रति 10 सेकंड में 10 कार्रवाइयां सीमित करना चाहते हैं, लेकिन आप पहले चरण में 10 कार्य नहीं करना चाहते हैं और फिर रहें 9 सेकंड बंद)

विलंबित प्रश्न का एक नुकसान होता है: आदेश जिस पर धागे टोकन का अनुरोध करते हैं, वह ऑर्डर नहीं हो सकता, जिस पर उनका अनुरोध पूरा हो जाता है। अगर एक से अधिक धागे टोकन के लिए प्रतीक्षा कर रहे हैं, तो यह स्पष्ट नहीं है कि कौन सा अगले उपलब्ध टोकन ले जाएगा। आपके पास थ्रेड्स हमेशा के लिए इंतज़ार कर सकते हैं, मेरी दृष्टि में

एक समाधान के लिए दो लगातार कार्रवाई के बीच समय का न्यूनतम अंतराल होना चाहिए , और उसी क्रम में कार्रवाई करना चाहिए , जैसा कि वे अनुरोध किया गया था।

यहां एक कार्यान्वयन है:

 public class LeakyBucket { protected float maxRate; protected long minTime; //holds time of last action (past or future!) protected long lastSchedAction = System.currentTimeMillis(); public LeakyBucket(float maxRate) throws Exception { if(maxRate <= 0.0f) { throw new Exception("Invalid rate"); } this.maxRate = maxRate; this.minTime = (long)(1000.0f / maxRate); } public void consume() throws InterruptedException { long curTime = System.currentTimeMillis(); long timeLeft; //calculate when can we do the action synchronized(this) { timeLeft = lastSchedAction + minTime - curTime; if(timeLeft > 0) { lastSchedAction += minTime; } else { lastSchedAction = curTime; } } //If needed, wait for our time if(timeLeft <= 0) { return; } else { Thread.sleep(timeLeft); } } } 

यद्यपि आप ने यह नहीं पूछा है, ThreadPoolExecutor , जो कि एम के साथ-साथ अनुरोध करने के लिए डिज़ाइन किया गया है, N सेकेंड में मी अनुरोधों के बजाय भी उपयोगी हो सकता है।

मुझे यह सुनिश्चित करने की ज़रूरत है कि मेरी विधि N सेकंडों की स्लाइडिंग विंडो में M बार से अधिक नहीं निष्पादित की गई है।

मैंने हाल ही में एक ब्लॉग पोस्ट लिखा है कि यह कैसे करें .नेट में करना है आप जावा में कुछ समान बना सकते हैं।

एनएटी [पेनेटेड ऑब्जेक्ट्स] में बेहतर दर सीमित

यदि आपको एक जावा आधारित स्लाइडिंग विंडो रेट सीमक की जरूरत है जो एक वितरित सिस्टम में काम करेगा तो आप https://github.com/mokies/ratelimitj प्रोजेक्ट पर एक नज़र रखना चाहेंगे।

आईपी ​​से 50 प्रति मिनट के अनुरोधों को सीमित करने के लिए एक Redis बैकड कॉन्फ़िगरेशन, इस तरह दिखेगा:

 import com.lambdaworks.redis.RedisClient; import es.moki.ratelimitj.core.LimitRule; RedisClient client = RedisClient.create("redis://localhost"); Set<LimitRule> rules = Collections.singleton(LimitRule.of(1, TimeUnit.MINUTES, 50)); // 50 request per minute, per key RedisRateLimit requestRateLimiter = new RedisRateLimit(client, rules); boolean overLimit = requestRateLimiter.overLimit("ip:127.0.0.2"); 

Redis कॉन्फ़िगरेशन पर अधिक जानकारी के लिए https://github.com/mokies/ratelimitj/tree/master/ratelimitj-redis देखें।

मूल प्रश्न इस ब्लॉग पोस्ट में हल की तरह बहुत लगता है: जावा मल्टी-चैनल असिंक्रोनस थॉटलर

एन सेकेंड में एम कॉल की दर के लिए, इस ब्लॉग में चर्चा करने वाले थ्रॉटलर की गारंटी देता है कि टाइमलाइन पर लंबाई एन के किसी भी अंतराल में एम कॉल्स नहीं होंगे।

मैंने एक सरल थ्रॉटलिंग एल्गोरिथम लागू किया है। इस लिंक को देखें, http://krishnaprasadas.blogspot.in/2012/05/throttling-algorithm.html

एल्गोरिथ्म के बारे में संक्षिप्त,

यह एल्गोरिथम जावा विलंबित कतार की क्षमता का उपयोग करता है। अपेक्षित विलंब के साथ एक विलंबित ऑब्जेक्ट बनाएं (यहां 1000 / एम मिलीसेकंड टाइम यूनिट के लिए ) उसी ऑब्जेक्ट को देरी हुई कतार में रखें जो प्रशिक्षु हमारे लिए चलती विंडो प्रदान करेगी। फिर प्रत्येक विधि कॉल से पहले ऑब्जेक्ट को कतार में लेते हैं, ले लो एक अवरुद्ध कॉल है जो केवल निर्दिष्ट विलंब के बाद ही लौटाएगा, और विधि कॉल के बाद ऑब्जेक्ट को अद्यतन समय के साथ कतार में (यहां वर्तमान मिलिसेकंड्स) ।

यहां हमारे पास अलग-अलग विलंब के साथ कई देरी वाली वस्तुएं भी हो सकती हैं। यह दृष्टिकोण उच्च थ्रूपुट भी प्रदान करेगा।

इस सरल दृष्टिकोण का उपयोग करने की कोशिश करें:

 public class SimpleThrottler { private static final int T = 1; // min private static final int N = 345; private Lock lock = new ReentrantLock(); private Condition newFrame = lock.newCondition(); private volatile boolean currentFrame = true; public SimpleThrottler() { handleForGate(); } /** * Payload */ private void job() { try { Thread.sleep(Math.abs(ThreadLocalRandom.current().nextLong(12, 98))); } catch (InterruptedException e) { e.printStackTrace(); } System.err.print(" J. "); } public void doJob() throws InterruptedException { lock.lock(); try { while (true) { int count = 0; while (count < N && currentFrame) { job(); count++; } newFrame.await(); currentFrame = true; } } finally { lock.unlock(); } } public void handleForGate() { Thread handler = new Thread(() -> { while (true) { try { Thread.sleep(1 * 900); } catch (InterruptedException e) { e.printStackTrace(); } finally { currentFrame = false; lock.lock(); try { newFrame.signal(); } finally { lock.unlock(); } } } }); handler.start(); } 

}

अपाचे ऊंट का समर्थन करता है थ्रोटलर तंत्र के साथ आता है:

 from("seda:a").throttle(100).asyncDelayed().to("seda:b"); 

वितरित सिस्टम में लॉकिंग की आवश्यकता होने पर आप इसके लिए redis का उपयोग कर सकते हैं। https://redis.io/commands/incr में दूसरा एल्गोरिथ्म

यह ऊपर LeakyBucket कोड के लिए एक अद्यतन है। प्रति सेकेंड 1000 अनुरोधों के लिए यह काम करता है

 import lombok.SneakyThrows; import java.util.concurrent.TimeUnit; class LeakyBucket { private long minTimeNano; // sec / billion private long sched = System.nanoTime(); /** * Create a rate limiter using the leakybucket alg. * @param perSec the number of requests per second */ public LeakyBucket(double perSec) { if (perSec <= 0.0) { throw new RuntimeException("Invalid rate " + perSec); } this.minTimeNano = (long) (1_000_000_000.0 / perSec); } @SneakyThrows public void consume() { long curr = System.nanoTime(); long timeLeft; synchronized (this) { timeLeft = sched - curr + minTimeNano; sched += minTimeNano; } if (timeLeft <= minTimeNano) { return; } TimeUnit.NANOSECONDS.sleep(timeLeft); } } 

और उपरोक्त के लिए एकजुट:

 import com.google.common.base.Stopwatch; import org.junit.Ignore; import org.junit.Test; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; public class LeakyBucketTest { @Test @Ignore public void t() { double numberPerSec = 10000; LeakyBucket b = new LeakyBucket(numberPerSec); Stopwatch w = Stopwatch.createStarted(); IntStream.range(0, (int) (numberPerSec * 5)).parallel().forEach( x -> b.consume()); System.out.printf("%,d ms%n", w.elapsed(TimeUnit.MILLISECONDS)); } } 

[टाइमर टास्क 1 क्लास देखें या अनुसूचित एक्सपोटर