Este artículo estudia principalmente Ratelimit: el contenido relevante de usar GuAVA para realizar la restricción de flujo de interfaz, de la siguiente manera.
1. Descripción del problema
Un día, el Sr. A descubrió repentinamente que el número de solicitudes para su interfaz de repente aumentó a 10 veces la anterior. No mucho después, la interfaz era casi inutilizable y activó una reacción en cadena que hizo que todo el sistema colapsara. ¿Cómo lidiar con esta situación? La vida nos da la respuesta: por ejemplo, los interruptores anticuados están equipados con fusibles. Una vez que alguien use equipos súper de alta potencia, el fusible será volado para proteger cada aparato de ser quemado por una corriente fuerte. Del mismo modo, nuestra interfaz también debe instalarse con un "fusible" para evitar la parálisis del sistema causada por una presión excesiva en el sistema mediante solicitudes imprevistadas. Cuando el tráfico es demasiado grande, se pueden adoptar mecanismos como el rechazo o el drenaje.
2. Algoritmos limitantes de corriente comúnmente utilizados
Hay dos algoritmos limitantes de corriente de uso común: algoritmo de cubo con fugas y algoritmo de cubo de token.
La idea del algoritmo de cubo con fugas es muy simple. Ingrese primero el cubo de fugas. El cubo con fugas saldrá a cierta velocidad. Cuando la solicitud de agua es demasiado grande, se desbordará directamente. Se puede ver que el algoritmo de cubo de fuga puede limitar por la fuerza la velocidad de transmisión de datos.
Figura 1 Diagrama esquemático del algoritmo de cubo filtrado
Para muchos escenarios de aplicación, además de poder limitar la tasa de transmisión promedio de datos, también se requiere permitir algún grado de transmisión de estallido. En este momento, el algoritmo de cubo filtrado puede no ser adecuado, y el algoritmo de cubo de tokens es más adecuado. Como se muestra en la Figura 2, el principio del algoritmo de cubo de token es que el sistema colocará un token en el cubo a una velocidad constante. Si la solicitud debe ser procesada, es necesario obtener un token del cubo primero. Cuando no hay token en el balde, se negará el servicio.
Figura 2 Diagrama esquemático del algoritmo de cubo de token
3. Ratelimiter en la clase de herramienta de limitación actual
El kit de herramientas de código abierto de Google proporciona la clase Ratelimiter, que se basa en el "Algoritmo de cubo de token" y es muy conveniente de usar. Para el uso específico de esta interfaz de clase, consulte la práctica de uso de Ratelimiter.
Ratelimiter usando demostración
paquete ratelimite; import com.google.common.util.concurrent.ratelimiter; public class ratelimiterDemo {public static void main (string [] args) {testNorAtElimiter (); testWithratElimiter ();} public static testNoratElimiter () {Long Start = System.currentTtimeMillis () para (); <10; Se envían 10 tareas por segundo para (int i = 0; i <10; i ++) {limiter.acquire (); // request RatElimiter, excediendo los permisos se bloqueará System.out.println ("Llame Execute ..} Long End = System.CurrentTimemillis (); System.Println (End - Start);}}} Cuatro concurrencia de Guava: Ejemplo de Future y Ratelimiter
concepto
Escuchar Future, como su nombre lo indica, es un futuro que se puede escuchar, es una mejora extendida para el futuro nativo de Java. Sabemos que el futuro representa una tarea de cálculo asincrónico, y los resultados del cálculo se pueden obtener cuando se completa la tarea. Si queremos obtener los resultados y mostrarlos al usuario una vez que se complete el cálculo o hacer otros cálculos, debemos usar otro hilo para consultar constantemente el estado de cálculo. Esto hace que el código sea complejo e ineficiente. Use la guayaba de escucha escuchable para ayudarnos a detectar si se completa el futuro. Si se completa, la función de devolución de llamada se llamará automáticamente, lo que puede reducir la complejidad del programa concurrente.
Se recomienda el segundo método, porque el segundo método puede obtener directamente el valor de retorno del futuro o los errores de manejo. En esencia, el segundo método se logra movilizando el primer método y se realiza una mayor encapsulación.
Además, ListenableFuture tiene varias otras implementaciones incorporadas:
SettableFuture: no es necesario implementar un método para calcular el valor de retorno, pero solo se necesita un valor fijo para devolver como valor de retorno. Puede establecer el valor de retorno o la información de excepción de este futuro a través del programa.
CheckedFuture: esto es un heredado de la interfaz de KurchableFuture. Proporciona el método checkedget (). Este método puede lanzar una excepción del tipo especificado cuando se produce una excepción en la ejecución futura.
Ratelimiter es similar al semáforo de JDK. Se utiliza para limitar el número de hilos para acceder simultáneamente a los recursos. Este artículo presenta el uso de Ratelimiter.
Ejemplo de código
import java.util.concurrent.callable; import java.util.concurrent.executionException; import java.util.concurrent.executors; import java.util.concurrent.timeunit; import com.google.common.util.concurrent.futurecallback; com.google.common.util.concurrent.futures; import com.google.common.util.concurrent.listenableFuture; import com.google.common.util.concurrent.listeningExecutorservice; import com.google.common.util.concurrent.moreexecutors; import com.google.common.util.concurrent.rateliMiter; public class escucheableFuturedemo {public static void main (string [] args) {testRateLimiter (); testListenableFuTure ();}/*** ratelimiter es similar a la semphore semestérica JDK, que se usa para limitar el número de shifts a los hilos de hilos a los hilos de hilos a los hilos. testRatelImiter () {ListenExeCuTorService ExecutorService = MoreExeCutors .ListeningDecorator (ejecutors.newCachedThreadPool ()); ratelimiter limiter = ratElimiter.create (5.0); // no más de 4 tareas se presentan por segundo para (int i = 0; i <10; i ++) {limiter.acquer (); RatElimiter, excediendo los permisos se bloqueará Final KindableFuture <Integer> ListearFuture = ExecutorService .SubMit (nueva tarea ("IS"+ i));}} public static void testInableBuTure () {ListeningExecutorService EjecutorService = MoreExeCutors .ListeningDecorator (Ejecutores. Final ListenableFuture <Integer> LearableFuture = ExecutorService .SubMit (new Task ("TestListenableFuture")); // Synchrony obtiene el resultado de la llamada Try {System.Println (ListenableFuture.get ());} Catch (InterrumpedException e1) {e1.Printstacktrace ();} Ejecution e1); {e1.printstackTrace ();} // La primera manera de escucharfuture.addListener (new runnable () {@Override public void run () {try {system.Println ("Get Kearable Future el resultado" + ListureFuture.get ());} Catch (interrumpedxception e) {E.PrintststAr EjecutorService); // the Second Way futures.addCallback (ListenableFuture, new Futurecallback <integer> () {@Override public void onSuccess (Integer result) {System.out .Println ("Obtenga el resultado del futuro escuchable con la devolución de llamada" + resultado);}@anulación pública Void Onfailure (shoule t) {T.PrintStackTrace ();}});}} Tarea de clase implementa Callable <integer> {String Str; public Task (String Str) {this.str = Str;}@anular public Integer Call () Exception {System.out.println ("Llame exUteut.Versión de guayaba
<Spendency> <MoupRid> com.google.guava </proupid> <artifactId> Guava </artifactid> <versión> 14.0.1 </versión> </pendency>
Resumir
Lo anterior se trata de Ratelimit, usando Guava para hacer ejemplos de código de limitación de interfaz actual. Espero que sea útil para todos. Los amigos interesados pueden continuar referiéndose a otros temas relacionados en este sitio. Si hay alguna deficiencia, deje un mensaje para señalarlo. ¡Gracias amigos por su apoyo para este sitio!