¿Cómo generar solicitudes de tasa constante en k6 con la nueva API de scripting?

Hola, Khabrovites. La víspera del inicio del curso de pruebas de carga, hemos preparado para usted una traducción de otro material interesante.






Introducción



La versión v0.27.0 nos trajo un nuevo motor de ejecución y muchos nuevos ejecutores para abordar sus requisitos específicos. También incluye una nueva API de scripting con muchas opciones diferentes para ajustar y simular la carga del sistema bajo prueba (SUT). Este es el resultado de un año y medio trabajando en la infame solicitud de extracción # 1007 .



Para generar consultas a un ritmo constante, podemos utilizarconstant-arrival-rateejecutante. Este corredor ejecuta la prueba con iteraciones a una frecuencia fija durante el tiempo especificado. Esto permite que k6 cambie dinámicamente el número de usuarios virtuales activos (VU) durante la ejecución de la prueba para lograr el número especificado de iteraciones por unidad de tiempo. En este artículo, voy a explicar cómo utilizar este escenario para generar solicitudes a un ritmo constante.



Conceptos básicos de las opciones de configuración de secuencias de comandos



Echemos un vistazo a los parámetros clave usados ​​en k6 para describir una configuración de prueba en un script que usa un constant-arrival-rateejecutor:



  • executor ():

    — k6. VU - — , , .
  • rate () timeUnit ( ):

    k6 rate timeUnit .



    :



    • rate: 1, timeUnit: '1s' « »
    • rate: 1, timeUnit: '1m' « »
    • rate: 90, timeUnit: '1m' « 90 », 1,5 /, 667 ,
    • rate: 50, timeUnit: '1s' « 50 », 50 (requests per second — RPS), , .. 20
  • duration ():

    , gracefulStop.
  • preAllocatedVUs:

    .
  • maxVUs:

    , .


Juntos, estos parámetros forman un script que forma parte de las opciones de configuración de la prueba. El siguiente fragmento de código es un constant-arrival-ratescript de muestra .



En esta configuración, tenemos un constant_request_ratescript, que es un identificador único que se usa como etiqueta para el script. Este escenario usa un constant-arrival-rateejecutor y se ejecuta en 1 minuto. Cada segundo ( timeUnit), se realizará 1 iteración ( rate). El grupo de usuarios virtuales aprovisionados previamente contiene 20 instancias y puede ser hasta 100, según la cantidad de solicitudes e iteraciones.



Tenga en cuenta que la inicialización de usuarios virtuales durante una prueba puede consumir mucha CPU y, por lo tanto, distorsionar los resultados de la prueba. En general, es mejor preAllocatedVUtener suficiente para ejecutar la prueba de carga. Por lo tanto, no olvide asignar más usuarios virtuales según la cantidad de solicitudes en su prueba y la velocidad a la que desea ejecutar la prueba.



export let options = {
  scenarios: {
    constant_request_rate: {
      executor: 'constant-arrival-rate',
      rate: 1,
      timeUnit: '1s',
      duration: '1m',
      preAllocatedVUs: 20,
      maxVUs: 100,
    }
  }
};


Un ejemplo de generación de solicitudes con una frecuencia constante con constant-arrival-rate



En el tutorial anterior, demostramos cómo calcular la tasa de solicitud constante. Miremos de nuevo, teniendo en cuenta cómo funciona la secuencia de comandos:



suponga que espera que su sistema bajo prueba maneje 1000 solicitudes por segundo en un punto final. La asignación previa de 100 usuarios virtuales (máximo 200) permite que cada usuario virtual envíe aproximadamente de 5 a 10 solicitudes (en función de 100 a 200 usuarios virtuales). Si cada solicitud tarda más de 1 segundo en completarse, terminará haciendo menos solicitudes de las esperadas (másdropped_iterations), que es una señal de problemas de rendimiento o expectativas poco realistas para el sistema que se está probando. Si este es el caso, debe solucionar los problemas de rendimiento y reiniciar la prueba, o moderar sus expectativas ajustando timeUnit.



En este escenario, cada usuario virtual aprovisionado previamente hará 10 solicitudes ( ratedivisibles porpreAllocatedVU). Si no se reciben solicitudes en 1 segundo, por ejemplo, tomó más de 1 segundo para obtener una respuesta, o su sistema bajo prueba tardó más de 1 segundo en completar la tarea, k6 aumentará la cantidad de usuarios virtuales para compensar las solicitudes perdidas. La siguiente prueba genera 1000 solicitudes por segundo y se ejecuta durante 30 segundos, que son aproximadamente 30,000 solicitudes, como puede ver en el resultado a continuación: http_reqsy iterations. Además, k6 solo usó 148 de 200 usuarios virtuales.



