Estrutura Camel: Comparando Componentes HTTP e AHC

Este artigo compara a operação dos serviços mais simples implementados usando o framework Camel e seus dois componentes: HTTP e AHC. Não vamos nos aprofundar na estrutura e trabalhar com a própria estrutura, presume-se que o leitor já esteja um pouco familiarizado com ela.





Vamos considerar um serviço Camel simples que recebe solicitações do componente jetty, processa-as, por exemplo, exibe-as no log, chama outro serviço via http e processa a resposta dele, por exemplo, grava no log.





Para o teste, scripts JMeter foram usados ​​para chamar nosso serviço de acordo com a frequência e intervalos pretendidos, bem como um pequeno serviço Http que desempenha o papel de externo ao nosso serviço e realiza um atraso de 5 segundos. Toda a comunicação ocorre em um loop local (127.0.0.1), portanto as latências da rede não são levadas em consideração, mas não são necessárias para a análise comparativa.





Componente HTTP

Esta seção examinará o componente HTTP padrão para comunicação HTTP. Código de serviço simples:





from("jetty:http://localhost:8080/test")
     .log("receive request body ${body}")
     .removeHeaders("CamelHttp*")
     .to("http://{{another.url}}")
     .log("finish process body ${body}");
      
      



Nota: A remoção dos cabeçalhos começando com "CamelHttp" é necessária porque eles estão expostos no componente Jetty e podem afetar a operação do componente Http.





Para testar o funcionamento deste serviço, vamos rodar o script JMeter que envia 25 requisições simultâneas.





Amostras





Min





Max





Erro%





25





5012





7013





20.000%





, 20% 5 25 (Read timed out). , http- 20 . connectionsPerRoute





from("jetty:http://localhost:8080/test")
     .log("receive request body ${body}")
     .removeHeaders("CamelHttp*")
     .to("http://{{another.url}}?connectionsPerRoute=200")
     .log("finish process body ${body}");
      
      



25 . – jetty-, 200. 4 JMeter:





  1. 200





  2. 300





  3. 300 5 , 5





  4. 200 5 , 5





1 JVM 214 , .





:





 









200





0%





300





34.667%





300 5





71.733%





200 5





0%









300 , 200 jetty-, 100 jetty, 5 , 10. 34% – 100 .





, – 300 5 , 5 , .. 60 , 200 5 , .





, , , , jetty- .





, jetty-, JVM 1 , Docker- , . .





AHC-

AHC- - Camel HTTP. AsyncHttpClient, () . – http- , , .. 5 . , . :





from("jetty:http://localhost:8080/test")
     .log("receive request body ${body}")
     .removeHeaders("CamelHttp*")
     .to("ahc:http://{{another.url}}")
     .log("finish process body ${body}");
      
      



, 300 . , http- . JVM:





, . :





 









300 5





0%





800 5





0%





1200 5





1.533%





1600 5





15.02%





, , .





, , 1200 1600 http-, - , .





AHC-

AHC-, . :





from("jetty:http://localhost:8080/test")
     .log("receive request body ${body}")
     .removeHeaders("CamelHttp*") 
     .setHeader("rand", ()->new Random().nextInt(10000) )
     .toD("ahc:http://{{another.url}}?rand=${headers.rand}")
     .log("finish process body ${body}");

      
      



Depois de executar o script com um início único de 300 solicitações, o estado dos threads na JVM:





Como você pode ver, há muito fluxo. O fato é que, por padrão, o componente AHC para cada endpoint cria sua própria instância do objeto AsyncHttpClient, cada um com seu próprio pool de conexões e threads, como resultado, para cada solicitação, 2 threads são criados - um thread de E / S, outro thread de timer para controlar tempos limite e manter as conexões no estado KeepAlive. Para evitar isso, você precisa configurar a instância AsyncHttpClient no nível do componente, que será passada ao terminal quando for criada.





AhcComponent ahc = getContext().getComponent("ahc", AhcComponent.class);
ahc.setClient(new DefaultAsyncHttpClient());
      
      



Depois disso, a criação de várias instâncias de AsyncHttpClient será interrompida.








All Articles