บทความนี้ส่วนใหญ่ศึกษา ratelimit - เนื้อหาที่เกี่ยวข้องของการใช้ guava เพื่อดำเนินการ จำกัด การไหลของอินเทอร์เฟซดังต่อไปนี้
1. คำอธิบายปัญหา
อยู่มาวันหนึ่งนายเอก็พบว่าจำนวนคำขอสำหรับอินเทอร์เฟซของเขาเพิ่มขึ้นเป็น 10 เท่าก่อนหน้านี้ ไม่นานหลังจากนั้นอินเทอร์เฟซแทบจะไม่สามารถใช้งานได้และก่อให้เกิดปฏิกิริยาลูกโซ่ที่ทำให้ระบบทั้งหมดยุบ จะจัดการกับสถานการณ์นี้ได้อย่างไร? ชีวิตให้คำตอบแก่เรา: ตัวอย่างเช่นสวิตช์สมัยเก่าติดตั้งฟิวส์ เมื่อมีคนใช้อุปกรณ์ที่ใช้พลังงานสูงเป็นพิเศษฟิวส์จะถูกเป่าเพื่อป้องกันเครื่องแต่ละเครื่องจากการถูกเผาโดยกระแสที่แข็งแกร่ง ในทำนองเดียวกันอินเทอร์เฟซของเราจะต้องติดตั้งด้วย "ฟิวส์" เพื่อป้องกันการอัมพาตของระบบที่เกิดจากแรงกดดันมากเกินไปในระบบโดยคำขอที่ไม่คาดคิด เมื่อการจราจรมีขนาดใหญ่เกินไปกลไกเช่นการปฏิเสธหรือการระบายน้ำสามารถนำมาใช้
2. อัลกอริทึมการ จำกัด ปัจจุบันที่ใช้กันทั่วไป
มีอัลกอริทึมการ จำกัด ปัจจุบันที่ใช้กันทั่วไปสองประการ: อัลกอริทึมถังรั่วและอัลกอริทึมถังโทเค็น
ความคิดของอัลกอริทึมถังรั่วนั้นง่ายมาก โปรดป้อนถังรั่วก่อน ถังที่รั่วไหลจะออกมาด้วยความเร็วที่แน่นอน เมื่อคำขอน้ำมีขนาดใหญ่เกินไปมันจะล้นโดยตรง จะเห็นได้ว่าอัลกอริทึมที่มีการรั่วไหลสามารถ จำกัด อัตราการส่งข้อมูลได้
รูปที่ 1 แผนผังไดอะแกรมของอัลกอริทึมที่รั่วไหลออกมา
สำหรับสถานการณ์แอปพลิเคชันหลายอย่างนอกเหนือจากความสามารถในการ จำกัด อัตราการส่งข้อมูลโดยเฉลี่ยแล้วยังจำเป็นต้องมีการส่งสัญญาณระเบิดระดับหนึ่ง ในเวลานี้อัลกอริทึมที่รั่วไหลออกมาอาจไม่เหมาะสมและอัลกอริทึมถังโทเค็นนั้นเหมาะสมกว่า ดังที่แสดงในรูปที่ 2 หลักการของอัลกอริทึมถังโทเค็นคือระบบจะใส่โทเค็นลงในถังด้วยความเร็วคงที่ หากคำขอจำเป็นต้องดำเนินการจะต้องได้รับโทเค็นจากถังก่อน เมื่อไม่มีโทเค็นในถังบริการจะถูกปฏิเสธ
รูปที่ 2 แผนผังไดอะแกรมของอัลกอริทึมถังโทเค็น
3. Ratelimiter ในคลาสเครื่องมือ จำกัด ปัจจุบัน
ชุดเครื่องมือโอเพ่นซอร์สของ Google ให้บริการคลาส Ratelimiter ซึ่งขึ้นอยู่กับ "อัลกอริทึม Bucket Token" และสะดวกในการใช้งานมาก สำหรับการใช้งานเฉพาะของอินเทอร์เฟซคลาสนี้โปรดดูการใช้งานการใช้ Ratelimiter
Ratelimiter โดยใช้การสาธิต
แพ็คเกจ ratelimite; นำเข้า com.google.common.util.concurrent.ratelimiter; คลาสสาธารณะ ratelimiterdemo {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {testnoratelimiter (); testwithRatelimiter (); I <10; มีการส่งงานมากกว่า 10 รายการต่อวินาทีสำหรับ (int i = 0; i <10; i ++) {limiter.acquire (); // คำขอ ratelimiter, เกินใบอนุญาตจะถูกบล็อก system.out.println ("เรียกร้องให้ดำเนินการ .. "+i); สี่ Guava Concurrency: ListenableFuture และ Ratelimiter ตัวอย่าง
แนวคิด
ListenableFuture ตามชื่อหมายถึงเป็นอนาคตที่สามารถรับฟังได้มันเป็นการเพิ่มประสิทธิภาพเพิ่มเติมสำหรับอนาคตของ Java Native เรารู้ว่าอนาคตแสดงถึงงานการคำนวณแบบอะซิงโครนัสและผลการคำนวณสามารถรับได้เมื่องานเสร็จสมบูรณ์ หากเราต้องการให้ได้ผลลัพธ์และแสดงให้ผู้ใช้เมื่อการคำนวณเสร็จสมบูรณ์หรือทำการคำนวณอื่น ๆ เราต้องใช้เธรดอื่นเพื่อสอบถามสถานะการคำนวณอย่างต่อเนื่อง สิ่งนี้ทำให้รหัสซับซ้อนและไม่มีประสิทธิภาพ ใช้ Guava ListenableFuture เพื่อช่วยเราตรวจสอบว่าอนาคตจะเสร็จสมบูรณ์หรือไม่ หากเสร็จสิ้นฟังก์ชั่นการโทรกลับจะถูกเรียกโดยอัตโนมัติซึ่งสามารถลดความซับซ้อนของโปรแกรมพร้อมกัน
แนะนำวิธีที่สองเนื่องจากวิธีที่สองสามารถรับค่าส่งคืนของอนาคตหรือจัดการกับข้อผิดพลาดได้โดยตรง ในสาระสำคัญวิธีที่สองทำได้โดยการระดมวิธีแรกและการห่อหุ้มเพิ่มเติมจะเสร็จสิ้น
นอกจากนี้ ListenableFuture ยังมีการใช้งานในตัวอื่น ๆ อีกมากมาย:
SetableFuture: ไม่จำเป็นต้องใช้วิธีการในการคำนวณค่าส่งคืน แต่จำเป็นต้องมีค่าคงที่เท่านั้นในการส่งคืนเป็นค่าส่งคืน คุณสามารถตั้งค่าค่าส่งคืนหรือข้อมูลข้อยกเว้นของอนาคตนี้ผ่านโปรแกรม
CheckedFuture: นี่คือการสืบทอดจากอินเทอร์เฟซ ListenableFuture มันมีวิธีการตรวจสอบ () วิธีนี้สามารถโยนข้อยกเว้นของประเภทที่ระบุเมื่อมีข้อยกเว้นเกิดขึ้นในการดำเนินการในอนาคต
Ratelimiter คล้ายกับสัญญาณของ JDK มันถูกใช้เพื่อ จำกัด จำนวนเธรดเพื่อเข้าถึงทรัพยากรพร้อมกัน บทความนี้แนะนำการใช้ Ratelimiter
ตัวอย่างรหัส
นำเข้า java.util.concurrent.callable; นำเข้า java.util.concurrent.executionexception; นำเข้า java.util.concurrent.executors; นำเข้า java.util.concurrent.timeUnit; นำเข้า com.google.Common.Util.concurrent. com.google.common.util.concurrent.futures; นำเข้า com.google.common.util.concurrent.listenablefuture; นำเข้า com.google.common.util.concurrent.listeningexecutorservice; com.google.common.util.concurrent.rateLimiter; คลาสสาธารณะฟังได้ futuredemo {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {testratelimiter (); testlistenablefuture ()}/** ** ** TestRatelimiter () {ListenexecutorService ExecutorService = moreexecutors .ListeningDecorator (Executors.newcachedThreadPool ()); ratelimiter Limiter = Ratelimiter.create (5.0); Ratelimiter, เกินใบอนุญาตจะถูกบล็อกสุดท้าย ListenableFuture <จำนวนเต็ม> ฟังได้รับการฟัง = ExecutorService .submit (งานใหม่ ("IS"+ I));}} โมฆะสาธารณะแบบคงที่ testListenableFuture () Final ListenableFuture <Integer> ListenableFuture = ExecutoRservice .submit (งานใหม่ ("testListenableFuture")); // synchronously ได้รับผลการโทรลอง {system.out.println {e1.printStackTrace ();} // วิธีแรก ListenableFuture.addListener (ใหม่ runnable () {@Override โมฆะสาธารณะเรียกใช้ () {ลอง {system.out.println ("รับผลลัพธ์ในอนาคต" ExecutorService); // วิธีที่สอง futures.addCallback (ฟังได้รับ futureCallback ใหม่ <จำนวนเต็ม> () {@Override โมฆะสาธารณะ onsuccess (ผลการศึกษาจำนวนเต็ม) {system.out .println ("รับผลการโทรกลับ {t.printStackTrace ();}});}} งานคลาสใช้ callable <teger> {String str; งานสาธารณะ (String str) {this.str = str;}@reverride การเรียกใช้จำนวนเต็มสาธารณะเวอร์ชัน GUAVA
<การพึ่งพา> <roupId> com.google.guava </groupId> <ratifactid> Guava </artifactid> <version> 14.0.1 </version>
สรุป
ข้างต้นเป็นเรื่องเกี่ยวกับ Ratelimit - การใช้ Guava เพื่อสร้างตัวอย่างรหัส จำกัด อินเทอร์เฟซ ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน เพื่อนที่สนใจสามารถอ้างถึงหัวข้ออื่น ๆ ที่เกี่ยวข้องในเว็บไซต์นี้ต่อไป หากมีข้อบกพร่องใด ๆ โปรดฝากข้อความไว้เพื่อชี้ให้เห็น ขอบคุณเพื่อนที่ให้การสนับสนุนเว็บไซต์นี้!