Este artigo estuda principalmente Ratelimit - o conteúdo relevante do uso de goiaba para executar a restrição de fluxo da interface, como segue.
1. Descrição do problema
Um dia, o Sr. A de repente descobriu que o número de pedidos de sua interface aumentou de repente para 10 vezes o anterior. Pouco tempo depois, a interface era quase inutilizável e desencadeou uma reação em cadeia que fez com que todo o sistema colapse. Como lidar com essa situação? A vida nos dá a resposta: por exemplo, os interruptores antiquados estão equipados com fusíveis. Quando alguém usa equipamentos super de alta potência, o fusível será soprado para proteger cada aparelho de ser queimado por uma corrente forte. Da mesma forma, nossa interface também precisa ser instalada com um "fusível" para impedir a paralisia do sistema causada por pressão excessiva no sistema por solicitações imprevistas. Quando o tráfego é muito grande, mecanismos como rejeição ou drenagem podem ser adotados.
2. Algoritmos de limitação de corrente comumente usados
Existem dois algoritmos de limitação de corrente comumente usados: algoritmo de caçamba com vazamento e algoritmo de balde de token.
A idéia do algoritmo de balde vazando é muito simples. Por favor, insira o balde vazando primeiro. O balde vazando será lançado a uma certa velocidade. Quando a solicitação de água for muito grande, ela transborda diretamente. Pode -se observar que o algoritmo de balde com vazamento pode limitar à força a taxa de transmissão de dados.
Figura 1 Diagrama esquemático do algoritmo de balde vazado
Para muitos cenários de aplicação, além de poder limitar a taxa média de transmissão de dados, também é necessário para permitir algum grau de transmissão de explosão. Neste momento, o algoritmo de balde vazado pode não ser adequado, e o algoritmo de balde de token é mais adequado. Como mostrado na Figura 2, o princípio do algoritmo do balde de token é que o sistema colocará um token no balde a uma velocidade constante. Se a solicitação precisar ser processada, será necessário obter primeiro um token do balde. Quando não houver token no balde, o serviço será negado.
Figura 2 Diagrama esquemático do algoritmo de balde de token
3. Ratelimiter na classe de ferramentas de limitação atual
O Aberto de Toolkit de código aberto do Google GUAVA fornece a classe Ratelimiter, que é baseada no "algoritmo de balde de token" e é muito conveniente de usar. Para o uso específico desta interface de classe, consulte a prática de uso do Ratelimiter.
Ratelimiter usando demonstração
pacote ratelimite; importação com.google.common.util.concurrent.ratelimiter; public class ratelimiterdemo {public static void main (string [] args) {testNoratelimiter (); TestWithRatelimiter ();} public static voidTimTimTimiMit ();); <10; 10 tarefas por segundo são enviadas para (int i = 0; i <10; i ++) {limiter.acquire (); // solicitar rateLimiter, as licenças excedentes serão bloqueadas System.out.println ("Call Execute .."+i);} end = System.curntimEmillis ();); Four GUAVA Concurrency: ListenableFuture e Ratelimiter Exemplo
conceito
O ouvido, como o nome indica, é um futuro que pode ser ouvido, é um aprimoramento prolongado do futuro nativo de Java. Sabemos que o futuro representa uma tarefa de cálculo assíncrona e os resultados do cálculo podem ser obtidos quando a tarefa é concluída. Se quisermos obter os resultados e exibi -los para o usuário depois que o cálculo for concluído ou outros cálculos, devemos usar outro thread para consultar constantemente o status do cálculo. Isso torna o código complexo e ineficiente. Use goiaba ou auditiva para nos ajudar a detectar se o futuro está concluído. Se for concluído, a função de retorno de chamada será chamada automaticamente, o que pode reduzir a complexidade do programa simultâneo.
O segundo método é recomendado, porque o segundo método pode obter diretamente o valor de retorno dos erros futuros ou manipulados. Em essência, o segundo método é alcançado mobilizando o primeiro método e o encapsulamento adicional é realizado.
Além disso, o ListenableFuture possui várias outras implementações internas:
SettableFuture: não há necessidade de implementar um método para calcular o valor de retorno, mas apenas um valor fixo é necessário para retornar como valor de retorno. Você pode definir o valor de retorno ou as informações de exceção desse futuro através do programa.
CheckEdFuture: Este é um herdado da interface ListenableFuture. Ele fornece o método checkEdget (). Este método pode lançar uma exceção do tipo especificado quando ocorre uma exceção na execução futura.
O Ratelimiter é semelhante ao semáforo do JDK. É usado para limitar o número de threads para acessar simultaneamente a recursos. Este artigo apresenta o uso do Ratelimiter.
Exemplo de código
importar java.util.Concurrent.Callable; importar java.util.concurrent.executionException; importar java.util.concurrent.executores; import java.util.concurrent.timeUnit; import.google.common.util.util.utrent.futurrent; com.google.common.util.concurrent.listenablefuture; importar com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.Concurrent.MoreExecutores; import com.google.common.util.Concurntent.Anat.ArtErt.MoreExecutores; import com.google.common.util.Concurntent.Artim.ArtErt.atimatores; main (string [] args) {testRatelimiter (); testlistenablefuture ();}/*** ratelimiter é semelhante ao semestre JDK Semphore, que é usado para limitar o número de threads a acesso concorrente a recursos*/public static void testREnMiter () {{) .ListeningDecorator (executores.newcachedthreadpool ()); ratelimiter limiter = ratelimiter.create (5.0); // não mais de 4 tarefas são enviadas por segundo para (int i = 0; i <10; i ++) {limiter.acquire (); // RATELIMITER <10; ExecutorService .Submit (New Task ("Is"+ i));}} public static void testListenablefuture () {auditionExecutorService executorService = maisexecutores .ListeningDecorator (executores.newcachedthreadpool ()); final ouvidofuture <Teger> ouvidofuture = ExecutorService .Submit (new Task ("TestListenableFuture")); // Sincrono, obtenha o resultado da chamada, tente {System.out.println (outableFuture.get (); {e1.printStackTrace ();} // A primeira maneira que ouvefuture.addlistener (new Runnable () {@Override public void run () {try {System.out.println ("Obtenha o resultado do futuro ou ouvido" + ouviceFuture.Get ();} Catchnn; ExecutorService); // O segundo caminho futuro.addcallback (ouvidofuture, new FutureCallback <Teger> () {@Override public void onSuccess (Inteiro resultado) {System.out .Println ("Obtenha o resultado de retorno de retorno de retorno" +);}@substituir o renome {t.printStackTrace ();}});}} classe Tarefa implementa chamadas <TEGER> {String str; public Task (String str) {this.str = str;}@substituir public integer chamado () {System.out.println ("Excute .." + string); timeUnit.Sec.Secrle.Secrle.SecR.Second.Second.Second.Second.Second.Second.Second.Second.Secon.Second.Second.Second.Second.Second.Second.Second.Second.Second.Second.Second.Second.Second.Second.Second.Second.Second.Second.Second.Second.Second.Second.Second.Versão de goiaba
<Depencency> <Puerpid> com.google.guava </frupid> <TRARFACTID> GUAVA </ArtifactId> <versão> 14.0.1 </versão> </dependency>
Resumir
O exposto acima é sobre ratelimit - usando goiaba para criar exemplos de código limitantes da interface. Espero que seja útil para todos. Amigos interessados podem continuar se referindo a outros tópicos relacionados neste site. Se houver alguma falha, deixe uma mensagem para apontá -la. Obrigado amigos pelo seu apoio para este site!