¿Por qué probar <\/SPAN>un Servicio de Mapa en Caché?<\/SPAN><\/H1>Los servicios de mapas en caché son una forma popular y recomendada para proporcionar una presentación con buen rendimiento de datos estáticos. El tipo de servicio en caché es una tecnología comprobada, pero aún puede haber requisitos para probarlo bajo carga para observar su escalabilidad de primera mano en una arquitectura de implementación específica. Aunque los servicios de mapas en caché funcionan bien, atender miles de <\/SPAN>solicitudes simultáneas de mosaicos puede ser intensivo en recursos para el hardware del servidor.<\/SPAN><\/P>Nota: Debido a la rápida tasa de entrega y consumo del recurso, las pruebas de carga en servicios de mapas en caché también pueden ser intensivas en la utilización del hardware de la estación de trabajo cliente de prueba.<\/STRONG><\/FONT><\/P>Desafíos en las Pruebas de Servicios de Mapas en Caché<\/SPAN><\/H1>En comparación con las pruebas de carga de la función exportar mapa, la prueba adecuada<\/EM> de un servicio de mapa en caché introduce varios desafíos ya que la composición de la solicitud cambia con cada pantalla del mapa. Dado que el esquema subyacente del caché utiliza un diseño de cuadrícula, las extensiones del mapa en algunos desplazamientos o acercamientos pueden descargar más o menos imágenes de mosaicos que otros. Tener en cuenta este comportamiento real del servicio en caché hace que la lógica de prueba sea más compleja que si se estuviera ejercitando la función exportar mapa.<\/SPAN><\/P>La lógica de prueba también debe ser dinámica y cubrir un área decente de interés. Convertir un archivo HAR con solicitudes capturadas de mosaicos en caché en una prueba puede ser rápido y fácil, pero no muestra una escalabilidad realista del servicio. Esto se debe a la pequeña muestra de solicitudes de mosaicos que se usan repetidamente.<\/SPAN><\/P>En términos generales, las solicitudes para mosaicos individuales en caché son rápidas...muy<\/EM> rápidas. Debido a este comportamiento, la lógica de prueba también necesita funcionar bien, escalar con el servicio y tener una sobrecarga mínima en el cliente de prueba.<\/SPAN><\/P>¿Cómo probar un <\/SPAN>Servicio de Mapa en Caché?<\/SPAN><\/H1>Los pasos en este Artículo deberían funcionar con cualquier servicio existente de mapa en caché en su implementación local de ArcGIS Enterprise. Sin embargo, si no hay uno disponible, se recomienda echar un vistazo al conjunto de datos Natural Earth para esta tarea.<\/SPAN><\/P>El Conjunto de Datos Natural Earth<\/H2>Aunque los pasos deberían funcionar con cualquier dato, el recorrido del proceso en este Artículo podría ser más efectivo si se pueden seguir directamente. En tales casos, es excelente recurrir a los conjuntos de datos Natural Earth<\/A> que proporcionan un detalle decente del mapa (a escalas menores) cubriendo todo el mundo.<\/SPAN><\/P>Descargue aquí el conjunto Natural Earth<\/A><\/STRONG> - La descarga mencionada arriba es un subconjunto del mayor <\/SPAN>
Natural_Earth_quick_start.zip<\/A> e incluye un MXD modificado para ArcMap 10.8.1 y proyecto ArcGIS Pro 2.8.<\/SPAN>Cualquiera puede usarse para publicar y crear un servicio de mapa en caché para ArcGIS Enterprise.<\/SPAN><\/LI><\/UL><\/LI><\/UL><\/LI>El subconjunto Natural Earth debería verse similar al siguiente cuando se abra en ArcGIS Pro (o ArcMap).<\/SPAN><\/LI><\/UL>
<\/span><\/SPAN><\/P>Este Artículo no<\/EM> <\/STRONG>cubrirá los detalles sobre cómo crear, configurar o publicar un servicio de mapa en caché en ArcGIS Enterprise. <\/SPAN>Para información sobre estas acciones, consulte:Tutorial: Creación de un servicio de mapa en caché<\/A><\/STRONG> <\/LI><\/UL><\/LI><\/UL>Nota: Se recomienda familiarizarse con algunos detalles metadata del servicio de mapa en caché ya que el esfuerzo para pruebas de carga requerirá conocimiento sobre parte esa información (por ejemplo, xorigin, yorigin, tileCols, tileRows y referencia espacial así como las escalas que contienen mosaicos).<\/STRONG><\/FONT><\/P>
Componentes del Plan de Prueba
Configuración de Conjunto de Datos CSV
Los elementos Configuración de Conjunto de Datos CSV en JMeter se usan para referenciar los datos de prueba recién generados desde el sistema de archivos. La versión actual del Plan de Prueba está construida para utilizar 3 archivos CSV diferentes (uno para cada archivo de datos de escala de mapa).

