الغرض من الحد الحالي هو حماية النظام عن طريق الحد من سرعة الوصول/الطلبات المتزامنة أو الحد من سرعة الطلبات خلال نافذة زمنية. بمجرد الوصول إلى معدل الحد ، يمكن رفض الخدمة.
قبل بضعة أيام ، قرأت خطة لاستخدام غواوا لتحقيق الحد من دفق التطبيق الواحد. مرجع "redis in Action" لتنفيذ إصدار Jedis ، وكلها قيود على مستوى الأعمال. استراتيجيات الحد الحالية المشتركة في السيناريوهات الفعلية:
الحد الحالي لطبقة الوصول إلى NGINX
وفقًا لبعض القواعد ، مثل رقم الحساب ، IP ، منطق استدعاء النظام ، إلخ ، للحد من التيار على مستوى Nginx
الحد الحالي لنظام تطبيق الأعمال
التحكم في حركة المرور من خلال رمز العمل ، يمكن تسمية حركة المرور هذه بأنها semaphore ، والتي يمكن فهمها على أنها قفل ، والذي يمكن أن يحد من عدد العمليات التي يمكن الوصول إليها في وقت واحد.
تنفيذ الكود
redis.clients.jedis.jedis ؛ import redis.clients.jedis.transaction ؛ import redis.jedis.zparams ؛ import java.util.list ؛ import java.util.uuid ؛/** * @email wangiegie.com * @data 2017-08 * "دلو" ؛ Static Final String Bucket_Count = "Bucket_Count" ؛ Static Final String Bucket_Monitor = "Bucket_Monitor" ؛ Static String AcquiretokenFrombucket (Jedis Jedis ، int limit ، ant timeout) {string identifier = uuid.randomuuid (). toString () ؛ طويل الآن = system.currentTimeMillis () ؛ معاملة المعاملة = jedis.multi () ؛ // حذف Semaphore Transaction.zreMrangeByScore (bucket_monitor.getbytes () ، "-inf" .getBytes () ، string.valueof (الآن - timeout) .getBytes ()) ؛ Zparams params = new Zparams () ؛ params.weightsbydouble (1.0،0.0) ؛ المعاملة. // Counter Self-Increment Transaction.incr (bucket_count) ؛ قائمة <Bound> النتائج = المعاملة. Exec () ؛ عداد طويل = (طويل) نتائج (النتائج. size () - 1) ؛ المعاملة = jedis.multi () ؛ Transaction.zadd (bucket_monitor ، الآن ، معرف) ؛ Transaction.zadd (دلو ، عداد ، معرف) ؛ Transaction.Zrank (دلو ، معرف) ؛ النتائج = المعاملة. Exec () ؛ // احصل على الترتيب لتحديد ما إذا كان الطلب قد حصل على رتبة Semaphore الطويلة = (طويلة) Results.get (Results.size () - 1) ؛ if (رتبة <limit) {return Identifier ؛ } آخر {// لم يتم الحصول على أي إشارة ، وضعت في redis قبل تنظيف المعاملة = jedis.multi () ؛ المعاملة. المعاملة. zrem (دلو ، معرف) ؛ Transaction.exec () ؛ } إرجاع فارغ ؛ }}يتصل
اختبار واجهة الاتصال
essmapping ("/") مؤشر الفراغ العام (استجابة httpservletresponse) يلقي ioException {jedis jedis = jedispool.getResource () ؛ TRING TOKEN = REDISRATELIMITER.ACquiretokenFrombucket (Jedis ، LIMIT ، TIMEOUT) ؛ if (token == null) {response.senderror (500) ؛ } آخر {// todo logic} jedispool.returnresource (jedis) ؛}تحسين
تحسين الرمز مع Interceptor + التعليق التوضيحي
اعتراض
ConfigurationStatic Class WebMVCConfigurer يمتد WebMVCConfigurerAdapter {private logger logger = loggerfactory.getLogger (WebMVCConfigurer.class) ؛ @Autowired Jedispool Jedispool ؛ public void addInterceptors (interceptorregistry registry) {registry.addInterceptor (New HandlerInterceptorAdapter () {public boolean prehandle (httpservletRequest request ، httpservletresponse ، methide ، methodly {handlermethod handlermethod = handlermethod) ؛ ratelimiter = method.getannotation (ratelimiter.class) ؛ (الرمز المميز == null) {response.senderror (500) ؛ }}التعليق التعليق
/** * eMail [email protected] * data 2017-08 * التعليقات التوضيحية الحالية الحالية */@target (elementType.method)@repinenting (attreentionpolicy.runtime) documentedpublic interface ratelimiter {int limit () default 5 ؛ int timeout () الافتراضي 1000 ؛}
يستخدم
@ratelimiter (limit = 2 ، timeout = 5000) getMapping ("/test") اختبار الفراغ العام () {}الاختبار المتزامن
الأدوات: Apache-Jmeter-3.2
ملاحظة: الواجهة التي لم تحصل على إرجاع Semaphore 500 ، الحالة حمراء ، الواجهة التي حصلت على إرجاع Semaphore 200 ، الحالة خضراء.
عندما يكون Semaphore طلب الحد هو 2 ، يتم إرسال 5 مؤشرات ترابط:
عندما يكون Simaphore طلب الحد هو 5 ، يتم إرسال 10 مؤشرات ترابط:
مادة
التنفيذ على أساس REIDS + LUA
لخص
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.