จุดประสงค์ของการ จำกัด ปัจจุบันคือการปกป้องระบบโดย จำกัด ความเร็วของการเข้าถึง/คำขอพร้อมกันหรือ จำกัด ความเร็วของคำขอภายในหน้าต่างเวลา เมื่อถึงอัตราการ จำกัด การบริการสามารถปฏิเสธได้
ไม่กี่วันที่ผ่านมาฉันอ่านแผนการใช้ Guawa เพื่อให้ได้สตรีมแอปพลิเคชันเดียวที่ จำกัด การอ้างอิง "Redis in Action" เพื่อใช้เวอร์ชันเจไดซึ่งทั้งหมดนี้เป็นข้อ จำกัด ระดับธุรกิจ กลยุทธ์การ จำกัด ปัจจุบันทั่วไปในสถานการณ์จริง:
Nginx Access Layer ขีด จำกัด
ตามกฎบางอย่างเช่นหมายเลขบัญชี IP, ตรรกะการโทรระบบ ฯลฯ เพื่อ จำกัด กระแสไฟฟ้าที่ระดับ Nginx
ระบบแอปพลิเคชันธุรกิจขีด จำกัด ปัจจุบัน
การควบคุมการรับส่งข้อมูลผ่านรหัสธุรกิจการรับส่งข้อมูลนี้สามารถเรียกได้ว่าสัญญาณซึ่งสามารถเข้าใจได้ว่าเป็นล็อคซึ่งสามารถ จำกัด จำนวนกระบวนการที่สามารถเข้าถึงทรัพยากรได้พร้อมกัน
การใช้รหัส
นำเข้า redis.clients.jedis.jedis; นำเข้า redis.clients.jedis.transaction; นำเข้า redis.clients.jedis.zparams; นำเข้า java.util.list; นำเข้า java.util.uuid;/** * @email [email protected] * @data 2017-08 "ถัง"; สตริงสุดท้ายคงที่ส่วนตัว bucket_count = "bucket_count"; สตริงสุดท้ายคงที่ส่วนตัว bucket_monitor = "bucket_monitor"; String String AcquireTokenFrombucket (Jedis Jedis, int ขีด จำกัด , การหมดเวลายาว) {string identifier = uuid.randomuuid (). toString (); Long Now = System.currentTimeMillis (); ธุรกรรมธุรกรรม = jedis.multi (); // ลบ transaction.zremrangebyscore (bucket_monitor.getBytes (), "-inf" .getBytes (), string.valueof (ตอนนี้ - หมดเวลา) .getBytes ()); zparams params = zparams ใหม่ (); params.weightsbyDouble (1.0,0.0); Transaction.zinterstore (bucket, params, bucket, bucket_monitor); // ตอบโต้การทำธุรกรรมการรับรู้ด้วยตนเอง incr (bucket_count); รายการ <jobch> results = transaction.exec (); long counter = (ยาว) ผลลัพธ์ get (results.size () - 1); ธุรกรรม = jedis.multi (); transaction.zadd (bucket_monitor ตอนนี้ตัวระบุ); Transaction.zadd (ถัง, ตัวนับ, ตัวระบุ); Transaction.zrank (ถัง, ตัวระบุ); ผลลัพธ์ = transaction.exec (); // รับการจัดอันดับเพื่อตรวจสอบว่าคำขอได้รับ Semaphore Long Rank = (ยาว) ผลลัพธ์ get (results.size () - 1); ถ้า (อันดับ <จำกัด ) {return identifier; } else {// ไม่ได้รับ semaphore ใส่ลงใน Redis ก่อนทำความสะอาดธุรกรรม = jedis.multi (); Transaction.zrem (bucket_monitor, ตัวระบุ); Transaction.zrem (bucket, identifier); transaction.exec (); } return null; -
เรียก
โทรทดสอบอินเตอร์เฟส
@getMapping ("/") ดัชนีโมฆะสาธารณะ (การตอบสนอง httpservletResponse) โยน ioexception {Jedis jedis = jedispool.getResource (); สตริงโทเค็น = redisratelimiter.acquiretokenfrombucket (Jedis, ขีด จำกัด , หมดเวลา); if (token == null) {response.senderror (500); } else {// toDo ตรรกะทางธุรกิจของคุณ} jedispool.returnresource (Jedis);}การเพิ่มประสิทธิภาพ
เพิ่มประสิทธิภาพรหัสด้วย Interceptor + Annotation
ตัวดักจับ
@ConfigurationStatic Class WebMVCCONFigurer ขยาย WebMVCCONFigurerAdapter {Private Logger Logger = loggerFactory.getLogger (WebMvCconFigurer.class); @autowired Private Jedispool Jedispool; โมฆะสาธารณะ addInterceptors (InterceptorRegistry Registry) {registry.addinterceptor (ใหม่ handlerInterceptorAdapter () {prehandle บูลีนสาธารณะ (httpservletrequest คำขอ httpservletResponse, handloTHOD. ratelimiter ratelimiter = method.getannotation (ratelimiter.class); การหมดเวลา); ถ้าโทเค็น == null) {Response.senderror (500); -คำอธิบายประกอบคำจำกัดความ
/** * @Email [email protected] * @data 2017-08 * คำอธิบายประกอบขีด จำกัด จำกัด ปัจจุบัน */@Target (ElementType.method) @retention (RetentionPolicy.runtime) @DocumentedPublic Int Timeout () ค่าเริ่มต้น 1000;}
ใช้
@RateLimiter (limit = 2, หมดเวลา = 5000) @getMapping ("/test") การทดสอบโมฆะสาธารณะ () {}การทดสอบพร้อมกัน
เครื่องมือ: Apache-Jmeter-3.2
หมายเหตุ: อินเทอร์เฟซที่ไม่ได้รับ Semaphore Returns 500 สถานะเป็นสีแดงอินเตอร์เฟสที่ได้รับ Semaphore returns 200 สถานะเป็นสีเขียว
เมื่อ Semaphore คำขอขีด จำกัด เป็น 2, 5 เธรดจะถูกส่ง:
เมื่อ Semaphore คำขอขีด จำกัด เป็น 5, 10 เธรดจะถูกส่ง:
วัสดุ
การดำเนินการตาม Reids + Lua
สรุป
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น