Nota: Aparte de las Variables Definidas por el Usuario y la configuración del Nombre de Archivo en los elementos Configuración de Conjunto de Datos CSV, no debería haber nada más que requiera edición o cambio en el Plan de Prueba. La lógica de la prueba se lista a continuación solo para explicar cómo se llenan los valores en la Solicitud HTTP.
Lógica de Lista de Niveles de Detalle
Para evitar una lógica más compleja en JMeter, 24 niveles fijos de detalle de caché de mapa están colocados dentro de una clase en un elemento de prueba JSR223 Sampler. Esa "alternativa compleja" sería conectar el endpoint del servicio al inicio de la prueba y descargar los metadatos del tile cache. Poner lógica HTTP en JSR223 Samplers es técnicamente posible, pero no fue la ruta que elegí.
- Solo hay un JSR223 Sampler dentro de la Transacción Niveles De Detalle
- Este ítem se ejecuta solo una vez, al inicio de cada hilo de prueba
- El elemento contiene 24 niveles fijos de detalle cacheados, con nivel 0 comenzando en escala 591657527.591555
- Si su esquema cache comienza en una escala diferente para 0, entonces el JSR223 Sampler necesitará ser ajustado manualmente
- Este JSR223 Sampler no necesita ser editado para ejecutar la prueba
- Esto asume que el servicio map cache tiene una Referencia Espacial 102100 (3857)