import http from 'k6/http';

export let options = {
    scenarios: {
        constant_request_rate: {
            executor: 'constant-arrival-rate',
            rate: 1000,
            timeUnit: '1s', // 1000   , ..1000  
            duration: '30s',
            preAllocatedVUs: 100, //      
            maxVUs: 200, //  preAllocatedVU ,    ,    
        }
    }
};

export default function () {
    http.get('http://test.k6.io/contacts.php');
}


El resultado de ejecutar este script será el siguiente:



$ k6 run test.js


          /\      |‾‾|  /‾‾/  /‾/

     /\  /  \     |  |_/  /  / /

    /  \/    \    |      |  /  ‾‾\

   /          \   |  |‾\  \ | (_) |

  / __________ \  |__|  \__\ \___/ .io

  execution: local
     script: test.js
     output: -

  scenarios: (100.00%) 1 executors, 200 max VUs, 1m0s max duration (incl. graceful stop):
           * constant_request_rate: 1000.00 iterations/s for 30s (maxVUs: 100-200, gracefulStop: 30s)

running (0m30.2s), 000/148 VUs, 29111 complete and 0 interrupted iterations
constant_request_rate ✓ [======================================] 148/148 VUs  301000 iters/s

    data_received..............: 21 MB  686 kB/s
    data_sent..................: 2.6 MB 85 kB/s
    *dropped_iterations.........: 889    29.454563/s
    http_req_blocked...........: avg=597.53µs min=1.64µs  med=7.28µs   max=152.48ms p(90)=9.42µs   p(95)=10.78µs
    http_req_connecting........: avg=561.67µs min=0s      med=0s       max=148.39ms p(90)=0s       p(95)=0s
    http_req_duration..........: avg=107.69ms min=98.75ms med=106.82ms max=156.54ms p(90)=111.73ms p(95)=116.78ms
    http_req_receiving.........: avg=155.12µs min=21.1µs  med=105.52µs max=34.21ms  p(90)=147.69µs p(95)=190.29µs
    http_req_sending...........: avg=46.98µs  min=9.81µs  med=41.19µs  max=5.85ms   p(90)=53.33µs  p(95)=67.3µs
    http_req_tls_handshaking...: avg=0s       min=0s      med=0s       max=0s       p(90)=0s       p(95)=0s
    http_req_waiting...........: avg=107.49ms min=98.62ms med=106.62ms max=156.39ms p(90)=111.52ms p(95)=116.51ms
    *http_reqs..................: 29111  964.512705/s
    iteration_duration.........: avg=108.54ms min=99.1ms  med=107.08ms max=268.68ms p(90)=112.09ms p(95)=118.96ms
    *iterations.................: 29111  964.512705/s
    vus........................: 148    min=108 max=148
    vus_max....................: 148    min=108 max=148


Al escribir un guión de prueba, tenga en cuenta los siguientes puntos:



  1. k6 (), . , , maxRedirects: 0 . http , maxRedirects.
  2. . , , , , sleep().
  3. , , . preAllocatedVU / maxVU, , , , preAllocatedVU, maxVU .



    WARN[0005] Insufficient VUs, reached 100 active VUs and cannot initialize more  executor=constant-arrival-rate scenario=constant_request_rate


  4. , drop_iterations, iterations http_reqs . dropped_iterations , , . , , preAllocatedVU. , , , .
  5. , , . :



    WARN[0008] Request Failed
  6. Recuerde que la API de secuencias de comandos no admite el uso global de duración, vus y etapas, aunque aún se pueden usar. Esto también significa que no puede usarlos junto con scripts.


Conclusión



Antes del lanzamiento de la versión 0.27.0 , k6 no tenía suficiente soporte para generar solicitudes a un ritmo constante. Por lo tanto, implementamos una solución alternativa en JavaScript , calculando el tiempo que lleva completar las solicitudes para cada iteración del script. Con v0.27.0 esto ya no es necesario.



En este artículo, analicé cómo k6 puede lograr una tasa de solicitud constante con la nueva API de scripting usandoconstant-arrival-rateejecutante. Este ejecutor simplifica el código y proporciona los medios para lograr un número fijo de solicitudes por segundo. Esto contrasta con una versión anterior del mismo artículo, en la que describí otro método para lograr sustancialmente los mismos resultados calculando el número de usuarios virtuales, iteraciones y duración usando una fórmula y algún código JavaScript estándar. Afortunadamente, este nuevo enfoque funciona según lo previsto y ya no necesitamos utilizar ningún truco.



Espero que hayas disfrutado leyendo este artículo. Me encantaría escuchar tus comentarios.







Lee mas






All Articles