Camel Framework: comparación de componentes HTTP y AHC

Este artículo compara el funcionamiento de los servicios más simples implementados utilizando el marco Camel y sus dos componentes: HTTP y AHC. No profundizaremos en la estructura y trabajaremos con el framework en sí, se supone que el lector ya está un poco familiarizado con él.





Consideraremos un servicio Camel simple que recibe solicitudes del componente de embarcadero, las procesa, por ejemplo, las muestra en el registro, llama a otro servicio a través de http y procesa la respuesta de este, por ejemplo, escribe en el registro.





Para las pruebas, se utilizaron scripts de JMeter para llamar a nuestro servicio de acuerdo con la frecuencia e intervalos planificados, así como un pequeño servicio Http que desempeña el papel de externo a nuestro servicio y realiza un retraso de 5 segundos. Toda la comunicación se produce en un bucle local (127.0.0.1), por lo que las latencias de la red no se tienen en cuenta, pero no son necesarias para el análisis comparativo.





Componente HTTP

Esta sección analizará el componente HTTP estándar para la comunicación HTTP. Código de servicio simple:





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



Nota: Es necesario eliminar los encabezados que comienzan con "CamelHttp" porque están expuestos en el componente Jetty y pueden afectar el funcionamiento del componente Http.





Para probar el funcionamiento de este servicio, ejecutemos el script JMeter que envía 25 solicitudes simultáneas.





Muestras





Min





Max





Error%





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}");

      
      



Después de ejecutar el script con un inicio único de 300 solicitudes, el estado de los subprocesos en la JVM:





Como puede ver, hay demasiado flujo. El hecho es que, de forma predeterminada, el componente AHC para cada punto final crea su propia instancia del objeto AsyncHttpClient, cada uno de los cuales tiene su propio grupo de conexiones y subprocesos, como resultado, para cada solicitud se crean 2 subprocesos: un subproceso de E / S, otro subproceso de temporizador para controle los tiempos de espera y mantenga las conexiones en estado KeepAlive. Para evitar esto, debe configurar la instancia de AsyncHttpClient a nivel de componente, que se pasará al punto final cuando se cree.





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



Después de eso, se detendrá la creación de muchas instancias de AsyncHttpClient.








All Articles