Niveles De Detalle -- JSR223 Sampler (Lógica Completa):
// Clase FileServer
import org.apache.jmeter.services.FileServer
public class Lod{
int level
double resolution
double scale
double tolerance
}
public class MyLodList1{
public List<Lod> LodList = new ArrayList()
MyLodList1(){
// Basado en Escalas de Mapa ArcGIS Online
// https://services.arcgisonline.com/arcgis/rest/services/World_Street_Map/MapServer
//
// Referencia Espacial: 102100 (3857)
Lod lod = new Lod()
lod = new Lod()
lod.level = 0
lod.resolution = 156543.03392800014 //11
lod.scale = 591657527.591555
lod.tolerance = 0.5
this.LodList.add(lod)
lod = new Lod()
lod.level = 1
lod.resolution = 78271.51696399994 //11
lod.scale = 295828763.795777
lod.tolerance = 0.5
this.LodList.add(lod)
lod = new Lod()
lod.level = 2
lod.resolution = 39135.75848200009 //11
lod.scale = 147914381.897889
lod.tolerance = 0.25
this.LodList.add(lod)
lod = new Lod()
lod.level = 3
lod.resolution = 19567.87924099992 //11
lod.scale = 73957190.948944
lod.tolerance = 0.5
this.LodList.add(lod)
lod = new Lod()
lod.level = 4
lod.resolution = 9783.93962049996 //11
lod.scale = 36978595.474472
lod.tolerance = 0.5
this.LodList.add(lod)
lod = new Lod()
lod.level = 5
lod.resolution = 4891.96981024998 //11
lod.scale = 18489297.737236
lod.tolerance = 0.5
the.LodList.add(lod)
lod = new Lod()
lod.level = 6
lod.resolution = 2445.98490512499 //11
lod.scale = 9244648.868618
lod.tolerance = 0.5
this.LodList.add(lod)
lod = new Lod()
lod.level = 7
lod.resolution = 1222.9924525624949 //13
lod.scale = 4622324.434309
lod.tolerance = 0.5
this.LodList.add(lod)
lod = new Lod()
lod.level = 8
lod.resolution = 611.49622628137968 //14
lod.scale = 2311162.217155
lod.tolerance = 0.5
this.LodList.add(lod)
lod = new Lod()
lod.level = 9
lod.resolution = 305.74811314055756 //14
lod.scale = 1155581.108577
lod.tolerance = 0.5
this.LodList.add(lod)
lod = new Lod()
lod.level = 10
lod.resolution = 152.87405657041106 //14
lod.scale = 577790.554289
lod.tolerance = 0.5
this.LodList.add(lod)
lod = new Lod()
lod.level = 11
lod.resolution = 76.437028285073239 //15
lod.scale = 288895.277144
lod.tolerance = 0.5
this.LodList.add(lod)
lod = new Lod()
lod.level = 12
lod.resolution = 38.21851414253662 //14
lod.scale = 144447.638572
lod.tolerance=0.5
this.LodList.add(lod)
lod= new Lod()
lod.level=13
lod.resolution=19.10925707126831 //15
lod.scale=72223.819286
lod.tolerance=0.5
this.LodList.add(lod)
lod=new Lod()
lod.level=14
lod.resolution=9.5546285356341549 //16
lod.scale=36111.909643
lod.tolerance=0.5
this.LodList.add(lod)
lod=new Lod()
lod.level=15
lod.resolution=4.77731426794937 //14
lod.scale=18055.954822
lod.tolerance=0.05
this.LodList.add(lod)
lod=new Lod()
lod.level=16
lod.resolution=2.388657133974685 //15
lod.scale=9027.977411
lod.tolerance=0.025
this.LodList.add(lod)
lod=new Lod()
lod.level=17
lod.resolution=1.1943285668550503 //16
lod.scale=4513.988705
lod.tolerance=0.025
this.LodList.add(lod)
lod=new Lod()
lod.level=18
lod.resolution=0.5971642835598172 //16
lod.scale=2256.994353
lod.tolerance=0.005
this.LodList.add(lod)
lod=new Lod()
lod.level=19
lod.resolution=0.29858214164761665 //17
lod.scale=1128.497176
lod.tolerance=0.005
this.LodList.add(lod)
lod=new Lod()
lод.level=20
double resolution... bbox_scale_double = Double.parseDouble(scale_var)
// Unidades del mapa por píxel
double tileresolution = 0
double lod_resolution = 0
double scale = 0
int tilelevel = 0
LodList = vars.getObject("LodList") // Suponiendo que el servicio de mapa en caché tiene una Referencia Espacial de 102100 (3857)
boolean firstIteration = true;
for(int i = 0; i < LodList.size; i++)
{
lod_resolution = Precision.round(LodList[i].resolution, resolutionprecision)
tileresolution = lod_resolution
tilelevel = LodList[i].level
scale = LodList[i].scale
if (mapresolution >= lod_resolution)
{
break
}
}
tileCols_var = vars.get("TileCols")
cols = Double.parseDouble(tileCols_var)
tileRows_var = vars.get("TileRows")
rows = Double.parseDouble(tileRows_var)
// Origen de la caché (esquina superior izquierda)
xorigin_var = vars.get("Xorigin")
xorigin = Double.parseDouble(xorigin_var)
yorigin_var = vars.get("Yorigin")
yorigin = Double.parseDouble(yorigin_var)
// Obtener columna mínima de mosaico
double minxtile = (xmin - xorigin) / (cols * tileresolution)
// Obtener fila mínima de mosaico
// Desde el origen, maxy es el mínimo y
double minytile = (yorigin - ymax) / (rows * tileresolution)
// Obtener columna máxima de mosaico
double maxxtile = (xmax - xorigin) / (cols * tileresolution)
// Obtener fila máxima de mosaico
// Desde el origen, miny es el máximo y
double maxytile = (yorigin - ymin) / (rows * tileresolution)
// Devolver valor entero para min y max, fila y columna
int mintilecolumn = (int)Math.floor(minxtile)
int mintilerow = (int)Math.floor(minytile)
int maxtilecolumn = (int)Math.floor(maxxtile)
int maxtilerow = (int)Math.floor(maxytile)
Scheme_var = vars.get("Scheme")
WebServerName_var = vars.get("WebServerName")
ServerInstanceName_var = vars.get("ServerInstanceName")
ServiceName_var = vars.get("ServiceName")
ServiceType_var = vars.get("ServiceType")
def cacheRequest
def tilePaths = []
int count = 0
for (int row = mintilerow; row <= maxtilerow; row++)
{
// para cada columna en la fila, dentro del alcance del mapa
for (int col = mintilecolumn; col <= maxtilecolumn; col++)
{
cacheRequest = ("/").concat(ServerInstanceName_var).concat("/rest/services/").concat(ServiceName_var).concat("/").concat(ServiceType_var)
cacheRequest = cacheRequest.concat("/tile").concat("/").concat(tilelevel.toString()).concat("/").concat(row.toString()).concat("/").concat(col.toString())
count++
tilePaths.add(cacheRequest)
}
}
def requestCount = count.toString()
vars.putObject("RequestCount_A",requestCount)
vars.putObject("TilePaths_A",tilePaths)
Bucle de Caché de Mosaicos y Población de Rutas
Hay varios componentes necesarios para esta parte del Plan de Pruebas. Con el cuadro delimitador traducido en los mosaicos correspondientes de la caché y ensamblado en una lista de URLs, se necesita un tercer JSR223 para colocar cada URL en una variable dentro de un bucle. La lógica del bucle tiene lugar dentro de la transacción Cache Tiles.
- Hay un muestreador JSR223 para cada escala del mapa
- Configuración CSV Data Set A --> Muestreador JSR223 A2
- Estos muestreadores JSR223 no necesitan ser editados para ejecutar la prueba
- Se añade un Controlador de Bucle para solicitar solo el número real de mosaicos por cuadro delimitador ya que esta cantidad puede cambiar según el alcance
- El número de mosaicos que corresponden a cada cuadro delimitador varía según el alcance pero también según la resolución del mapa (1920x1080)
- Resoluciones de pantalla más altas requieren más mosaicos
- El Controlador de Bucle contiene los siguientes elementos:
- Contador
- Muestreador JSR223
- Solicitud HTTP
Controlador de Bucle

Contador

Muestreador JSR223

Solicitud HTTP
Toda la lógica de prueba anterior existe solo para este componente de la prueba. Para cada escala del mapa, ¡solo hay una Solicitud HTTP! Este diseño simple favorece la legibilidad y mantenibilidad.

Nota: Las Solicitudes HTTP contienen un elemento Response Assertion para validar los ítems devueltos por el servidor. Si el tipo de contenido de la respuesta es image/jpeg o image/png, entonces la solicitud pasará. Sin embargo, algunas cachés VectorTileServer pueden devolver un archivo Protocolbuffer Binary Format (*.pbf). En estos casos, los Patrones a Probar necesitarían ser ampliados manualmente a lo siguiente: image/jpeg || image/png || application/octet-stream || application/x-protobuf
Configuración del Grupo de Hilos
El Plan de Pruebas JMeter está configurado actualmente para una prueba relativamente corta de 20 minutos. Los servicios de mapas en caché funcionan bien, por lo que habrá mucho rendimiento durante cada paso (2 minutos por paso) y en toda la prueba.
- Diferentes entornos pueden requerir una configuración alternativa de presión para lograr los resultados deseados, ajustar según sea necesario

Validando el Plan de Pruebas
Como buena práctica, siempre es buena idea validar los resultados antes de ejecutar la prueba real de carga.
- Usar el listener View Results Tree para ayudar con la validación
- El Plan de Pruebas incluye un Listener View Results Tree pero está deshabilitado por defecto
- Activarlo para ver los resultados
- Desde la GUI, iniciar la prueba
Transacciones
- Seleccionar una de las transacciones "Cache Tiles"
- Los resultados deberían parecerse a lo siguiente:

- En este ejemplo, todas las transacciones se completaron con éxito (por ejemplo, la marca verde)
- Cache Tiles (escala del mapa: 4622324.434309)
- Cache Tiles (escala del mapa: 2311162.217155)
- Cache Tiles (escala del mapa: 1155581.108577)
- Seleccionar una de las transacciones y el elemento resultado Sampler lista información clave
- Echar un vistazo rápido al Tamaño en bytes
- En el ejemplo anterior, el tamaño de la Transacción fue superior a 50KB lo que sugiere que se devolvieron datos decentes del mosaico (para este conjunto de datos) y las respuestas no fueron todas imágenes "en blanco"
- El Número de muestras en la transacción fue 80
- Dado que hay un Muestreador JSR223 con cada solicitud de mosaico, esto resultó en realidad en que se descargaron 40 mosaicos
- El Tiempo de carga muestra 62 (ms), lo que significa que solo tomó 0.062 segundos descargar 40 imágenes del mosaico
Solicitudes
- Expandir la Transacción seleccionada
- En este ejemplo, Cache Tiles (escala del mapa: 1155581.108577)
- Seleccionar una de las solicitudes HTTPS
- Los resultados deberían parecerse a lo siguiente:
<\/span><\/SPAN><\/P>En este ejemplo, la solicitud select se completó <\/SPAN>exitosamente (por ejemplo, la marca de verificación verde)<\/SPAN><\/LI>Echa un vistazo rápido al Tiempo de carga<\/SPAN>En este ejemplo, la solicitud individual de mosaico solo tardó 2 ms (0.002 segundos) en descargarse<\/SPAN><\/LI><\/UL><\/LI>Hacer clic en la pestaña Datos de respuesta te permite previsualizar el mosaico solicitado:<\/SPAN><\/LI><\/UL>
<\/span><\/SPAN><\/P>Nota: Una vez que la validación visual y la depuración estén completas, se recomienda deshabilitar el elemento View Results Tree antes de ejecutar la prueba de carga<\/STRONG><\/FONT><\/P>Ejecución de la prueba<\/H1>La prueba de carga debe ejecutarse de la misma manera que un Plan de Prueba típico de JMeter.<\/P>Consulta el script runMe.bat incluido con el proyecto cache_tiles1.zip para un ejemplo sobre cómo ejecutar una prueba según lo recomendado por Apache JMeter. <\/P>El script runMe.bat contiene una variable jmeterbin<\/EM> que deberá configurarse con el valor apropiado para tu entorno<\/LI><\/UL>Nota: Siempre se recomienda coordinar el tiempo de inicio y duración de la prueba de carga con el personal adecuado de tu organización. Esto asegura un impacto mínimo a los usuarios y otros colegas que también puedan necesitar usar tu sitio ArcGIS Enterprise local. Además, esto ayuda a prevenir system noise<\/EM> de otras actividades y usos que podrían "contaminar" tus resultados de prueba.<\/STRONG><\/FONT><\/P>Nota: Por varias razones, se aconseja encarecidamente nunca realizar pruebas de carga en ArcGIS Online<\/EM><\/U>.<\/STRONG><\/FONT><\/P>Informe JMeter<\/H1>El informe generado automáticamente por JMeter puede proporcionar información sobre el rendimiento del servicio de mapas en caché bajo cargaEste informe se genera automáticamente a partir de las opciones de línea de comandos pasadas desde el script runMe.bat<\/LI><\/UL><\/LI><\/UL>Curva de rendimiento (Throughput)<\/H2>El informe JMeter para una prueba de carga del servicio de mapas en caché puede parecer lento y pesado cuando se visualiza en un navegador webEsto se debe a la naturaleza predeterminada de su composición, que intenta representar cada solicitud única en algunos gráficosEn una prueba como esta, habrá muchas<\/LI>Desde la leyenda del gráfico, selecciona todos los elementos JSR223 Sampler para deshabilitar su representación (ya que pueden sesgar la escala)<\/LI><\/UL><\/LI><\/UL><\/LI>En este caso, el rendimiento máximo para cualquiera de las transacciones dadas a escala del mapa con mosaicos en caché fue aproximadamente 15 transacciones/segundoDado que se probaron 3 escalas del mapa, el total de transacciones por segundo alcanzado fue 45 transacciones/segundoEsto equivalió a alrededor de 162,000 transacciones en caché/hora <\/LI><\/UL><\/LI>El pico máximo parece ocurrir en la marca 10:34<\/LI><\/UL><\/LI><\/UL>