• Inicio
  • Novedades
  • Academia SAP
  • FAQ
  • Blog
  • Contacto
S4PCADEMY_Logo
Twitter Linkedin Instagram
S4PCADEMY_Logo
Twitter Linkedin Instagram
FORMACIÓN SAP

Paralelizar cl_http_client

By s4pcademy 


Esta es una respuesta directa a mi propia pregunta

Tiene el requisito de llamar a un microservicio REST escalable externo. Desafortunadamente, el sistema necesita unos 100 ms para responder y debe llamar al sistema varias veces con diferentes parámetros. Como los usuarios finales llaman al código, desea paralelizar las llamadas REST.

Entonces, ¿cuál es la solución «normal» para ese problema? La respuesta ABAP estándar es, por supuesto: ABAP Parallelization using Worker-Processes (usando, por ejemplo, esa maravillosa biblioteca ZHREAD por marian zeis ). Sin embargo, esto tiene múltiples problemas:

  1. Usted es el antiguo sistema SAP limitante. El otro sistema es un microservicio escalable elegante que también puede consumir 100 000 solicitudes por segundo. Solo tienes 100 procesos de trabajo….
  2. Los procesos de trabajo son un recurso escaso. Si, por ejemplo, paraleliza la solicitud anterior a 10 procesos de trabajo y tiene, por ejemplo, 1.000 usuarios activos en su sistema ERP, los procesos de trabajo limitarán en gran medida su posible paralelización. En el peor de los casos, se sale de los procesos de trabajo, lo que provoca tiempos de espera en todas partes.
  3. Los procesos de trabajo son un enfoque de «uno para todos». En mi opinión, están muy sobredimensionados por el requisito simple de múltiples solicitudes http.
  4. Los procesos de trabajo son agotadores para escribir y especialmente para depurar. Incluso con buenas bibliotecas con ZTHREAD, todos conocen la situación cuando se abren 100 ventanas SAP GUI porque accidentalmente ha establecido un punto de interrupción en un código ejecutado en paralelo.

¿Entonces, cuál es la solución? En realidad es extremadamente simple e incluso está documentado en el Ayuda SAP (con ejemplos de código «un poco más antiguos»): puede simplemente llamar al método de envío de cl_http_client varias veces.

¿Cómo funciona esto? Veamos el siguiente código de ejemplo muy simple sobre cómo activar una llamada HTTP.

DO 20 TIMES.
   cl_http_client=>create_by_url(
      EXPORTING
        url                = |{ base_part_of_url }{ sy-index }{ parameters_of_url }|
      IMPORTING
        client             = DATA(client)
    ).
    client->request->set_method( if_rest_message=>gc_method_get ).
    client->send( ).
    client->receive( ).
    client->close( ).
ENDDO.

En mi caso, esta solicitud tarda alrededor de 100 ms y tengo que llamarla 20 veces. Entonces, sin paralelización, tomaría alrededor de 2 segundos.

Solución: simplemente no llame a la recepción todo el tiempo (lo cual es síncrono), sino que simplemente inserte cl_http_clients en una tabla interna de clientes y, después de que todos hayan sido enviados, llame a la recepción una por una.

  DATA: clients type standard table of if_http_client.

  DO 20 TIMES.
    cl_http_client=>create_by_url(
      EXPORTING
        url                = |{ base_part_of_url }{ sy-index }{ parameters_of_url }|
      IMPORTING
        client             = DATA(client)
    ).

    APPEND client TO clients.

    client->request->set_method( if_rest_message=>gc_method_get ).
    client->send( ).
  ENDDO.

  LOOP AT clients INTO client.
    client->receive( ).
    client->close( ).
  ENDLOOP.

El siguiente gráfico ofrece una comparación entre llamar a las solicitudes secuencialmente y en paralelo.

Es claramente visible que también hay algunos gastos generales (probablemente en mi extremo receptor), aún así funciona drásticamente mejor sin un gran aumento de la complejidad.

Tiempo de ejecución%20Comparación

Comparación de tiempo de ejecución

Observaciones adicionales:

  • La documentación sugiere usar el método de escucha estático en lugar de simplemente llamar a «recibir» en cada cl_http_client. En teoría, esto debería devolver la instancia cl_http_client que devolvió los datos «primero». En mis experimentos, sin embargo, eso no fue realmente más rápido (al menos si tengo que esperar a que regresen todas las consultas) y al mismo tiempo hizo que la codificación sea más compleja, ya que debe hacer coincidir la llamada con los parámetros que ha enviado. En la «paralelización de código duro» (es decir, hacer> 1,000 llamadas paralelas), este enfoque incluso falló, mientras que solo llamar a recibir uno por uno fue estable.
  • Nada viene gratis. Asegúrese de que el parámetro RZ11 icf/max_handle_key e icm/max_threads estén lo suficientemente altos en caso de que realmente tenga una paralelización masiva.




Simplificación de la carga de Excel en Fiori Elements: el control personalizado UI5 de código abierto y fácil de usar
Previo
Migración a la nube de SAP HANA: configure su sistema HANA local para la herramienta de migración de autoservicio
Siguiente

Madrid

Calle Eloy Gonzalo, 27
Madrid, Madrid.
Código Postal 28010

México

Paseo de la Reforma 26
Colonia Juárez,  Cuauhtémoc
Ciudad de México 06600

Costa Rica

Real Cariari
Autopista General Cañas, 
San José, SJ 40104

Perú

Av. Jorge Basadre 349
San Isidro
Lima, LIM 15073

Twitter Linkedin Instagram
Copyright 2022 | All Right Reserved.