Source: https://www.scribd.com/document/148768638/2010-02-benchmarking-servicios-wmsc-pdf
Timestamp: 2019-02-20 05:31:00+00:00

Document:
2010-02 benchmarking_servicios_wmsc.pdf
Uploaded by Juan Pablo de Castro
Curso-Watercad
Leer Datossiose2011 Shp v2
Articulo Jorge Torres y Oscar Mojica
Elaboración de Un Sistema de Información Geográfica Para El Análisis de La Actividad Comercial en El Municipio de Cullera
Aplicacion de Teledeteccion y SIG Para El Levantamiento Cartografico de Los Suelos de La Cuenca Solani India
Generalidades Del Sig
Preguntas Desarrolladas.final (1)
PresentaciónPortoviejo_MESOVE
Articulo Cientifico Sigopram
Data Mart - 7 Pasos Tecnicos
Manual_FactuSOL_2015EV.pdf
documentation ha
02-HUAWEI Server Products Sales Specialist Training V1.0
bts sio e6 florentin heliez
SMS Security Session Ver 3.042eng.ppt
WS08 Datasheet
DAMMI ONE.txt
Samba Inst
CISSP - 06 - Application Security v3
Desbloqueando o Modem
UNIVERSIDAD DE VALLADOLID ESCUELA TÉCNICA SUPERIOR DE INGENIEROS DE TELECOMUNICACIÓN
I.T. TELECOMUNICACIONES SISTEMAS DE TELECOMUNICACIÓN FEBRERO 2010
AUTOR: PABLO NAVARRETE ALMARZA TUTORES: JUAN PABLO DE CASTRO FERNÁNDEZ RICARDO GARCÍA MARTÍN
BENCHMARKING DE SERVICIOS WMS-C
0. Introducción 1 0.1 Introducción a los servicios de mapas 1 0.2 Objetivos del proyecto 2 0.3 Estructura de la memoria 3 1. Servicios Web de Mapas 5 1.1 Servicio Web Map Service (WMS) 5 1.2 Propuesta Web Map Tiling Service (WMTS) 7 1.3 Propuesta WMS­C 7 2. Implementaciones WMS­C 10 2.1 Cacheado en WMS 10 2.2 TileCache 11 2.3 Geowebcache 11 2.4 WMSCwrapper 12
3. Benchmarking de servicios Web de Mapas 16 4. Desarrollo de la aplicación de Benchmarking 20 4.1 Objetivos de la aplicación 20 4.2 Estructura de la aplicación 20 4.2.1 Archivo de Jmeter 20 4.2.2 Generador de Bboxes 23 4.2.3 Reporte de resultados 34 4.2.4 Estructura Maven­SVN 39 4.2.5 Scripts 40 4.2..6 Resumen 42 4.3 Conclusiones 43 5. Análisis de Resultados 44 6. Conclusiones y líneas futuras 75 Bibliografía Apéndice I. Instalación de las cachés Apéndice II. Manual de uso de la aplicación ANEXOS: Código completo de la aplicación
con el telón de fondo del impresionante desarrollo del hardware y el acceso del gran público a ordenadores cada vez mas manejables y potentes a precios asequibles. Los Sistemas de Información Geográfica (SIG o GIS en su nomenclatura inglesa) definidos como una integración de software hardware y datos geográficos. nacieron en Canadá [2] en el año 1962 cuando el Canadian Geographic Information System (CGIS) cartografió parte de su territorio nacional. y su uso quedó reducido al entorno gubernamental y administrativo Posteriores proyectos como los llevados a cabo por la Universidad de Harvard en la década de los 70 o por M&S Computing en los ochenta. una codificación de líneas en "arcos" que poseían una verdadera topología integrada y que almacenaba los atributos de cada elemento y la información sobre su localización en archivos separados. puesto que permitía superponer capas de información..0. soportaba un sistema nacional de coordenadas que abarcaba todo el continente norteamericano. Este sistema jamas llegó a estar disponible al público general. con el fin de llevar a cabo una gestión integral de sus recursos naturales mediante el uso de factores de clasificación para poder analizar toda la información El CGIS supuso un considerable avance con respecto a las aplicaciones cartográficas existentes hasta entonces. así como una conectividad creciente a las redes globales de datos y por tanto a múltiples servidores de mapas de cualquier clase situados en cualquier parte del mundo 1 . la realidad es que comparten dos elementos básicos: una imagen asociada con un atributo de información. incluyendo datos referentes a tipos de suelo. realizar mediciones y llevar a cabo digitalizaciones y escaneo de datos. Asimismo..­ INTRODUCCIÓN A LOS SERVICIOS DE MAPAS Históricamente el hombre ha utilizado mapas con los mas diversos fines [1]. especies animales. y si bien poco tienen en común los toscos dibujos efectuados en el neolítico con los complejos sistemas de información que se manejan hoy en día.. El uso comercial de estos servicios no llegaría hasta la década de los noventa. recursos fluviales.1. fueron perfilando los modelos que han llegado hasta nuestros días. especies vegetales..
para poder así establecer un uso óptimo de estas y propiciar mejoras que puedan ser de utilidad para la integración de los servidores de mapas y la optimización de los recursos disponibles. Para propiciar esta convergencia. en forma de un archivo de imagen digital (png. En este proyecto se pretende comparar el funcionamiento de tres de estas diferentes caches poniéndolas a prueba bajo diferentes condiciones de estrés. 2 . uno de los principales “cuellos de botella” en este tipo de servicios online. jpeg. que facilitan información vía web a cualquier cliente que la solicite. contenidos.. el Open Geospatial Consortium (OGC) definió hace algunos años el sistema Web Map Services (WMS). con el propósito de producir mapas georreferenciados espacialmente de forma dinámica. capas. sino en una representación visual de la misma. la existencia de información redundante en el trafico servidor­cliente. Cada mapa no consistiría por tanto en un cúmulo de información contenida en la región precisada. se han desarrollado herramientas para optimizar el uso de los recursos tanto del servidor de mapas como del cliente.­ OBJETIVOS DEL PROYECTO En la actualidad. en la medida de lo posible. Dicha información suele estar soportada en protocolos propios.).. gif. Este estándar define cada mapa como la representación de la información geográfica contenida en el servidor. formatos y sobre todo de servidores tanto a nivel regional.2. aligerando notablemente las cargas de computación. nacional o supranacional.0. existe una gran demanda de servicios de información geográfica de una enorme diversidad tanto en temática.. con el fin de realizar el menor numero de peticiones posibles y evitar. tanto en el lado del cliente como en el del servidor. por lo que resulta muy complicado poder integrar datos provenientes de mas de un servidor distinto. . usuarios.. disponibles para ser consultadas en un futuro sin tener que hacer uso de nuevo de las peticiones al servidor.. Quizá el principal tipo de herramientas optimizadoras en el campo de los proveedores de mapas sean las diferentes implementaciones de memorias de caché para almacenar datos de regiones y capas. creando de este modo un forma rápida y cómoda de consultar dicha información Haciendo uso de estas recomendaciones.
­ En el segundo capítulo se detallarán las distintas implementaciones WMS­C que van a ser testadas a lo largo del proyecto. dando así una clara idea del rendimiento que ofrecerán cada una de ellas en términos absolutos en función de las distintas condiciones a las que serán sometidos. 2. trabajando la tres sobre estándares WMS. y por otro lado se tendrá que poner a prueba cada una de las tres caches escogidas mediante es uso de la anterior aplicación sumada a otras ya existentes.­ En este capítulo se detallará cómo se lleva a cabo un Benchmarking o comparativa entre distintos sistemas de servicios Web de mapas 4. En nuestro caso hemos optado por la creación de dos aplicaciones diferenciadas.3.­ Como continuación se procederá a implementar las distintas aplicaciones que van a ser necesarias para la realización de las pruebas anteriormente descritas. GeowebCache y WMS – C – Wrapper. 0. destinadas a mejorar los sistemas de mapas.­ ESTRUCTURA DE LA MEMORIA Los objetivos principales del proyecto se centrarán en dos aspectos diferentes. 3. Para ello la memoria constará de los siguientes apartados: 1. Por un lado es necesario crear una aplicación que permita controlar los distintos parámetros de cada una de las peticiones Http que será necesario enviar al servidor.Las tres caches elegidas han sido TileCache.­ En un primer capítulo se presentarán las tecnologías de los Servicios Web de Mapas así como las propuestas WMS­C (Web Map Service ­ Cached) y WMTS (Web Map Tiling Service). por lo que los resultados obtenidos en las pruebas para un servidor concreto (en este caso Geoserver) pueden ser extrapolados a otro servidor de mapas cualquiera.­ Posteriormente será necesario analizar los diferentes resultados obtenidos mediante el uso de las aplicaciones anteriores y obtener conclusiones acerca del funcionamiento y rendimiento de las distintas implementaciones analizadas. La primera construida en python y las otras dos en JAVA. 5. 3 .
6. se adjuntan dos anexos que complementan la redacción del proyecto y sirven para ampliar conocimientos de cada uno de los capítulos principales.­ Finalmente se obtendrán las conclusiones y se sugerirán posibles lineas futuras de investigación y desarrollo. APENDICE I: instalación de las cachés APENDICE II: manual de uso de la aplicación 4 . Además.
1 SERVICIOS WEB DE MAPAS .
Cada una de estas peticiones define la capa y el área de interés que va a ser procesado. Un mapa no consiste por tanto en los propios datos. Del mismo modo. El estándar implementa tres operaciones distintas [5]. Devolver un mapa cuyos parámetros geográficos y dimensionales han sido bien definidos. 1. Devolver metadatos del nivel de servicio. GIF o JPEG y opcionalmente como gráficos vectoriales en formato SVG (Scalable Vector Graphics) o WebCGM (Web Computer Graphics Metafile). desde navegadores específicos a simples visores de imágenes. 2. Si analizamos un ejemplo podemos ver de que modo se incluyen todos los parámetros necesarios para que el servidor envíe la respuesta deseada por el cliente: 5 .1.1. 3. sino en la representación visual de estos. Esta interfaz también implementa la posibilidad de especificar ciertos grados de transparencia si se realiza una petición sobre distintas capas pero sobre un área idéntica. Devolver información de características particulares mostradas en el mapa (opcionales). la respuesta va a consistir en una o varias imágenes georreferenciadas que pueden ser visualizadas en diferentes aplicaciones. De este modo pueden ser visualizadas de forma conjunta y formando una sola unidad datos provenientes de varios servidores y/o capas. consiguiendo así una absoluta integración entre diferentes fuentes de datos y servidores de mapas en un sólo sistema[4].­ SERVICIO WEB MAP SERVICES El servicio Web Map Services (WMS) fue definido por el Open Geoespatial Consortium (OGC) [3] como estándar para la generación de mapas georreferenciados de forma dinámica a partir de información geográfica. Cada una de estas operaciones pueden ser invocadas por el cliente mediante un navegador estándar realizando peticiones en forma de URLs en las que se indican los diferentes parámetros. WMS proporciona una interfaz HTTP de fácil manejo para realizar peticiones de mapas georreferenciadas sobre una o varias capas provenientes así mismo de una o mas bases de datos geoespaciales. Este estándar internacional define un "mapa" como una representación de la información geográfica en forma de un archivo de imagen digital conveniente para la exhibición en una pantalla de ordenador. Los mapas producidos por WMS se generan normalmente en un formato de imagen como PNG.
Estas normas y recomendaciones tratan de conseguir un estándar de referencia a la hora de implementar tanto servidores como clientes de mapas para permitir la obtención de datos de manera independiente a su origen. Cada petición HTTP utilizada para obtener la información de los servidores ha de cumplir unos requisitos especificados en la norma ISO/DIS 19128. Un servidor WMS básico clasifica sus recursos geográficos en capas. que indica tanto los parámetros que han de especificarse. FondoUrbano. correspondientes a los máximos y mínimos del BBox en cada uno de los dos ejes (en el apartado 4 de la presente memoria se detallan estas coordenadas así como el método que se sigue para obtenerlas). Para indicar al servidor el área sobre el que se va a trabajar (Boundig Box o BBox) WMS implementa una referenciación absoluta indicada por cuatro parámetros. Esta norma Internacional sólo admite capas y estilos con nombres propios y especificados.http://www. que en este caso será una imagen png. Por último se incluye en la petición una referencia al tamaño (WIDTH y HEIGHT) de la imagen que se desea obtener. Vial y División territorial. 6 . Esta norma se aplica a un servidor de mapas que ofrece sus servicios para producir mapas más que a su capacidad de acceso a datos específicos.se_inimage&SRS=EPSG%3A4326&BBOX=­180%2C ­90%2C0%2C90&WIDTH=256&HEIGHT=256 Se puede observar que se efectúa la petición al servidor cartociudad indicándole que las capas requeridas son Topónimo. También se le especifica el formato de salida del mapa. el modo que se utiliza cada uno de ellos así como las operaciones que permite cada tipo de servidor.1. y ofrece un número finito de estilos predefinidos en el que mostrar las capas. y no incluye ningún mecanismo para que el usuario pueda efectuar una caracterización propia de los datos.ogc.cartociudad.1&REQUEST=GetM ap&STYLES=&EXCEPTIONS=application%2Fvnd.es/wms/CARTOCIUDAD/CARTOCIUDAD?LAYERS=Toponimo %2CDivisionTerritorial %2CFondoUrbano%2CVial&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.
nacen los actuales modelos de servidores y clientes de mapas orientados a la total convergencia y la interconectabilidad operativa.3.­ PROPUESTA WEB MAP TILING SERVICES (WMTS) Un concepto muy importante en el estándar WMS y por tanto en el desarrollo de este proyecto es el de tesela (tile en su terminología inglesa). 1. En caso de tener que efectuar de nuevo una petición sobre una tesela ya visualizada con anterioridad. será preciso efectuar una petición al servidor indicándole que teselas son las requeridas y a partir de que capas queremos obtener los datos.1. definido mediante el TilingStandard y concebido como una representación de una porción de terreno correspondiente a una o mas capas determinadas. una vez definido el área del que se desean obtener los datos. en un lugar intermedio. la propuesta debe de ser capaz de advertir al cliente de que un conjunto de teselas ya cacheadas está disponible para una determinada capa de un particular proxy WMS. Además. 7 . Basados en este concepto. el cliente tendrá que volver a actuar del mismo modo sin que la anterior petición agilice en modo alguno el proceso. en caso de desearlo.2. De este modo una área cualquiera de terreno puede ser subdividida en parcela regulares (generalmente de forma cuadrada) de tamaño variable en función de la resolución deseada. obtener datos de diferentes servidores. para de este modo simplificar y estandarizar las petición de datos al servidor y poder. El objetivo de una propuesta WMS Tile Cache (WMS­C) es encontrar una manera de optimizar la distribución de imágenes de mapas a través de Internet. las especificaciones concretas de los servicios implementados por los servidores [7] y otras varias que atañen a los clientes [8]. La propuesta debe de ofrecer algunos medios por los cuales los clientes puedan obtener teselas de los servidores existentes. y en las múltiples recomendaciones efectuadas por OsGeo (Open Source Geospatial Foundation) en referencia a cómo deben implementarse estas teselas (TilingStandard [6]).­ PROPUESTA WMS­C Tal como se ha visto en el apartado anterior. de tal manera que las imágenes pueden almacenarse en una caché en el servidor. o incluso ser completamente generados si se desea.
sino también a las teselas adyacentes en un radio concreto. SRS. y sólo a los niveles de escala particular en que fueron almacenados. Formato de salida fijo Obsérvese por tanto que los argumentos LAYERS. Esto invita a una serie de limitaciones a las solicitudes de WMS GetMap [9]: 1. Nombre de capa fijo (o al menos su orden) 7. a diferencia de WMS. Mínima cadena de argumentos en las consultas (no se permiten argumentos opcionales). HEIGHT. y FORMAT de una petición GetMap estarán fijados para una capa WMS­C de teselas. WIDTH. STYLES. 8 . dando así una sensación de continuidad absoluta en su navegación. activando opciones como el metatiling. 2. Rango fijo de posibles Bounding Boxes. podemos conseguir que el cliente efectúe peticiones no sólo referentes a las teselas indicadas. con el fin de optimizar el tráfico entre ambos. dos peticiones diferentes para una misma tesela WMS­C debe generar una petición HTTP GET idéntica. Por otro lado. Todos estos proceso tienen como fin dinamizar los procesos de visualización de los mapas y agilizar la obtención de resultados. Estilo fijo 8. Tamaño fijo de las teselas (en píxeles) 6. Precisión fija en los valores de los Bounding Boxes 5. un proxy WMS­C debe de tener libertad para devolver una excepción o redirigir la petición que recibe si ésta no es totalmente compatible o no corresponde a un Bounding Box que corresponda exactamente a una única tesela en la caché. Por ejemplo. Un servicio WMS­C probablemente sólo ofrecerá imágenes de Bounding Boxes ajustadas a un origen determinado y en rejilla rectangular.Con estos objetivos se definió el actual estándar WMS­C. pero las especificaciones de WMS obligan a que estos campos se incluyan en todas y cada una de las peticiones. 4. que bien podría definirse como un perfil limitado de WMS que permite almacenar teselas en algún punto intermedio entre el cliente y el servidor. Cadena de argumentos fija. La idea básica es que. 3.
dado que el servidor que utilizaremos será también un servidor local (concretamente GeoServer).En nuestro caso las teselas se almacenarán localmente en el lado del cliente. eliminando así de la comparativa el factor de dependencia referente a la conexión al servidor y a la disponibilidad de la linea de comunicaciones. 9 .
2 IMPLEMENTACIONES WMS-C .
2. la labor de las cachés para WMS es actuar de intermediario entre el servidor encargado de proporcionar las teselas y el cliente que es quien va a demandarlas.1. 10 . Por tanto. Como contrapartida. Como es lógico. cuanto más cerca del cliente se implementen estos sistemas más rendimiento vamos a obtener. las que la rodean son pedidas de forma conjunta. alcanzado un punto máximo si el cacheado se realiza de modo local. ya sea de modo local o en algún punto entre el servidor y el cliente. bien sea en el lado del servidor o en el del cliente. exige la necesidad de reservar espacios de memoria que pueden llegar a tener tamaños importantes según sea la máquina con la que se trabaje y la cantidad de teselas que se vayan a cachear. de modo que si deseamos acceder a ellas (habitual en las consultas realizadas en los servidores de mapas vía web) sólo tendremos que acceder a nuestra memoria local para obtenerlas. dado que las respuestas que hayan sido cacheadas y vuelvan a ser solicitadas estarán almacenadas en la propia máquina del usuario.­ CACHEADO EN WMS Según lo visto en el capitulo anterior. así como también acarreará una carga computacional añadida que puede suponer un lastre importante para otras operaciones que este llevando a cabo el usuario de manera simultánea a la consulta del mapa. dado que las comunicaciones a través de internet suponen en principio el principal cuello de botella en estas conexiones. el hecho físico de tener que almacenar las teselas. A priori esta labor podría ser llevada a cabo en cualquier punto intermedio entre ambos. Estos procesos deberían de propiciar una mayor velocidad en la navegación del cliente a través del mapa. cuantificar estos parámetros para conocer cuál de las implementaciones posee una mayor eficiencia tanto en el almacenamiento de las teselas (en nuestro caso en el propio disco duro local) como en el uso de recursos de la máquina. eliminando en gran parte los tiempos de espera para la interconexión. Será también objetivo de este proyecto. dando una sensación absoluta de continuidad en la navegación. los casos que vamos a estudiar se encuentran en el extremo más alto de eficiencia que se va a alcanzar con estos sistemas. ya que en el preciso momento en el que se solicita una tesela al servidor.
la capacidad de ejecutar scripts Python CGI y un servidor WMS para ser cacheado.2. como es lógico.­ GEOWEBCACHE Dado que Geowebcache nació como una adaptación de Tilecache construida en Java. intentando acercar la experiencia de usuario de estos sistemas a otros como los populares Google Maps o Yahoo Maps. TileCache nació como un prototipo o prueba de concepto para testear las capacidades de esta forma de recuperar cartografía en la web. dado que entre las tres cachés que van a ser analizadas. De esta manera las peticiones que incluyan teselas pedidas con anterioridad no serán remitidas al servidor sino que serán respondidas mediante el uso de esa información almacenada. 2. es la única que no está construida íntegramente en JAVA. Fue el primer intento serio de implementar una memoria caché que agilizase la comunicación servidor­cliente almacenando las peticiones para su posterior uso. Es un proyecto basado en Python que realiza la función de proxy entre un servidor WMS y un cliente WMS­C proporcionando una gestión de Cache para el almacenamiento de las teselas. 11 .2. En su modo más básico de uso.­ TILECACHE TileCache [10] es una implementación del WMS­C en la parte del servidor desarrollado por Metacarta Labs. integrabilidad en diferentes máquinas respecto a las implementaciones en JAVA. pero en la actualidad su uso ha decaído en gran medida debido a su que su construcción en Python le resta. Tilecache sólo necesita permisos de escritura y acceso a un disco de memoria. funcionando igualmente como proxy entre el cliente y el servidor y almacenando teselas a medida que éstas son requeridas. Será necesario tener en cuenta este aspecto de su arquitectura a la hora de analizar los resultados finales.3. ya podemos crear nuestra propia caché local de cualquier servidor WMS y utilizar los resultados en algún cliente que soporte WMS­C. Con sólo estos recursos. [11] comparte con ésta muchas de sus características.
añade a las características de Tilecache la posibilidad de trabajar en cualquier máquina que implemente un entorno de JAVA y presumiblemente. al estar construido íntegramente en JAVA. El sistema se encarga de respetar los tiempos recomendados de actualización de la información y de asegurarse de que la caché atiende a la mayoría de las peticiones de forma óptima gracias a su sistema de cacheado espacial y estadístico. 2. WMSCwrapper consiste en un filtro que permite transformar cualquier servidor de mapas estándar en un potente servidor de teselas y una fuente de imágenes para Google Earth. Para ello solamente se requiere un disco duro para realizar caché y un tipo de información que no deba actualizarse instantáneamente. está desarrollado completamente en java por el IDELab (laboratorio de Infraestructura de Datos Espaciales) perteneciente al grupo de investigación universitario ITAST (Infraestructuras. Además. Este sistema se encarga de adaptar las distintas peticiones de teselas para cachear las distintas áreas contiguas a la solicitada sin que en ningún caso haya una repetición en la solicitud. a priori un mayor rendimiento efectivo a la hora de gestionar las peticiones y las teselas GeoWebCache ha adelantado a TileCache como implementación más utilizada en la actualidad. De este modo conseguimos que cualquier servidor de información geográfica ofrezca un formato de salida compatible con los clientes que utilizamos. pudiendo compaginar y superponer de este modo capas e información provenientes de fuentes totalmente distintas de una manera fácil y rápida. Tecnologías. 12 . [12]. en la actualidad se considera la tecnología de referencia en el desarrollo de cachés destinadas a almacenar teselas en este tipo de servicios de información geográfica.­ WMSCWRAPPER Al igual que GeoWebCache.7.4.1 en adelante) ya incluyen esta imlementación por defecto. Aplicaciones y Servicios de Telecomunicaciones) de la Universidad de Valladolid. en gran medida debido a que las versiones más recientes de GeoServer (1.Evidentemente.
2: metatiling 4x4 13 . formando anillos concéntricos centrados en ella. mientras que en WMSCwrapper este comportamiento viene también influenciado por el hecho de si las teselas adyacentes están o no cacheadas.El metatiling tanto en TileCache como en GeowebCache funcionaría realizando peticiones sobre las teselas adyacentes a la que hemos solicitado. En la imagen vemos cómo funciona el metatiling para las tres cachés si no tenemos ninguna zona precacheada (En rojo tesela solicitada y en negro las que van a ser pedidas debido al metatiling) Imagen 2.1: metatiling 3x3 Imagen 2.
Sin embargo.3: TileCache y GeowebCache Imagen 2. Lo vemos en una imagen: Imagen 2. si tenemos una zona precacheada (en azul) antes de solicitar la misma tesela. los resultados no van a ser los mismos para TileCache y GeoWebCache que para WMSCwrapper.4: WMSCwrapper 14 .
si bien se adapta mejor a las zonas cacheadas.Como puede observarse. y por tanto tendremos una zona ya almacenada en las caches mayor que en el primer caso. es posible que genere un retardo mayor que sus competidores al tener que solicitar un porcentaje mayor de teselas al servidor (en el caso de la imagen. serían 3) La instalación y configuración de las diferentes implementaciones puede consultarse en el Apéndice I de este proyecto. existen tres teselas ya cacheadas que son solicitadas de nuevo. mientras que en WMSCwrapper. todas las teselas que van a ser solicitadas no han sido pedidas en ningún momento. en el caso de TileCache y GeowebCache. 15 . Este sistema de WMSCwrapper.
3 BENCHMARKING DE SERVICIOS WEB DE MAPAS .
el tipo de servicio que demandan y el tipo de información que tratan de obtener. A ojos del cliente el mapa siempre ha de mantener una continuidad y no ha de percibir el modo en el que las teselas van siendo cargadas y visualizadas en su navegador. los tiempos de espera si bien eran importantes. Ya no resulta admisible mantener un tiempo de espera que sea percibido por el usuario como una molestia en su navegación. El ingente desarrollo de las redes de comunicaciones globales y de la capacidad de procesado de los terminales de usuario propició que cada vez más clientes se interesaran por acceder a información geográfica.3. Para hacernos una idea de lo significativo o no de estos tiempos de espera y por tanto de la calidad de servicio que ofrece un determinado servidor surgen los Benchmarks o comparativas entre cada una de las diferentes cachés. sino que el servidor sólo atendía peticiones de un único cliente a la vez y normalmente de una sola tesela por cliente. el aumento de la demanda llevó aparejado un aumento no sólo de los clientes que realizaban peticiones sino también del número de peticiones por cliente.­ RETARDOS EN WMS Dada la apertura de los sistemas de mapas al gran público. Este cambio en el ratio de peticiones por cliente fue debido en gran medida a la sustitución del usuario institucional o administrativo.1. cambiando en gran medida el sistema de trabajo de los distintos servidores. En origen estos sistemas fueron diseñados para uso administrativo o militar. no eran determinantes en la comunicación. por un usuario particular con un patrón de búsquedas mucho más irregular y complejo para el servidor. En el primer escenario en el cual eran las administraciones quienes demandaban los recursos. por lo que en las peticiones que se realizaban al servidor no primaban criterios de velocidad u optimización de la atención a varios clientes simultáneos. dado que la información tenía que ser obtenida a partir de un servidor concreto que era el único que alojaba ese mapa. En la disposición actual el retardo en el ofrecimiento de las teselas es quizá el principal factor de calidad que rige la comunicación entre el usuario y el servidor. que demandaba un plano concreto para un fin determinado. se ha producido un cambio en el modo en el cual los usuarios acceden a la información. Si antes cada servidor se tenía que preocupar de servir unas pocas teselas a unos pocos usuarios. 16 . dado que el cliente demanda principalmente una gran interactividad y una sensación de continuidad en los mapas.
3.2.­ BENCHMARKS EN WMS
A lo largo de la historia de la informática, el uso de pruebas en detalle o benchmarks ha sido algo muy común, de forma que los resultados obtenidos de forma objetiva en las distintas arquitecturas mediante estas pruebas podían ser comparados. En general, la realización de pruebas comparativas no suele ser una tarea fácil y requiere de sesiones repetitivas para llegar a conclusiones útiles, siendo también difícil la interpretación de los resultados de las pruebas. Un factor a tener en cuenta durante la realización de las pruebas es que los fabricantes suelen afinar sus productos específicamente para los benchmarks más comúnmente utilizados en su sector, por lo que hay que tener especial precaución a la hora de interpretar los resultados. Además, los benchmarks generalmente, aparte de las mediciones cuantitativas del rendimiento de un sistema, no suelen tener en cuenta ninguna medición cualitativa acerca del servicio como pueden ser la seguridad, la disponibilidad, la confiabilidad, la escalabilidad, o el grado de conformidad con las especificaciones, las cuales son tan o más importantes que las anteriores [15]. Dentro del amplio espectro de pruebas de Benchmarking que existen para evaluar el rendimiento de casi cualquier componente software o hardware, hay dos campos que son de especial relevancia para el caso que nos ocupa en este trabajo: las bases de datos y los servicios web. Dentro de los objetivos de este proyecto no se encuentra el hacer un estudio en profundidad del rendimiento de los distintos gestores de bases de datos, ya sean libre distribución como MySQL y PostgreSQL o propietarias como Oracle Server y Microsoft SQL Server. Pero es interesante hacer mención de la existencia de multitud de benchmarks orientados a la evaluación de éstos, ya que las bases de datos, y en concreto aquellas que disponen de extensión espacial, son comúnmente utilizadas como repositorios para el manejo y acceso a la información geoespacial, bien sea de forma directa a través de clientes, o indirectamente por medio de servicios web de geo­procesamiento como es el caso de los Web Map Services. Existe además algunos estudios comparativos acerca de los rendimientos tanto de los servidores (nosotros sólo usaremos geoserver) como de las cachés en sí. Este último grupo es el que más nos interesa por ser el más parecido al estudio que vamos a llevar a cabo. Como ejemplo tenemos un estudio llevado a cabo por OpenGeo bajo el título “Comparing the Performance of Open Source Web Map Servers”, en el que se incluye entre otros muchos, un apartado comparativo entre GeoWebCache y Tilecache para unas determinadas condiciones.
Los resultados obtenidos son para Tilecache 2.04 y GeoWebCache 1.0­beta0 (en este proyecto las versiones a analizar serán 2.10 y 1.1.3 para Tilecache y GeoWebCache respectivamente), e indican un resultado muy parejo en una simulación concreta sobre Geoserver 1.7.0 (en nuestro caso será la versión 1.7.5)
Imagen 3.1: Estudio sobre TileCache y GeoWebCache
Estos resultados se han obtenido saturando una línea de conexión con el servidor de 100 Mbps, llegando a alcanzar en ambos casos (sus comportamientos son prácticamente iguales) una velocidad de 450 teselas por segundo. Dado que las distintas implementaciones de las cachés han ido mejorando y que en nuestro caso el servidor será local, es de esperar que se mejoren sensiblemente los resultados obtenidos en esta medición.
Así pues, la comparativa que llevaremos a cabo se basará principalmente en el tiempo de espera que ha de soportar el cliente a la hora de recibir una respuesta a su petición, dado que será éste el principal parámetro de medición de la calidad de servicio en este tipo de comunicaciones. Además también se reflejará una medición de la tasa de transmisión de teselas por parte del servidor, que dará idea del rendimiento comparativo para cada una de las implementaciones que vamos a estudiar. A partir de los datos anteriores es de esperar que lleguemos a las conclusiones necesarias para afirmar qué caché se comporta mejor en cada uno de los escenarios y cuál es el motivo de dicha diferencia.
4 DESARROLLO DE LA APLICACIÓN DE BENCHMARKING .
Generar un interfaz cómodo y simple que permita una rápida gestión de las variables y de los campos. 20 .­ ESQUEMA DE FUNCIONAMIENTO En este apartado se detallará la estructura que ha de seguir nuestra aplicación. será necesario dividir el trabajo a realizar entre más de una aplicación.­ OBJETIVOS DE LA APLICACIÓN Los objetivos generales en este apartado.2. Gestionar de manera rápida y sencilla todas y cada una de las variables incluidas en el las peticiones. cada una construida en el lenguaje y formato mas adecuado para sus respectivas funcionalidades. así como las partes de las que estará compuesta para su correcto funcionamiento. que se pueden resumir en 6 principalmente: Generar un archivo legible por Jmeter con cada uno de los campos y parámetros necesarios para las peticiones Http. – – – Generar un archivo legible por Jmeter con valores de los bboxes válidos.­ ARCHIVO DE JMETER Para la realización de las peticiones se utilizará la aplicación Jmeter. 4. Flexibilidad suficiente para poder ser adaptada en posteriores pruebas en entornos suficientemente similares. 4.1. serán los marcados al comienzo del proyecto.1. – – – Para cumplir estos objetivos contaremos además con otras aplicaciones ya desarrolladas y presentadas en anteriores apartados dentro de este mismo proyecto. que permite generar tráfico http con la condiciones que se deseen en cada momento.4. No generar demasiada carga computacional que pueda alterar los resultados obtenidos en las medidas de eficiencia. Dado que es necesario que realice un buen número de funciones.2.
21 .valor_por_defecto)} en determinados campos.jmx y deberá de tener los siguientes componentes: – – – – – – – grupo de hilos cuatro bloques de parámetros definidos por el usuario bloque de configuración de csv data set valores por defecto para una petición HTTP un bloque de petición HTTP un escritor de datos simple un generador de un sumario de resultados.jmx cuyo significado será explicado mas adelante): Imagen 4.El archivo que ha de crearse y ejecutarse cada vez que se quiera realizar una petición será del tipo . El esquema general del archivo . es posible introducir el valor concreto de estos campos mediante la utilización de argumentos del tipo ­Jvariable=valor_deseado.jmx una vez ejecutado por el Jmeter quedará por tanto de la siguiente forma (el nombre elegido es Non­GUI­Text. o en caso de no hacer uso de estos argumentos. cuando ejecutemos la aplicación. Esto se puede hacer mediante el uso de valores de variable del tipo ${__P(variable. el programa tomará por defecto el valor_por_defecto que hallamos agregado.1: Estructura generada en JMeter En archivos de Jmeter existe la posibilidad de no asignar un valor numérico concreto a las variables de cada uno de los bloques que hemos colocado. De esta manera.
1)} ● RAMP_UP: ${__p(ramp_up.EPSG:4326)} WIDTH: ${__P(width.py)} ● CSV: ${__P(csv.0)} ● VARIABLES DEFINIDAS POR EL USUARIO (para la petición HTTP) HOST: ${__P(host.256)} HEIGHT: ${__P(height.tilecache/tilecache.1.De esta manera en nuestro caso las variables que hemos colocado en cada uno de nuestros bloques han sido las siguientes: GRUPO DE HILOS: Nombre: WMS­C Users Numero de Hilos: ${THREADS} ● Periodo de Subida: ${RAMP_UP} ● ● VARIABLES DEFINIDAS POR EL USUARIO (para el grupo de hilos ) THREADS: ${__P(threads. )} ● PATH: ${__P(path.csv)} ● VARIABLES DEFINIDAS POR EL USUARIO (valores petición WMS­C) ● ● ● ● ● ● ● ● LAYERS: ${__P(layers.topp:hidrografia)} SERVICE: ${__P(service.localhost)} ● PORT: ${__P(port.txt)} VARIABLES POR DEFECTO PARA PETICION HTTP (listener) ● ● ● ● ● ● ● ● LAYERS: ${LAYERS} SERVICE: ${SERVICE} VERSION: ${VERSION} REQUEST: ${REQUEST SRS: ${SRS} WIDTH: ${WIDTH} HEIGHT: ${HEIGHT} FORMAT: ${FORMAT 22 .256)} FORMAT: ${__P(format.bboxes/bboxes.WMS)} VERSION: ${__P(version.1.image/png)} VARIABLES DEFINIDAS POR EL USUARIO (listener) ● OUT: ${__P(out.GetMap)} SRS: ${__P(srs.1)} REQUEST: ${__P(request.results.
la longitud de los laterales de cada tesela va venir determinado por una serie de valores numéricos concretos propios de esta tecnología.2.2. ha de estar en unos rangos pre­establecidos.CONFIGURACIÓN DEL CSV DATA SET NOMBRE: BBox from CSV ● NOMBRE DE ARCHIVO: ${CSV} ● VARIABLE: BBOX ● PETICIÓN HTTP ● NOMBRE: WMS­C Request ESCRITOR DE DATOS SIMPLE ● ● NOMBRE: Result Listener NOMBRE DE ARCHIVO: ${OUT} GENERAR SUMARIO DE RESULTADOS ● NOMBRE: Results Summary Todos estos datos tendrán que ser proporcionados al Jmeter en función de la caché que queramos probar. Por tanto se hace imprescindible construir una aplicación que genere grupos de teselas válidos o bounding boxes (bboxes) para las peticiones. Por tanto tendremos que crear un sistema para poder hacerlo. 4.­ GENERADOR DE BBOXES Todas las implementaciones de cachés con las que vamos a trabajar manejan sistemas de teselas (o tiles en su nomenclatura inglesa). la capa que deseemos. el numero de threads. Una tesela es una porción de mapa (en nuestro caso de forma cuadrada) de tamaño variable en función de la resolución. pero con la configuración actual. por lo que las aplicaciones que creemos tienen que adaptarse a este funcionamiento... En los sistemas WMS­C que vamos a utilizar. que representa una sección de una capa. El tamaño de las teselas no puede ser arbitrario. podríamos realizar ya una simulación de trafico satisfactoria. 23 ..
2: Teselización para resolución = 0 Imagen 4. y la segundo para una resolución de 2: Imagen 4. A. además de poder realizar el trabajo con poco esfuerzo tanto de desarrollo como de carga computacional a la hora de su ejecución. así como de las resoluciones máxima y mínima y el tamaño de cada tesela (ancho y alto).Dicha aplicación será generada en Java a través de eclipse dado que así podemos crear un sistema portable a otras maquinas y distribuciones. La primera la obtendríamos para la resolución mínima (0).3: Teselización para resolución = 2 24 . constando por tanto de sólo dos teselas. Dicha matriz está definida en los estándares de WMS.­ GENERACIÓN ALEATORIA DE TESELAS En primer lugar veamos cómo podemos generar un BBox válido a partir de los valores máximo y mínimo tanto en el eje X como en el Y del trozo de mapa que queremos tomar (para ser válidos estos valores también van a tener que cumplir unas condiciones que veremos más adelante). Además será necesaria una matriz (resmat[]) con los valores válidos de los tamaños de las teselas. Podemos visualizar lo que significa una teselización global a partir de las siguientes dos imágenes.
mientras que el segundo si: Imagen 4. En la primera figura el programa tendría que ser capaz de detectar que no le estamos indicando una zona correcta y por tanto elegir automáticamente la teselas que contiene. Se puede observar también que la precisión con la que se va a ajustar al contorno de la zona deseada va a depender en gran medida de la resolución a la que estemos trabajando: 25 . por lo que el hecho de que sea o no válido va a depender de la resolución a la que se trabaje.5: BBox válido Por tanto el primer objetivo que tendrá que salvar nuestra aplicación es implementar un corrector de coordenadas que nos calcule qué Bounding Box válido es el mayor dentro del que le indiquemos. en las siguientes dos imágenes podemos ver como en un caso el BBox elegido no será correcto para la resolución dada. la zona que se le indica a la aplicación es la dibujada en negro y la zona que él debe de tomar es la roja. Por ejemplo.4: BBox no válido Imagen 4. es necesario que contenga un número exacto de subdivisiones o teselas.Para que el BBox sea válido y podamos trabajar con el sin problemas. Si lo vemos en un dibujo.
Dado que conocemos la resolución a la que estamos trabajando.6:Resolución baja => poco ajuste Imagen 4.8:parámetro que caracterizan un BBox 26 . La siguiente imagen representa este hecho. El siguiente paso consistirá en ir proporcionando cada tesela contenida en esta zona de manera individual y aleatoria conforme a las especificaciones que deseemos. resulta sencillo saber cuantas filas y columnas de teselas tenemos dentro del área de trabajo.Imagen 4. por lo que podemos trabajar con él sin riesgo alguno. Imagen 4. el tamaño en píxeles que va a tener cada una de las imágenes que vamos a obtener y las coordenadas del BBox con el que estamos trabajando.7:Resolución mayor => mayor ajuste En este punto ya tenemos un BBox que incluye un numero entero de teselas.
como conocemos ambos factores. Por lo tanto. pero tomando como parámetros maxX y minX. Debido a la restricción antes impuesta. Evidentemente el número de filas y de columnas se irá multiplicando a medida que vaya aumentando la resolución tomada.9:Tesela seleccionada aleatoriamente y sus parámetros 27 . Finalmente bastará con elegir de manera aleatoria una fila y una columna para tener una tesela concreta. conocemos el tamaño exacto de cada una de las teselas.Sabemos que el ancho de una tesela (que será igual que el alto dado que las teselas con las que trabajamos van a ser cuadradas y denominaremos TileSpanX) va a ser el producto del tamaño en píxeles (por defecto normalmente serán 256x256) por un factor sacado de una matriz de elementos y que va a depender de la resolución. este número de filas y de columnas va a resultar siempre un número entero. En el siguiente ejemplo se habría elegido aleatoriamente la segunda fila (numrow=1) y tercera columna (numcol=2). Para las columnas se operará de igual forma. Para saber el número de filas de teselas que contiene nuestro BBox basta con operar maxY­minY y dividirlo entre el tamaño de las teselas ya calculado.Las filas se cuentan de arriba a abajo y las columnas de izquierda a derecha Imagen 4.
En nuestro caso contamos con una base de datos proporcionada por cartociudad en la que se incluye una lista de teselas de diferentes tipos y resoluciones conjuntamente con otros datos que no van a ser utilizados en la realización de este proyecto.csv. tilemaxX y tilemaxY separando cada elemento por una coma y escribiendo cada tesela en una linea separada del archivo. será necesario hacer uso de JDBC (Java DataBase Conectivity). La forma de efectuar esta conexión es simple.csv para su posterior uso. En nuestra aplicación se ha implementado un mecanismo para que la resolución a la que se toman las teselas pueda variar dentro de un rango indicado. Cabe reseñar que el orden en el que se escribe cada una de las cuatro coordenadas de cada tesela no es permutable. B.Para calcular los distintos parámetros de la tesela pedida se operará de la siguiente forma: tileminX = minX+numcol*TileSpanX tilemaxX=minX+(numcol+1)*TileSpanX tilemaxY=maxY­numrow*TileSpanY tileminY=maxY­(numrow+1)*TileSpanY De este modo ya tenemos una tesela con la resolución pedida y dentro del BBox indicado. de modo que cuando queramos obtener un archivo legible por Jmeter que las contenga sólo tengamos que efectuar un acceso a dicha base de datos y una transcripción al archivo . de manera que aunque la zona de trabajo quede fija desde un primer momento. Finalmente sólo resta escribir los datos de cada tesela en un archivo . tileminY. indicándole un usuario y un password válidos para el acceso a dicha base de datos (que habremos creado con anterioridad). Para permitir que la aplicación acceda a la base de datos. herramienta de Java que permite establecer conexiones con bases de datos. 28 . bastará con establecer una conexión mediante un driver. y será el siguiente (según se han nombrado en el dibujo): tileminX. el tamaño de las teselas dependerá de otro generador aleatorio que irá escogiendo la resolución entre los valores indicados.­ OBTENCIÓN A PARTIR DE UNA BASE DE DATOS Puede resultar interesante tener almacenadas en una base de datos las distintas teselas que van a ser utilizadas.
y1)). El formato en el que están registradas las teselas sería como se indica en la imagen: Imagen 4.x2. Conociendo el número de teselas que deseamos obtener bastará con leer un número de registros igual a a ese número de peticiones.x1.x2. podemos obtener los datos contenidos mediante consultas.Una vez establecida la conexión de manera correcta. tendriamos que: tileminX = X1 tileminY = Y2 tilemaxX = X2 tilemaxY = Y1 29 .x1.10: Parámetros de una tesela en formato Polygon Cada tesela estará representada como ((x1.y1.y2.y1. accediendo sólo a la columna deseada y transformar los datos que obtendremos (escritos en forma poligonal) al formato de cuatro coordenadas que estamos utilizando.y2. Si lo adaptamos a nuestro sistema. de manera análoga a como podría realizarse con postgresql o con cualquier otro gestor.
C. no será necesario configurar manualmente cada uno de los componentes ni las relaciones que se establecen entre ellos.De nuevo ya sólo resta escribirlo en el archivo . Dado que eclipse incluye opciones para crear aplicaciones gráficas de una manera sencilla y eficaz.­ INTERFAZ GRÁFICA. 30 .11: Interfaz gráfica de la aplicación BBoxgenerator como puede observarse no contiene una gran cantidad de información.csv correspondiente y cortar la conexión con la base de datos para no consumir recursos de una manera innecesaria. hemos optado por introducirle un interfaz gráfico que permita gestionar todos los parámetros de una forma mas sencilla y visual. ya que no existe la posibilidad de romper la conectividad por defecto. Para que el manejo de esta aplicación resulte mas sencillo. El aspecto que va a tomar nuestra interfaz va a ser el siguiente Imagen 4. pero si la precisa para poder gestionar de manera eficaz la generación de Bboxes válidos u obtenerlos a partir de la base de datos de cartociudad.
100. 31 . Hay que reseñar que a efectos del cálculo de la validez de la zona que posteriormente indicaremos como la zona deseada. la aplicación tomará el valor mínimo dentro del rango de resoluciones que le hayamos introducido. 0. La zona 4 permite establecer el nombre del archivo que va a ser generado con todos los Bboxes válidos. Por defecto generará un fichero llamado bboxes.csv En la zona 3 podemos introducir el numero de teselas que deseamos pedir así como una indicación de las que deseamos que estén repetidas de manera directa. En caso de que ésta se repita.Está compuesta por cuatro zonas o apartados: Imagen 4. Por tanto si por ejemplo indicamos que las probabilidades respectivas para una. volverá a hacer lo mismo con la posibilidad de que esté repetida una segunda vez (“prob 2 rep”) y así sucesivamente hasta cuatro veces.csv. posteriormente evalúa la probabilidad de que esta tesela esté o no repetida (“prob 1 rep” en el interfaz ).12: Componentes de la Interfaz gráfica de BBoxGenerator En la zona 1 podemos establecer las resoluciones mínima y máxima con las que vamos a generar los Bboxes. 0 cada tesela aparecerá tres veces. dos tres y cuatro repeticiones son: 100. Funciona de la siguiente manera: la aplicación genera los parámetros de un BBox particular y lo escribe en el archivo .
por lo que si le pedimos que nos genere 100 Bboxes. 32 . los valores que hayamos introducido no tienen por qué ser válidos. el programa sólo tendrá dos teselas donde elegir.13: Ejemplo de autocorrección de BBox Además de mostrarlo en un mapa. La ventana queda de este modo: Imagen 4. En las cuatro casillas superiores se debe de escribir las cuatro coordenadas del BBox que deseemos. es seguro que 98 de ellos como mínimo serán repetidos. No obstante si se desea una visualización de la zona que se ha escogido en referencia a un mapa del mundo. Como se ha visto anteriormente. se ha implementado la posibilidad de ver no sólo la zona que hemos elegido como nuestro BBox deseado. La zona 2 es quizá la que tiene un manejo mas complejo. sino también la zona que la aplicación tomará como corrección de la introducida por el usuario y que será el BBox válido mas grande dentro del que se le haya indicado. Si pensamos en el caso visto anteriormente para una resolución que se establezca en 0.Hay que tener en cuenta que en el proceso aleatorio de elección de teselas es posible que también se produzca alguna repetición. en las cuatro casillas que esta inmediatamente bajo las que hemos escrito los valores del BBox deseado aparecerán los valores válidos con los que la aplicación trabajará. que será el que la aplicación tomara. por lo que se ha diseñado un sistema que corrige dichos valores sin que el usuario tenga por qué advertirlo.
En caso de que resulte imposible generar un BBox válido a partir de los que le indique el usuario aparecerá una ventana de advertencia y los valores que tomará entonces la aplicación como correctos será los valores por defecto. todo el mapa completo. hemos decidido incluir un archivo de propiedades para que no sea necesario cambiar nada más que los valores precisos de estos. En esta zona también se encuentra el botón BBDD.csv ha sido generado. que permite obtener el número de teselas que se indique en en la casilla “number of Bboxes” directamente a partir de la base de datos de cartociudad. es decir. emergerá una ventana indicando que la operación ha sido realizada correctamente y el archivo . 33 . También ha sido necesario incluir un mecanismo para leer este archivo de propiedades y proporcionar los resultados a la aplicación. Finalmente si se han introducido todos los datos de manera correcta y se pulsa el botón OK. Dado que algunos parámetros puede que tengan que ser modificados una vez finalizada la labor de programación.
del modo siguiente.4 para su gestión. Este modelo tendrá dos gráficas para los dos juegos de resultados que obtendremos.­ REPORTE DE RESULTADOS Cada simulación efectuada por el Jmeter generará (como se vio anteriormente) un archivo . en función del numero de threads de la simulación y del tipo de caché testada. Para este proyecto. geowebcache1.. A. así como OpenOffice 2.3..­ Template.xls.csv con todos y cada uno de los resultados obtenidos. se ha utilizado Excel2003 para la generación del archivo modelo. y les asignamos valores siguiendo el siguiente patrón: nombre=DESREF(hoja1!primera_celda. Por lo tanto al finalizar todas las iteraciones existirán varios archivos del tipo tilecache1.xls Para la generación del archivo .csv (dado que a priori no conoceremos el número de threads utilizados) y a que cada uno contenga un número indeterminado de lineas (en función de número de bboxes).xls partiremos de un modelo flexible que permita visualizar los resultados de manera gráfica. es decir.csv.. El sistema ha de ser lo suficientemente flexible como para adaptarse a un diferente número de archivos . geowebcache.csv.CONTARA(hoja1!$A:$A)­1.. el tiempo medio por tesela y las velocidad medida en teselas por segundo que alcanza cada cache..xls existiría un conflicto a la hora de generar los nuevos ficheros csv. en nuestro caso tilecache.4. Seleccionamos la opción Insertar – Nombre – Definir. este archivo puede almacenar sucesivas pruebas para un numero de threads repetido. Definimos un nombre para la variable.. se ha optado por generar a partir de ellos un solo archivo que resuma los datos mas importantes en una sola tabla y que ésta sea visualizada gráficamente mediante un archivo . mientras que si no fueran escritos en un archivo . Para poder conseguir que las gráficas representen un número variable de entradas. Además. wmscwrapper y threads. Dado que no toda la información que contienen estos archivos es de utilidad para nuestra investigación.csv. los resultados se almacenarán de forma individual...2. si realizamos una simulación para 5 threads y posteriormente otra para 5 threads igualmente.1) 34 . tilecache5. haremos uso de definiciones de área mediante nombres.
pero se han incluido en el ejemplo para una mejor visualización. por lo que si le indicamos a una gráfica. 35 .xls zona superior Imagen 4. obtendremos una gráfica de mas o menos numero de columnas dependiendo de las casillas con valor en dicha columna. que ha de tomar los valores incluidos en dicha variable. que contendría las dos gráficas quedaría del siguiente modo Modelo de Template. Finalmente indicar que la única tarea que nos resta.Con esta función conseguimos definir un área que variará en función del número de valores que contenga la primera columna.xls zona inferior En el modelo que almacenaremos. no se encontrarían valores en las casillas numéricas. es sobreescribir los valores que se deseen incluir en el gráfico en cada una de sus correspondientes casillas mediante una aplicación que generaremos. De este modo el modelo.14: Modelo de Template.
csv que genera Jmeter en cada una de las ejecuciones (tilecacheNUMERODETHREADS. y calcular a partir de cada uno el tiempo medio por tesela y la tasa media de emisión de teselas por parte del servidor. Estos dos serán los parámetros que utilizaremos para calcular tanto la tasa de transmisión del servidor como el tiempo medio por tesela.csv.B.­ ALMACENAMIENTO DE RESULTADOS Y GENERACIÓN DE REPORTE En cada ejecución hemos decidido almacenar los datos relevantes en un archivo con el fin de poder tener un índice de ls ejecuciones con sus resultados propios. y lo establecemos como tiempo de origen o tiempo cero.csv). será necesario sobreescribir la hoja modelo de excel con los datos obtenidos y generar una visualización en linea de comandos con los mismos.csv y wmscwrapperNUMERODETHREADS. Para calcular el tiempo medio que emplea cada implementación en responder una tesela. seguidamente hallamos el momento exacto en el cual la última tesela llega al receptor hallando el máximo valor de una hipotética columna que nos reflejase el código temporal en el que cada respuesta llega al usuario (TimeStamp + elapsed) 36 . Para ello calculamos el mínimo de la columna TimeStamp. bastará con sumar el tiempo individual que emplea en cada una de ellas y calcular la media. Típicamente uno de estos archivos tendrá el siguiente formato: timeStamp elapsed 1258446582713 141 1258446582868 25 1258446582896 2 1258446582901 3 1258446582907 3 1258446582913 3 label WMS­C Request WMS­C Request WMS­C Request WMS­C Request WMS­C Request WMS­C Request responseCode 200 200 200 200 200 200 responseMessage OK OK OK OK OK OK threadName dataType success bytes bin 562 WMS­C Users 1­1 true bin 562 WMS­C Users 1­1 true WMS­C Users 1­1 true bin 562 WMS­C Users 1­1 true bin 562 bin 562 WMS­C Users 1­1 true bin 562 WMS­C Users 1­1 true TimeStamp es un código temporal correspondiente al momento exacto del envío de cada petición por parte del Jmeter y elapsed es el tiempo que tarda cada tesela en ser respondida por parte del servidor. geowebcacheNUMERODETHREADS. Para calcular la tasa será necesario conocer el lapso de tiempo total desde que se envía la primera de las teselas hasta que la última es recibida por el usuario. Cuando finalicen todas las ejecuciones. para luego poder calcular los parámetros que se crea convenientes y poder mostrarlos en el modelo anterior. Para ello partiremos de los archivos .
37 . En primer lugar se parte de una hoja de cálculo vacía.54 WMSCwrapper 601.01 TileCache 1.7 703. resulta necesario almacenar estos datos individuales en un archivo . 1 y 2 respectivamente. Al final de las tres iteraciones si consultamos el archivo store. Como se puede ver dos entradas distintas tienen el mismo valor para la columna threads. despues “store 1” de nuevo y finalmente “store 2”.99 Cada una de las lineas será por tanto el resultado de una simulación distinta.52 AVG RATE GeoWebCache 431. Como se dijo anteriormente. De este modo obtenemos los datos de cada una de las cachés para cada prueba individual. Para ello haremos uso de POI. pero diferentes valores para el resto dado que pertenecen a pruebas independientes.Una vez hallados los valores inicial y final del experimento.83 602.11 1.74 1. bastará dividir el numero total de teselas pedidas entre el tiempo total del ensayo y transformarlo en segundos multiplicando por 1000.45 858. El método usado para almacenar los datos es sencillo.69 499. será necesario introducir una bifurcación dentro del código.82 2. un API para JAVA [16] que permite crear y gestionar hojas de cálculo de una manera rápida y sencilla.02 1.xls para su posterior uso.83 1. Como sólo se quiere tener una aplicación para realizar dos funciones (ir almacenando los datos a medida que se generan y generar el archivo gráfico al finalizar todas las ejecuciones).xls.46 2. En nuestro caso hemos optado por hacerlo a partir de los argumentos que se introduzcan en la ejecución: “store” seguido del numero de threads en el caso de que se pretenda almacenar los datos o simplemente “0” para el caso de que se quieran mostrar los resultados finales.94 646. podremos encontrarnos con los siguientes resultados: threads 1 1 2 WMSCwrapper 1. por cada prueba individual para un numero de threads concreto.6 AVG TIME GeoWebCache 1.7 419. bastará con ejecutar al final de cada iteración (cuando los archivos . a la cual se añade una linea.jar primero con los argumentos “store 1”. con los datos obtenidos como se explicó anteriormente.19 TileCache 27.csv estén completos y en su lugar) la aplicación JmeterReports. Así por ejemplo si se realizan tres ejecuciones con unos valores del numero de threads de 1.
se ha incluido un archivo de configuración y un sistema interno para leerlo con el fin de simplificar la configuración de las aplicaciones y poder introducir cambios en las rutas a los archivos de entrada y salida con facilidad.xls que tenemos almacenado en la sección de recursos y escribir las celdas adecuadas para que éste muestre las gráficas deseadas. se ordenarán todas las entradas en función del numero de threads de cada una.jar.Una vez que se ha creado el archivo de almacenamiento store. dado que es posible que algunas pruebas hayan sido repetidas. la tabla las mostrara de forma diferenciada. por lo que si existen dos o mas pruebas repetidas. hemos decidido implementa otra funcionalidad que escribe una tabla de resultados en la linea de comandos con todos los datos obtenidos en las distintas iteraciones. Este proceso se llevará a cabo en dos fases. En primer lugar. para posteriormente ir leyendo las distintas lineas del archivo y e ir calculando las medias de las que estén repetidas. 38 .jar con el argumento “0”. Una vez que tenemos sólo los valores que queremos mostrar.xls. bastará con acceder al modelo template. En una primera operación. Esta tabla tomas los datos directamente a partir del archivo store. bastará con ejecutar JmeterReports. será necesario calcular la media entre las distintas entradas con un valor igual de la columna thread. Al igual que en el caso de BboxGenerator. Para una visualización rápida.xls y habiendo finalizado todas y cada una de las diferentes pruebas que se quieren mostrar.
dado que la naturaleza de estas tareas requiere de un administrador con suficientes permisos para ello. así como un repositorio a partir del cual se pueda.4. pudiendo así fomentar la colaboración de una manera muy notable y permitiendo además trabajar reutilizando módulos ya existentes. El uso de SVN permite además que varias personas estén trabajando y modificando el mismo proyecto de manera simultanea. Para ello se ha creado una estructura que defina el software a construir y sus dependencias. se hace necesario la creación de una estructura que permita su portabilidad a cualquier ámbito y su accesibilidad dentro de los servidores en lo que se trabaja.4.2. Tanto la definición de la estructura de Maven como la creación de repositorios en el servidor del laboratorio. 39 . tanto descargar la aplicación como actualizarla. Estas estructuras permiten también alojar recursos (como template. corrieron a cargo de técnicos del propio laboratorio. modificarla o simplemente integrarla en otros proyectos Maven.­ ESTRUCTURA MAVEN – SVN Dado que se pretende integrar los resultados y los métodos que componen este proyecto con otros proyectos y trabajos llevados a cabo por el IDELAB.xls) dentro de la estructura reduciendo así el número de archivos externos que el usuario va a tener que manejar.
siempre que se tengan los permisos necesarios para ello.sh Este script consiste en una serie de ordenes encaminadas a introducir todos los datos que son necesarios para el correcto funcionamiento de la estructura que hemos construido con el Jmeter. dejando los datos obtenidos de otras capas intactos. dado que se encuentra ubicados en la carpeta /tmp/ del sistema de archivos 40 ..2. Su funcionamiento es muy simple. Tanto TileCache como WMSCwrapper pierden sus caches al cabo de un tiempo determinado.4. Además funciona como elemento de cohesión entre los distintos elementos y permite direccionar los flujos de datos en función de donde se encuentren ubicados cada uno . así como proporcionar una visualización del punto en el que se encuentra el proceso en un determinado momento.png. Para facilitar la labor hemos creado este sencillo script.5. A.. PATH. lo único que hay que hacer es localizar estos archivos dentro de las direcciones de las caches y eliminarlos . En función de la capa a la que se haya accedido es posible realizar un vaciado parcial.­ SCRIPTS A la hora de llevar a cabo cada una de las pruebas. HOST. Esto facilita la tarea de configuración de todo el sistema mediante unos pocos cambios en su código.­Clean_caches.­ Benchmark. Para solucionar este problema nos hemos planteado la opción de crear tres sencillos scripts que facilitan sensiblemente la tarea y reducen la posibilidad de error al introducir todos los datos que se requieren para cada una de las simulaciones. Dado que las teselas son almacenadas en formato .sh En muchos casos es necesario proceder al vaciado de las caches para poder controlar y restringir su uso en determinadas situaciones. B.. sería necesario realizar una orden que incluyese cada una de las variables recogidas en el archivo de Jmeter (OUT.) para todas y cada una de las iteraciones.. lo que supondría ralentizar el proceso y provocar la existencia de posibles errores.
sh 1. luego . provocará que ejecutemos un . Asi por tanto una ejecución del tipo ./benchmark./clean_caches.sh 4 cleancache 7 8.sh 8./benchmark.­ Bench_start.jar con el argumento correspondiente para la realización del reporte de los resultados (0)./benchmark. realizará automáticamente una llamada a la aplicación JMeterReport con el fin de almacenar los resultados de esa iteración concreta. así como la gestión del script clean_caches.sh. Si no se desea añadir argumentos a la hora de la ejecución. Justo después de la ejecución de .C. Este script ofrece la posibilidad de indicarle el numero de threads deseados para cada ejecución. así como ordenarle o no la limpieza de caches entre cada una de las ejecuciones.sh y la eliminación de los archivos pertenecientes a anteriores ejecuciones.sh 10./benchmark. la función tomará los valores que le hemos asignado por defecto./bench_start. o bien efectuar una prueba por defecto. es decir.sh 5 y finalmente . Finalmente ejecutamos la aplicación JmeterReports. 5 y 10 respectivamente sin realizar vaciado en las cachés. ejecutará . luego un .sh para distintos valores de la variable THREADS.sh Tiene como finalidad ejecutar el script benchmark. posteriormente ./benchmark.sh 4. con los valores de threads iguales a 1.sh 7 y finalmente . 41 ./benchmark./benchmark.
4. tamaño. tanto en formato . llame al script benchmark.sh para cada valor de la variable Thread indicado y genere los archivos de salida.­ RESUMEN El esquema final del montaje realizado quedaría como indica la figura: Imagen 4.csv como las gráficas en formato .sh para que éste limpie las cachés.jar para generar el archivo con los bboxes con las características que desee en cuanto a resolución. Posteriormente bastará con ejecutar el script bench_start.6.2. o bien las tomará de la base de datos de cartociudad.xls 42 . zona deseada.15: Estructura del montaje final El cliente ejecutará la aplicación BboxGenerator.
3. Hemos conseguido una aplicación que además de generar bboxes válidos para realizar las peticiones con un interfaz de fácil comprensión.­ CONCLUSIONES Si analizamos las funcionalidades de las aplicaciones creadas y las características que buscábamos al comienzo del apartado. se ha implementado la posibilidad de promediar entre las distintas pruebas repetidas sin el menor perjuicio para el rendimiento del programa. necesaria en este proyecto.4. sino que además se han añadido otras que originalmente no se encontraban en el proyecto. 43 . permite delimitar una zona cualquiera del mundo y calcular a partir de ella los bboxes válidos siempre y cuando la resolución sea lo suficientemente grande como para permitirlo. podemos ver que no sólo se cumplen todas y cada una de ellas.jar a parte de conseguir igualmente todos los objetivos marcados en un principio. La principal preocupación a la hora de la realización de las aplicaciones ha consistido no sólo en aportar una funcionalidad garantizada y robusta. Por otro lado se ha añadido también la posibilidad de obtener los bboxes a partir de una base de datos data. sino también un manejo sencillo y una gran portabilidad a otras máquinas para la futura realización de pruebas similares. En cuanto a la aplicación JmeterReports.
5 ANÁLISIS DE RESULTADOS .
0. con el fin de evitar las distorsiones que se pueden producir al tomar un número que no sea representativo de las situaciones y cargas normales de trabajo. es decir. Cabria esperar que el rendimiento del servidor vaya variando en función del nivel de saturación al que va a estar sometido. alojado como servidor local. para lo cual podemos ir aumentando progresivamente el número de hilos generados hasta un máximo que se ha tomado en 20. podemos afirmar que los resultados cualitativos serán extrapolables a cualquier otra situación. pero dado que este proyecto trata de establecer una comparativa entre las distintas cachés. como ya se ha indicado con anterioridad será GeoServer [13]. Las pruebas se han realizado en una máquina Compaq Presario C700 con una conexión a internet vía ADSL de 2Mb. han de ser realizadas sobre un número suficientemente grande de peticiones. si el factor limitante de la comunicación es la capacidad de procesado del servidor (como es esperable).04.­ INTRODUCCIÓN En primer lugar cabe indicar que los siguientes resultados puede variar en términos absolutos en función de la máquina en la que se realicen. las condiciones de trabajo en las que se encuentre o de la conexión a internet de la que se disponga. estableciéndose un valor máximo estable si se produce en él un “cuello de botella”. mientras que los datos sobre los que se realizarán las peticiones han sido obtenidos de cartociudad [14]. y todas han sido testadas bajo las mismas condiciones. 44 .5. El servidor utilizado. Para que las pruebas tengan el mayor rigor posible. Resulta además igual de interesante saber como se va a comportar cada caché al variar el número de usuarios que tratan de acceder a unos mismos recursos. con un sistema operativo Ubuntu 8.
para posteriormente enviárselas a través de cada una de las diferentes implementaciones de caché. es interesante ver en que medida va a afectar el hecho de tener que pasar todas las peticiones por un sistema intermedio en lugar de enviarlas directamente al servidor.2: Reducción en la tasa de servicio de teselas para TileCache 45 . al cual le enviamos peticiones de manera directa.5. En cada una de las siguientes gráficas podemos observar la Imagen 5.1: Retardo provocado por TileCache Imagen 5.­ RETARDO AÑADIDO Antes de proceder al análisis de las diferentes cachés que se van a analizar.1. Para ello utilizamos un servidor local WMS (GeoServer). Evidentemente para este estudio no puede repetirse ninguna tesela dado que sería almacenada en las caches diferencia entre cada tecnología y una situación de envío directo de peticiones al servidor: y se desvirtuarían los resultados.
4: Reducción en la tasa de servicio de teselas para Geowebcache 46 .En la imagen 5.2 puede observarse como el servidor de teselas ofrece una tasa constante de 40 teselas por segundo independientemente del numero de usuarios que tenga. esta tasa efectiva se sitúa entre los 30­35 teselas por segundo Imagen 5. mientas que si tenemos que enviar las peticiones a través de TileCache.3: Retardo provocado por Geowebcache Imagen 5.
por lo que se pierde mas de un 50% de la eficiencia inicial del servidor Imagen 5.En el caso de Geowebcache tal y como puede verse en la imagen 5.4. la tasa efectiva de servicio de teselas se va a situar en unas 18 por segundo.5: Retardo provocado por WMS­C­Wrapper Imagen 5.6: Reducción en la tasa de servicio de teselas para WMS­C­Wrapper En este último caso la reducción en la tasa de provisión de teselas por parte del servidor llega hasta casi un 25% respecto al obtenida en un escenario sin caches entre en cliente y el servidor WMS. 47 .
48 .Vemos en general como el efecto que provocan las distintas caches que interponemos entre el servidor y el cliente ralentizan el proceso de comunicación entre ambos entre un 50% en el caso de Geowebcache y un 15% para TileCache. Este aumento en los tiempos de espera tendrá que ser compensado por el aumento en los rendimientos que se obtendrá cuando se estudien las ventajas del almacenamiento de teselas para cada una de las caches.
Para ello utilizamos la misma configuración de la prueba anterior pero rellenando previamente las caches con todas las teselas que van a ser solicitadas.2.7: Tiempo medio de respuesta. comparativa caches­servidor local 49 . En primer lugar vemos la diferencia existente entre una situación sin caches. De este modo el cliente no tendrá que enviar ninguna petición hasta el servidor. y los resultados obtenidos para cada una de las caches que estamos testando: Imagen 5.­ GANANCIA Una vez cuantificado el retardo que añade el hecho de tener que pasar todas las peticiones a través de un nuevo sistema intermedio entre el cliente y el servidor (las caches) vamos a analizar ahora el ahorro de tiempo que supone obtener las teselas a partir de las caches en lugar de recibirlas desde el servidor. y por tanto teniendo que recibir las solicitudes desde el servidor.5.
Imagen 5. comparativa caches­servidor local Podemos ver en la gráfica anterior como se obtienen unas tasas de servicio muy superiores en el caso de solicitar las teselas a las caches que en el caso de tener que conseguirlas desde el servidor. Si cuantificamos las ganancias como el resultado de dividir las distintas tasas de provisión de teselas de las caches entre la tasa de la situación sin caches. obtenemos el siguiente grafico: Imagen 5.8: Tasa de provisión de teselas.9: Tasa de provisión de teselas. ganancias de las caches respecto a servidor local 50 .
independientemente del numero de usuarios que estén enviando solicitudes. mientras que en el caso de las caches este parámetro si que va a condicionar ligeramente el rendimiento. 51 . Se puede observar también que la respuesta del servidor es siempre lineal.Podemos ver como el rendimiento del sistema se multiplica por un factor entre 8 y 12 aproximadamente en función de la cache utilizada y del numero de usuarios simultáneos.
86 400.6 1360.3 TileCache 1024.69 1313.05 Se puede observar que el mejor comportamiento va a ser siempre para Geowebcache.72 5341.49 630. por lo que es interesante conocer a qué velocidad pueden procesar las peticiones que van a tener que ser enviadas obligatoriamente al servidor.55 500.67 395.28 1963.86 1793.5.02 960.42 GeoWebCache 539.28 431.10: Tiempo medio de respuesta en almacenamiento threads 1 2 3 4 5 6 7 8 9 10 15 20 WMSCWrapper 755.69 1490.26 708.35 2140.33 539. que se mantiene estable en el entorno de los 500 ms hasta que se superan los 10 usuarios simultáneamente.95 444.95 2303.15 2797. Para ello probamos en primer lugar a realizar peticiones sobre teselas totalmente diferentes y con un rango variable de resoluciones.65 1286. De el hecho de que se mantenga estable el tiempo de respuesta aunque se vayan añadiendo más usuarios se puede deducir que el factor limitante en este caso no va a estar en la capacidad del servidor de ofrecer teselas.­ VELOCIDAD DE ALMACENAMIENTO Inicialmente las caches respectivas de las diferentes implementaciones van a estar vac ías.74 750.3.25 806.38 419.01 1072.47 470.78 673.61 461. sino más bien en la tasa de solicitudes que tenga 52 .54 487.2 491.14 629.51 782.65 3458.27 1335.7 1459. Imagen 5.
84 4. por lo que podemos deducir que el sistema alcanza su máximo rendimiento antes que para Geowebcache.08 3.37 2.17 5.52 11.18 4.59 7.11: Tasa media de transmisión en almacenamiento threads 1 2 3 4 5 6 7 8 9 10 15 20 WMSCWrapper 1. a partir de este punto ambas cachés parecen estar saturadas.69 16.36 4.63 GeoWebCache 1. puede observarse como existe un punto de mínimo tiempo de espera para cuatro usuarios y que a partir de este punto éste se dispara.56 4.93 5.88 4.25 7.46 TileCache 1.55 12.47 8.17 4.73 2.65 12.69 7. mientras el máximo tanto para TileCache como para WMSCwrapper está entre 7 y 8 teselas por segundo para un máximo de 4 usuarios.04 3.24 4.54 16. 53 .91 5.06 6. En el caso de WMSCwrapper y TileCache.el cliente.26 4.04 4.07 En esta gráfica puede verse que el máximo rendimiento para Geowebcache se sitúa en casi 20 teselas por segundo para 15 usuarios. Esto se hace más obvio si analizamos los resultados obtenidos para las tasas o rendimiento de los tres sistemas: Imagen 5.43 5.81 4.36 3.09 8.54 17.5 16.94 19.
También es interesante analizar el espacio en memoria que ocupa cada una de las cachés para almacenar las teselas.07 Kb de memoria por cada tesela almacenada.64 elementos por cada tesela mientras que GeowebCache genera 1. 54 . Esto se debe claramente a la forma de estructurar las memorias y al número de archivos que genera cada una. Concretamente TileCache genera 1. que ocupa 3.1 y WMSCwrapper sólo uno (datos tomados para un total de 100.745 Kb por tesela y finalmente WMSCwrapper que tan sólo ocupa 0. ya que TileCache almacena las teselas con un amplio sistema de carpetas que consumen una buena cantidad de memoria. La implementación menos eficiente es claramente TileCache.000 teselas almacenadas en cada caché).714 Kb/tesela. seguido por Geowebcache con 0. mientras que las otras dos generan muchos menos.
82 2.­ VELOCIDAD DE ACCESO Quizá el factor más importante es la velocidad que puede alcanzar cada una de las diferentes implementaciones a la hora de servir teselas ya cacheadas en memoria.51 4 5.59 31.85 28.02 3.47 2.68 6.03 1.92 44.84 23.37 13.44 7. Los resultados son los siguientes: Imagen 5. Para ello cacheamos en primer lugar 100.5.2 8.82 14.87 55 .48 7.61 17.96 27.3: Tiempo medio de respuesta en servicio desde cachés threads 1 2 3 4 5 6 7 8 9 10 15 20 WMSCWrapper 1.31 6.56 16.15 13.59 27.69 27.5 3.09 4.53 TileCache 1.88 5.98 GeoWebCache 1.35 16.67 8.17 55.41 15.46 12.61 2.3.000 teselas y posteriormente efectuamos las pruebas para distinto número de usuarios sin vaciar las memorias.8 11.
43 547.36 669.Como era de esperar en un principio. En cuanto a la tasa o rendimiento.45 475.84 615.63% en el tiempo de respuesta de cada tesela.12 330.92 353.2 695.3 570. TileCache obtiene los peores resultados con un 63.81 GeoWebCache 494.27 783.38 721.78 56 .53 720.13: Tasa media de respuestas en servicio desde cachés threads 1 2 3 4 5 6 7 8 9 10 15 20 WMSCWrapper 642. lo que da idea de que el sistema está trabajando a máximo rendimiento desde el mismo momento en el que tenemos un sólo usuario.49 599.35 313.29 521.74 443.63 610.65 849.43 317.73 439.52 493.88 TileCache 381.24% de incremento en sus tiempos medios.45 485. seguido por Geowebcache con una aumento del 9.78 468.3 470.93 709. como es obvio el mejor comportamiento responde exactamente a los mismos patrones que la gráfica anterior: Imagen 5. el tiempo que tarda cada petición en ser contestada por el servidor aumenta cuantos más usuarios intentan acceder de manera simultanea.24 867. Los resultados indican que WMSCwrapper es la implementación que tiene una mayor velocidad de acceso.57 535.73 631.95 605.72 576.33 595.09 424.25 513.01 476.
por lo que podemos afirmar que todas tienen un máximo rendimiento para un tráfico generado por entre 2 o 3 usuarios. alcanzando en el caso de WMSCwrapper tasas de hasta 867 teselas por segundo. ya que se puede observar que las tres siguen un patrón casi idéntico en la situación de sus puntos máximos y mínimos.En esta última gráfica queda claro que el rendimiento de las distintas implementaciones sigue las mismas normas. 57 . mientras que Geowebcache y TileCache llegan a 721 y 605 respectivamente.
Imagen 5.42 384.18 2278.14: Tiempo medio de respuesta 75% cacheado threads 1 2 3 4 5 6 7 8 9 10 15 20 WMSCWrapper 232.62 479. mientras que se tengan que obtener del servidor externo un 25%.8 376.57 435.88 221 321.06 450.59 5109.5.5.7 474.99 58 .26 1340.26 1872.3 1048.39 712.4 425.95 565.24 334.43 486.77 1400.73 936. En primer lugar vamos a probar cómo se comportan en una situación en la cual el 75% de las peticiones se hagan a las caches internas.08 658.14 321.38 620.32 GeoWebCache 125.2 3084.67 1819.16 889. es importante saber cómo se comporta cada una de las caches ante distintos escenarios y porcentajes de teselas cacheadas.­ PETICIONES MIXTAS Para dar idea del rendimiento en situaciones reales.65 1520.25 1196.7 537.7 503.55 TileCache 176.35 2756.75 664.9 413.
58 TileCache 5.5 9.75 4.93 36.28 Vemos que Geowebcache puede continuar aumentando su tasa de devolución de peticiones para mantener aproximadamente constante el tiempo de respuesta de cada tesela.16 15.32 6.67 4.97 GeoWebCache 8.65 5.78 7.85 6. mientras que tanto TileCache como WMSCwrapper se saturan y provocan un tiempo de respuesta siempre creciente.61 5.79 14.48 9.85 16.15: Tasa media de servicio 75% cacheado threads 1 2 3 4 5 6 7 8 9 10 15 20 WMSCWrapper 4. mientras que tanto TileCache como WMSCwrapper se saturan desde el principio y por tanto no son capaces de ir aumentando su rendimiento a la par que aumenta el numero de usuarios.71 15.72 30.43 5.39 5.12 6.86 4.7 4.18 22.61 9.54 5.26 8.22 22.6 7.25 5.09 8.En este caso vemos que Geowebcache es el único que más o menos mantiene unos tiempos constantes de respuesta a pesar de ir aumentando los usuarios.09 6.84 6.13 4. Si analizamos las tasas de cada uno de ellos: Imagen 5.53 3. 59 .9 6.
92 518.75 2575.77 790.16 1205.15 724.3 60 .67 352.26 589.52 1196.97 677.24 1601.24 3861.56 865.79 1038.13 466.33 484.5 2314.76 543.2 566.41 1456.51 451.Analizamos ahora una situación análoga pero con un 50% de respuestas cacheadas.27 533. El resultado para los tiempos de respuesta por tesela será el siguiente: Imagen 5.21 440.38 584.58 GeoWebCache 169.07 TileCache 294.22 631.54 1594.16: Tiempo medio de respuesta 50% cacheado threads 1 2 3 4 5 6 7 8 9 10 15 20 WMSCWrapper 270.77 2545.5 976.15 549.68 384.38 1643.18 518.63 629.13 731.
54 16. A priori cabria esperar un comportamiento muy similar pero con un aumento en los tiempos de respuesta y una disminución en las tasas efectivas proporcionales a la disminución de otro 25% en la cantidad de respuestas que van a ser cacheadas.28 4.87 5.01 13.84 4.45 16.21 5. hacemos la misma prueba pero limitando en este caso el número de respuestas cacheadas al 25%.22 8. Por último.88 6.49 4.12 6.53 9.28 5.77 Puede observarse también un patrón idéntico.% 33% y 18% respectivamente para WMSCwrapper Geowebcache y TileCache.3 5.65 7.72 6.98 3.34 5. Los resultados para los tiempos de respuesta son: 61 . salvo que al tener menos respuestas cacheadas.07 6.Imagen 5.53 7.17: Tasa media de servicio 50% cacheado threads 1 2 3 4 5 6 7 8 9 10 15 20 WMSCWrapper 3.72 11.31 TileCache 3.66 7.94 28.23 8.93 7.05 10.09 12.9 4.98 5. Este porcentaje está en consonancia con el 25% de respuesta cacheadas que hemos reducido.77 4. todas las tasas se ven un reducidas en un 27.42 30.49 6.32 3.31 GeoWebCache 5.
72 1426.99 Y en el caso de las tasas: Imagen 5.55 2006.98 697.23 880.27 672.86 TileCache 704.27 548.45 1012.67 1126.29 696.91 1305.6 3003.4 1843.65 595.Imagen 5.25 3384.33 1183.19 984.98 1163.61 616.05 1110.81 1113.12 3631.53 1034.7 623.04 597.19: Tasa media de servicio 25% cacheado 62 .18 1143.64 GeoWebCache 433.81 1099.18: Tiempo medio de respuesta 25% cacheado threads 1 2 3 4 5 6 7 8 9 10 15 20 WMSCWrapper 795.56 584.96 1276.81 1502.96 787.76 507.16 1405.55 1649.
5 2.61 8.87 9.84 6.98 3. el comportamiento de Geowebcache se mantiene estable dentro dentro del rango de usuarios al que lo hemos sometido.3%.3 Si calculamos de nuevo la variación respecto al caso anterior.4% respectivamente para WMSCwrapper. Esto confirma nuestra idea inicial en la estabilidad del comportamiento de las distintas cachés.8% y 37.49 1.67 GeoWebCache 2.68 23. Geowebcache y TileCache. 25.29 4.14 4.48 11.74 3.37 6.39 2.95 11.6 4.11 20. Para conocer el techo de la tasa de devolución de teselas para Geowebcache realizamos una prueba extra añadiendo un rango mucho más amplio aunque menos detallado de usuarios.18 6.34 5.68 2.11 5.6 4.24 9.36 5.45 2.49 4. vemos que en este caso la reducción de las tasas se sitúa en 20.49 10.threads 1 2 3 4 5 6 7 8 9 10 15 20 WMSCWrapper 1.83 4. mientras que TileCache y WMSCwrapper se saturan con un número relativamente bajo de usuarios y se mantienen en esas tasas.65 3.22 5.55 TileCache 1.16 8.76 3. Como puede observarse en el desarrollo de las pruebas mixtas. para una situación de obtención de teselas sin cachear: 63 .27 5.11 3.
Imagen 5.21: Tasa media de servicio Geowebcache Puede observarse que se mantiene en tiempos de espera más o menos estables hasta un máximo de 20 usuarios simultáneos.20: Tiempo medio de respuesta Geowebcache Imagen 5. 64 . llegando en ese momento a la saturación del sistema. Puede decirse por tanto que Geowebcache tiene una capacidad de admisión de teselas simultáneas muy superior a lo que han demostrado tanto TileCache como WMSCwrapper.
22: Comparativa del tiempo medio de respuesta en función del área de metatiling 65 .6. Además. el metatiling consiste básicamente en la solicitud automática de teselas alrededor de la zona indicada por el cliente. por lo que los resultados absolutos no tienen por qué coincidir con otros tomados anteriormente. Por otro lado. Por cada petición que realicemos.­ METATILING Como ya se explicó en apartados anteriores. se viera compensado por el hecho de lograr tener cacheada un área importante rodeando a dicha zona. 9 0 25 teselas centrada en la deseada. ahorrando por tanto la realización de más peticiones que acarrearían un retardo mayor. De este modo se logra pre­ cachear áreas de terreno que es probable que el cliente consulte con posterioridad. en realidad realizaremos una consulta a una zona de 1. que por cada tesela que deseemos solicitar al servidor. aunque dado que el objetivo es realizar un benchmark comparativo no tiene porqué afectar. nuestro cliente solicitará conjuntamente un número de teselas mayor.5. cabe esperar que los retardos disminuyan como consecuencia de la inclusión de mas teselas en las caches: Imagen 5. 3x3 y 5x5. esto es. también sería conveniente que este aumento en el tiempo de espera por cada tesela solicitada. el estudio se realiza para un único usuario simultaneo y sobre una zona delimitada. En nuestro caso vamos a estudiar un metatiling de 1x1. Este estudio ha sido llevado a cabo en otra máquina distinta. por lo que al aumentar el numero de teselas solicitadas en cada petición. por lo que cabe esperar que los tiempos de espera hasta recibir respuesta del servidor aumenten considerablemente.
23: Comparativa de la tasa de provisión de teselas en función del área de metatiling Como se puede ver en las imágenes 5.22 y 5. mientras que para un valor de 3x3 se encuentra empatado con TileCache.Imagen 5. la tasa efectiva final aumenta de manera considerable debido a que cada vez un mayor porcentaje de teselas serán obtenidas de las cachés.23. Este aumento del rendimiento de WMSCwrapper respecto a sus competidores al aumentar el tamaño de la zona cacheada en cada solicitud se debe al distinto tratamiento que cada una de las tecnologías hace del metatiling. Si comparamos los resultados de cada una de las distintas caches entre sí. a medida que aumentamos el número de teselas solicitadas con cada petición. mientras que TileCache y Geowebcache sí pueden repetir solicitudes. 66 . dado que WMSCwrapper trata de adaptar el contorno de las zonas solicitadas de modo que no se le pida al servidor ninguna tesela que ya haya sido cacheada. podemos observar cómo WMSCwrapper proporciona un menor tiempo de espera y por tanto una tasa de transmisión efectiva de teselas superior para un metatiling de 5x5.
Para ello vamos a realizar una medici ón utilizando la herramienta Jmeter. – Imagen 5.7. Un bloque de petición HTTP con los siguientes datos: – – – – – – Nombre de Servidor o IP: localhost Puerto: 8888 Path: /manager/status Será también necesario mandar un parámetro con la petición con Nombre XML y el valor true. Geowebcache y WMSCwrapper.5. Obviamente compararemos resultados obtenidos para ambas cachés en las mismas condiciones de trabajo de la máquina.2. ordenándolas en base al número de usuarios en cada prueba. es decir. obteniendo datos sólo cada 5000 ms. para no entorpecer la actuación de la aplicación.24: Configuración de Jmeter para la medición del uso de recursos De este modo podemos obtener los datos referentes a las dos implementaciones que trabajan sobre el gestor de contenedores Apache Tomcat. – Temporizador constante. Un bloque de Resultados del Monitor para visualizar los resultados.­ USO DE RECURSOS Es importante tener también en cuenta el nivel de utilización de los recursos de la CPU que van a consumir cada una de las diferentes caches .1 otro grupo de hilos con los siguientes componentes: Gestor de Autorizaciones HTTP: será necesario introducir user y password del tomcat. Esto se consigue añadiendo a la configuración explicada en el apartado 4. 67 . configurada para calcular los parámetros de utilización de aplicaciones web.
por lo que los resultados no podrían ser comparados con los obtenidos de este modo. Además en todos los apartados anteriores. la linea azul representa el porcentaje de la carga computacional.La linea roja representa el porcentaje de hilos ocupados respecto al máximo permitido. haciendo un uso de la memoria y una carga computacional análoga. No se incluyen resultados para TileCache dado que el sistema de medición debería de ser otro completamente distinto a no estar gestionado por el contenedor de paquetes tomcat de la misma manera que Geowebcache y WMSCwrapper.25: Comparativa del consumo de recursos para un usuario Los resultados son prácticamente los mismos en ambos casos. la linea amarilla el porcentaje de memoria utilizada respecto al total. por lo que su utilización no va a ser en ningún caso la más indicada. El indicador de la salud de la aplicación en ambos caso es del 100% para esta prueba. Probamos a continuación para un número de usuarios de cinco simultáneos: 68 . Comenzamos la prueba con un solo usuario : Imagen 5. y la linea verde da una idea de la salud general del sistema para la prueba concreta. TileCache ha demostrado ser la implementación menos efectiva en todas y cada una de las situaciones.
Imagen 5.27: Comparativa del consumo de recursos para 15 usuarios 69 . Aumentamos ahora el numero de usuarios hasta los 15: Imagen 5.26: Comparativa del consumo de recursos para 5 usuarios Vemos que de momento los resultados se siguen manteniendo muy parejos en ambas situaciones. por lo que a estas alturas de la prueba las dos cachés siguen funcionando al mismo ritmo y sin aparentes problemas de sobrecarga.
que si bien se han visto sutilmente incrementadas respecto a los casos anteriores. este alza no llega a afectar a la salud total de la aplicación. Aumentamos ahora el número de usuarios hasta situarlo en 35. Donde se podría esperar que la salud del sistema comenzase a resentirse. Imagen 5. En cuanto a la diferencia entre ambas caches . si bien pueden observarse unas cargas y unos usos de memoria ligeramente importante. pero todavía no puede decirse que la salud de las aplicaciones se encuentre comprometida. exactamente del mismo modo que para un numero menor de usuarios. y el uso de la memoria se acerca en algunos puntos al 100%. esta diferencia no es sustancialmente 70 . pero no se nota un aumento considerable ni en la carga computacional que está soportando el sistema ni en la utilización de la memoria total. inferiores en WMSCwrapper que en Geowebcache.28: Comparativa del consumo de recursos para 35 usuarios La carga total que implica el aumento de usuarios supera ahora en algunos momentos el 50% del total.Se puede observar ahora como es evidente el aumento en el porcentaje de hilos que están siendo utilizados respecto al máximo permitido. que se mantiene en todo momento al tope de sus posibilidades.
éstas tienen una duración menor.Aumentamos el número de usuarios hasta 50 simultáneos.29: Comparativa del consumo de recursos para 50 usuarios Por último realizamos las pruebas para 75 usuarios simultáneos: 71 . por lo que ahora si. pero son más acusados para Geowebcache que para WMSCwrapper. Estos efectos generales sobre los distintos parámetros que estamos midiendo son compartidos por las dos cachés. que si bien alcanza también cotas igualmente bajas en el nivel de salud. vemos como el sistema empieza a resentirse y se alcanzan puntos en los cuales la salud del sistema se ve comprometida y desciende hasta un 65­70%. Imagen 5.
De los distintos resultados podemos concluir que para un numero relativamente bajo de usuarios (hasta 30­35) el sistema mantiene sus parámetro más o menos constantes y parejos para ambas. llegando incluso en a sufrir una caída en el uso efectivo de memoria y en la carga computacional debido a dicha saturación al alcanzar los 75 usuarios. mientras que si superamos este umbral Geowebcache degrada sus prestaciones a un mayor ritmo que WMSCwrapper.30: Comparativa del consumo de recursos para 75 usuarios En estas dos últimas pruebas podemos observar como un exceso de usuarios simultáneos satura el sistema impidiendo que la aplicación correspondiente responda las peticiones que recibe. 72 .Imagen 5.
5. siempre se va a ver cómo WMSCwrapper obtiene unos resultados cada vez más distantes de sus competidores debido al sistema adaptativo de petición de teselas en función de las ya solicitadas. llegándose a la conclusión de que tanto en el caso de WMSCwrapper como en el de Geowebcache o TileCache se produce un retardo por petición similar para una zona de metatiling de 1x1. Por un lado tenemos los resultados referentes a la capacidad y velocidad de los sistemas. que es la que ofrece unos tiempos de espera mayores. si analizamos situaciones mixtas en las cuales tengamos un porcentaje de teselas cacheadas y otro de teselas por cachear. Como consecuencia de estos comportamientos. bastará que un pequeño porcentaje de teselas tengan que ser solicitadas al servidor para que los resultados de Geowebcache sean mejores que los de WMSCwrapper. También se ha analizado el efecto del metatiling en cada una de las implementaciones. mientras que WMSCwrapper es la que obtiene unas mayores tasas de respuestas por segundo. Por su parte TileCache obtiene en todos los estudios los peores comportamientos en relación con sus competidores. Debido a la diferencia que existe entre el tiempo de espera por cada tesela sin cachear y por cada tesela cacheada (entre 500 y 1000 veces superior en el caso de tener que realizar la petición al servidor). podemos concluir que Geowebcache posee unos resultados muy superiores a sus dos competidores a la hora de pedir teselas y almacenarlas en la memoria local.8. En cuanto al servicio de teselas ya cacheadas TileCache sigue manteniendo el peor resultado. tanto a la hora de almacenar las teselas como a la hora de servirlas.­ RESUMEN De los completos tests que hemos realizado sobre cada una de las tres caches sometidas a estudio podemos llegar a varias conclusiones generales que se subdividen en dos campos. mientras que si aumentamos mas este parámetro. 73 . Ciñéndonos a los tiempos de espera y las tasas de provisión de teselas que tienen cada una de las tres implementaciones. y por otro los relativos a las cargas y usos de memoria. los resultados de Geowebcache y WMSCwrapper irán convergiendo cuanto mayor sea el ratio entre las teselas cacheadas y las teselas sin cachear. muy por encima de los resultados de WMSCwrapper y TileCache. En el caso de extenderla a 3x3 WMSCwrapper y TileCache obtienen mejores resultados que Geowebcache.
nos hemos ceñido solamente a WMSCwrapper y Geowebcache.En cuanto al estudio de los recurso que consume cada caché. llegando incluso para Geowebcache a producirse caídas importantes en el uso de memoria y en el porcentaje de carga. 74 . pero en ambas caches se nota una saturación importante por encima de los 60­75 usuarios simultáneos. manteniendo una salud general del sistema óptima y unos usos de memoria y de carga computacional que se van incrementando a medida que aumentamos el número de clientes. la salud del sistema se va deteriorando con mayor velocidad en el caso de Geowebcache que en el de WMSCwrapper. En general los resultados obtenidos son realmente parejos para uno número de usuarios relativamente bajo (menos de 30­35 usuarios). que son las implementaciones que funcionan de un modo similar sobre el contenedor de aplicaciones Apache Tomcat. A partir de este umbral en el número de usuarios.
6 CONCLUSIONES Y LÍNEAS FUTURAS .
si bien no eran predecibles a priori. En cuanto a los objetivos fijados al principio del proyecto puede decirse que se han cumplido todos y cada uno de ellos. los resultados son claros y. o el manejo de aplicaciones Web.­ CONCLUSIONES A lo largo de este proyecto se ha ilustrado el funcionamiento de los servidores de mapas WMS. modular y de un manejo rápido y sencillo. sí son lo suficientemente sólidos y consistentes como para ser tomados como correctos. y que además puede ser adaptado para posteriores pruebas en entornos similares sin un excesivo trabajo. También se han descrito las distintas herramientas que se utilizan en las mediciones y las configuraciones que requieren para su correcto funcionamiento. pero también iniciarme en el mundo de los sistemas geográficos y las tecnologías de los sistemas de mapas. investigación. así como las interconexiones necesarias.1. su utilización y propiedades. En lo referente a las pruebas en sí. software. Personalmente. Además considero que hemos realizado un trabajo que ha abarcado diferentes cuestiones (teoría. ya que se ha conseguido alcanzar los objetivos que se marcaron al comienzo del proyecto de una forma totalmente satisfactoria. campo de gran auge en la actualidad debido a multitud de soportes muy populares y muy utilizados hoy en día. ya que se ha conseguido construir un sólido mecanismo de pruebas para las distintas caches. 75 . portable ( al estar construido en JAVA ). robusto. así como una descripción de la tecnología WMS­C y en particular de los distintos sistemas de cacheado de teselas que se implementan. la valoración que hago del trabajo realizado a lo largo del desarrollo del proyecto es francamente positiva. como pueda ser la programación en JAVA.6. permitiéndome ahondar en conocimientos ya esbozados durante algunas asignaturas de la carrera.) que me permiten tener ahora una visión general sobre cómo trabajan y como se desarrollan herramientas orientadas a la gestión de mapas. Se ha establecido un método para la comparación de tres de las opciones disponibles en el mercado y se han construido las aplicaciones necesarias para su correcto desarrollo. etc.
. Del mismo modo sería interesante conocer cuáles son los tiempos de latencia de las teselas en las caches que optimizan el gasto de recursos frente a la posibilidad de demandar zonas ya almacenadas. por lo que sería necesario realizar un estudio sobre las mejoras en el rendimiento general de la aplicación que va a percibir el usuario final del servicio como consecuencia del sobrecacheado de teselas. sino que se establezca un punto a partir del cual se distribuyan las peticiones ya almacenadas a los clientes sin necesidad de consumir los recursos locales.2. de modo que en definitiva sólo tenemos una idea general de como se comportan las distintas aplicaciones.6.. que la tesela se encuentre cacheada en la memoria o que ésta tenga que ser solicitada al servidor. Resultaría interesante establecer planes de peticiones en base a consultas reales para conocer además el verdadero alcance del metatiling. área. En nuestro caso se han establecido los rendimientos estadísticos basándonos en dos posibles circunstancias.). pero no ciñéndose al comportamiento que suele seguir un usuario. capa. 76 . pero en ningún caso se ha relacionado la petición de una tesela con la siguiente. En este proyecto se ha estudiado solamente el efecto del metatiling en el retraso que sufre cada petición respecto a una situación análoga pero sin esta opción activada. Por otro lado también puede resultar interesante combinar las distintas tecnologías que hemos probado con otros servidores de mapas o simplemente configurarlas para que no almacenen las teselas de forma local.­ LÍNEAS FUTURAS El análisis llevado a cabo en este proyecto se ha basado en unas secuencias de peticiones de teselas aleatorias dentro de unas determinadas condiciones fijadas(resolución. y que arrojarían resultados mas coherentes a un uso real de estos servicios. Existen estudios que establecen patrones de comportamiento en las peticiones efectuadas por el cliente.
77 .6. y por supuesto a todos los amigos que en estos años me han hecho sentir en casa fuera de mi casa. me gustaría agradecer a toda la gente que me ha apoyado durante la realización de este proyecto. así como a mi familia por la tremenda paciencia en tantos años de estudio más allá de los éxitos y los fracasos. no habría sido posible su realización sin la colaboración de sus integrantes. También agradecer a Cecilia su contribución “artística” y su apoyo absoluto en los buenos. especialmente de Ricardo. malos y regulares momentos a lo largo de todo este tiempo. saber hacer y sobre todo su paciencia. Dado que esta tarea se enmarca dentro de los trabajos del departamento ITNT­ ITAST de la universidad de Valladolid. por su tiempo.3.­ AGRADECIMIENTOS Para acabar.
[1] www.abcdatos.com (última consulta 10/10/09) [2] http://es.wikipedia.org/wiki/Sistema_de_Informaci%C3%B3n_Geogr%C3%A1fica (última consulta 18/11/09) [3] http://www.opengeospatial.org/standards/wms#schemas (última consulta 07/10/09) [4] en.wikipedia.org/wiki/Web_Map_Service (última consulta 10/12/09) [5] OGC Implementation Specification (http://portal.opengeospatial.org) (última consulta 21/10/09) [6] http://wiki.osgeo.org/wiki/TilingStandard (última consulta 10/10/09) [7] http://wiki.osgeo.org/wiki/Tile_Map_Service_Specification (última consulta 21/12/09) [8] http://wiki.osgeo.org/wiki/WMS_Tiling_Client_Recommendation (última consulta 21/10/09) [9] http://wiki.osgeo.org/wiki/WMS_Tile_Caching (última consulta 21/10/09) [10] http://tilecache.org/ (última consulta 03/10/09) [11] http://geowebcache.org (última consulta 03/10/09) [12] wmsc­wrapper documentation http://localhost:8888/WMS_C_wrapper/ (última consulta 03/01/10) [13] geoserver.org/ (última consulta 19/11/09) [14] www.cartociudad.es (última consulta 01/12/09) [15] http://presentations.opengeo.org/2008_FOSS4G/WebMapServerPerformance­ FOSS4G2008.pdf (última consulta 10/12/09) [16] poi.apache.org/ (última consulta 1/11/09)
INSTALACIÓN DE LAS CACHÉS
4 hardy haeron. Se instalará de la misma forma que el anterior.1. a partir de los repositorios oficiales disponibles para Ubuntu y haciendo uso del gestor de paquetes por defecto Synaptic. es necesario la instalación y configuración de ciertos elementos que se encuentran fácilmente en muchas máquinas sin los cuales sería imposible llegar a los resultados deseados. ya que algunas de ellas necesitan de otras para su correcta implantación y/o configuración. ni de instalación. 1. 1. En nuestro caso se instalará a partir de los repositorios oficiales de Ubuntu y mediante el uso del gestor de paquetes Synaptic Java runtime enviroment: permite la ejecución de programas en Java. En este primer apartado de requisitos previos se enumeran los distintos componentes necesarios para soportar el resto de la estructura que se creará. 1 .0.­ INSTALACIÓN DE COMPONENTES Para el ensamblaje de los distintos elementos que van a ser necesarios en el correcto desarrollo del proyecto. se hará un breve comentario sin entrar a detallarlos en profundidad. se hace necesario la instalación tanto del Java development kit como del Java runtime enviroment. Dado que en muchos casos son bastante comunes y no requieren un esfuerzo ni de configuración. Java development kit(jdk): es un software que provee herramientas de desarrollo para la creación de programas en java. Por lo tanto aquí se exponen en el orden y con el método con el cual fueron instaladas.­ JAVA Dado que tanto la aplicación que vamos a crear como muchas otras ya existentes está programadas en Java. es necesario seguir unas ciertas instrucciones proporcionadas por los distribuidores de las distintas herramientas e instalarlas en el orden apropiado.1.­ REQUISITOS PREVIOS Dada la naturaleza del proyecto que se va a desarrollar. Todos los trabajos y pruebas efectuados en este proyecto fueron realizados en una máquina Compaq C700 bajo un sistema operativo Ubuntu 8.1.1.
org). A continuación se detalla el método de instalación: 2 .0. está desarrollado por la Apache Software Foundation. como en nuestro caso Apache. En nuestro proyecto se hace necesaria la presencia de un servidor web dado que las pruebas de los distintos modelos de caché se realizan mediante peticiones HTTP dirigidas al servidor a través de cada una de las tecnologías. 1.). estando escrita en Java. Esta herramienta está desarrollada bajo el proyecto Jakarta en la Apache Software Foundation.1. Windows.apache. Macintosh.­ APACHE WEB SERVER Este servidor web HTTP de código abierto escrito en C. se considera que se optimizan sus prestaciones si se combina con otro servidor mas potente. En nuestro caso se ha instalado la versión 6.2.3. lo que permite su funcionamiento en cualquier máquina que contenga la maquina virtual Java. por lo que la descarga. Aunque puede funcionar de forma autónoma como servidor web por si mismo. por lo que es indispensable un servidor de este tipo que las gestione. cuyo código fuente se encuentra disponible en su página web oficial (http://tomcat.. y diseñado para casi cualquier plataforma (Unix.­ APACHE TOMCAT Apache Tomcat funciona como un contenedor de servlets (programas ejecutados en un servidor) y de Java Server Pages (desarrolladas por Sun Microsistems).. siendo en la actualidad el mas utilizado en el mundo debido principalmente a su gran capacidad de adaptarse a múltiples entornos debido a que es fácilmente configurable. instalación y configuración se realizaron de forma casi automática.1. si bien carece de interfaz gráfica que facilite este proceso. En nuestro caso se instaló la versión Apache2 directamente desde los repositorios oficiales de Ubuntu y mediante el uso del gestor de paquetes Synaptic.1.
0.18. las siguientes lineas se agregan al final de archivo: #vim .06 Entonces la variable de entorno JAVA_HOME debe apuntar a usr/lib/jvm/java­6­sun. si no nos sale esto.tomcat-6.gz Entramos a nuestro directorio hogar en nuestro caso /home/pablo/ #cd /home/pablo Ahora.0.6.18.0.tar. debemos buscar la ruta en donde se instalo java Ahora agregamos la variables de entorno a nuestro archivo . vamos a configurar las variables de entorno JAVA_HOME y CATALINA_HOME Probamos: #ls /usr/lib/jvm/ Si nos sale: java­6­sun java­6­sun­1.bashrc. Nota: Los números varían según la versión.Nos logeamos como root: su passwd: Copiamos el archivo descargado a /usr/local/ #cp /media/Datos/Software/Sistemas\ Linux/Servidores\ Web/Apache\ Tomcat/ apache.bashrc 3 .gz /usr/local/ Descomprimimos y desempaquetamos: #tar -zxvf apache-tomcat-6.tar.
Si deseamos parar nuestro servidor web: #/usr/local/apache-tomcat-6.18/temp Using JRE_HOME: /usr/lib/jvm/java-6-sun Probamos en un navegador web: http://localhost:8080/ Si nos aparece la página de Apache Tomcat.18/bin/shutdown.0.18 Salimos y guardamos cambios.0.0.18/webapps/ROOT/ El archivo de configuración de Apache Tomcat es: #vim /usr/local//apache-tomcat-6.18/conf/server. todo esta correcto.18 Using CATALINA_HOME: /usr/local/apache-tomcat-6.Agregamos al final: export JAVA_HOME=/usr/lib/jvm/java-6-sun export CATALINA_HOME=/usr/local/apache-tomcat-6.18 Using CATALINA_TMPDIR: /usr/local/apache-tomcat-6.sh Nos muestran los siguientes mensajes: Using CATALINA_BASE: /usr/local/apache-tomcat-6.0.18/bin/startup.0.0. ahora tendremos soporte para código de jsp y servlets de java.0. Ahora levantamos nuestro servidor Apache Tomcat #/usr/local/apache-tomcat-6.xml 4 .sh El directorio de publicación es: #cd /usr/local/apache-tomcat-6.0.
1.5.gz 1. las aplicaciones basadas en la plataforma Eclipse pueden ser extendidas fácilmente por otros desarrolladores de software. una organización independiente sin ánimo de lucro que fomenta una comunidad de código abierto y un conjunto de productos complementarios.2.2.0. ideada para un fin muy concreto. Debido a que los módulos pueden ser desarrollados independientemente. capacidades y servicios.18. pueda ser extendida para su uso en otros entornos similares al que nos ocupa. extendiendo constantemente las áreas de aplicación cubiertas. Eclipse fue desarrollado originalmente por IBM como el sucesor de su familia de herramientas para VisualAgel. En cuanto a la instalación en nuestra máquina resulta extremadamente sencilla.org (en nuestro caso instalamos la versión 3. Eclipse es ahora desarrollado por la Fundación Eclipse.­ ECLIPSE La plataforma Eclipse permite que las aplicaciones sean desarrolladas a partir de un conjunto de componentes de Software llamados módulos. así como una guía de cómo han sido instaladas y configuradas en nuestra máquina. 1. Un módulo es un archivo Java que contiene clases de java escritas para interactuar con las APIs de Eclipse y un archivo especial (manifest file) que lo identifica como módulo. Eclipse es también una comunidad de usuarios. ya que no es necesario mas que bajarse el instalador de la versión deseada directamente desde su página web http://eclipse. la última disponible hasta la fecha de 5 .tar.­ COMPONENTES ESPECÍFICOS En este apartado se incluirán descripciones mas detalladas de las herramientas utilizadas a lo largo del proyecto. logrando así que aplicaciones como la nuestra. Las aplicaciones construidas a partir de módulos pueden ser extendidas agregándole nuevos módulos.Podemos eliminar el fichero descargado al terminar la instalación: #rm -r /usr/local/apache-tomcat-6..
y el orden de construcción de los elementos. sino también para subir artefactos al repositorio al final de la construcción de la aplicación. sus dependencias de otros módulos y componentes externos. será necesario instalar un gestor de proyectos. ejecutar el archivo del instalador y seguir los pasos indicados por el mismo para su configuración. para cualquier otro lenguaje. pero su adopción ha sido muy lenta. Maven utiliza un Project Object Model (POM) para describir el proyecto de software a construir. Maven provee soporte no sólo para obtener archivos de su repositorio. el repositorio Maven . Este repositorio y su sucesor reorganizado. Dado que también serán necesarios otros componentes que interactúan con Eclipse. dejándola al acceso de todos los usuarios. Una caché local de artefactos actúa como la primera fuente para sincronizar la salida de los proyectos a un sistema local. En teoría. en nuestro caso nos hemos decantados por utilizar Maven. 6 . pugnan por ser el mecanismo de facto de distribución de aplicaciones en Java. Una característica clave de Maven es que está listo para usar en red. el soporte y uso de lenguajes distintos de Java es mínimo. esto podría permitir a cualquiera escribir plugins para su interfaz con herramientas como compiladores. de Apache y otras organizaciones y desarrolladores. etcétera. en nuestro caso Subversion (SVN) para poder actualizar los distintos repositorios creados a medida que vayan siendo modificados. Actualmente existe un plugin para . Maven está construido usando una arquitectura basada en plugins que permite que utilice cualquier aplicación controlable a través de la entrada estándar.Net Framework y es mantenido. El motor incluido en su núcleo puede dinámicamente descargar plugins de un repositorio.[1] y un plugin nativo para C/C++ fue alguna vez mantenido por Maven. Además se utilizará también un sistema de control de versiones.realización del proyecto). herramientas de pruebas unitarias. Viene con objetivos predefinidos para realizar ciertas tareas claramente especificadas como la compilación del código y su empaquetado. el mismo repositorio que provee acceso a muchas versiones de diferentes proyectos Open Source en Java. En realidad.
requisiciones FTP y prácticamente cualquier otro medio. siendo capaz de manipular resultados en determinada petición y reutilizarlos para ser empleados en una nueva secuencia. 7 .Para la instalación tanto de Maven como de SVN basta con abrir el Eclipse.2. ya que basta con descargar el programa desde su página web oficial (en nuestro caso la versión elegida es la 2. En el siguiente paso se seleccionan los paquetes que van a ser descargados e instalados y finalmente se reinicia Eclipse. posee la capacidad de realizar desde una solicitud sencilla hasta secuencias de peticiones que permiten diagnosticar el comportamiento de una aplicación en condiciones de producción. programas en Perl. ir a Help – Install New Software – Add.org/JMeter . hoy en día. Inicialmente diseñada para pruebas de estrés en aplicaciones web. descomprimir el fichero y ejecutar el archivo JMeter situado en la carpeta bin. su arquitectura ha evolucionado no sólo para llevar acabo pruebas en componentes habilitados en Internet (HTTP).6. sino además en Bases de datos. En nuestro caso utilizaremos esta aplicación para simular el tráfico que genera un visor de mapas hacia el servidor en las peticiones de información y para interpretar las respuestas que produzca este.­ JMETER JMeter es una herramienta de carga para llevar acabo simulaciones sobre cualquier recurso de Software. o de cualquier otro cliente.org/ para Maven).org/update_1.x para SVN y http://m2eclipse.codehaus.4. la mas reciente hasta el momento de la realización del proyecto) http://jakarta. Además. ya sean en forma de imágenes (resultado deseado) o en forma de mensajes de error debidos a cualquier causa.3. En este sentido. simula todas las funcionalidades de un Navegador. 1.tigris. La instalación nuevamente resulta extremadamente sencilla.2.apache. Y especificar la dirección de cada uno de los recurso que se desean solicitar (http://subclipse.
Para comprobar la correcta instalación y activación bastará con acceder a través de http://localhost:8080/geoserver.org) y descomprimirlos. y esta desarrollado testado y mantenido por diversos grupos y organizaciones de todo el mundo.org/display/GEOS/Stable)..3. 1. De modo que la instalación quedará como sigue: $ sudo easy_install TileCache . Una vez hecho esto. bastará con instalar el archivo de configuración de TileCache.1. descomprimir en la ubicación deseada y arrancarlo mediante el ejecutable startup. De este modo sólo tendremos que escribir: type easy_install TileCache.­ GEOSERVER GeoServer es un software de código abierto escrito en java que permite a los usuarios compartir y editar datos geoespaciales. Para realizar esta acción bastara con hacer uso de la herramienta llamada TileCache_install_config. aunque en ocasiones si se desea una instalación mas rápida y completa. Se trata de un proyecto dirigido de manera comunitaria. Geoserver es la implementación de referencia de los estándares WFS (Web Feature Service) y WCS (Web Coverage Service) del Open Geospatial Consortium (OGC).. publica datos de cualquier fuente de datos espaciales que utilice estándares abiertos.py que se habrá instalado por defecto.sh situado dentro de la carpeta bin.2. Diseñado para ser interoperable.2. Installed 8 . es posible usar el Python Package Index (pypi o Cheeseshop).4.tilecache..­ TILECACHE Para su instalación debemos descargar los archivos binarios desde la pagina web del proyecto (www. En nuestro caso este servidor ha sido desplegado en en la carpeta local dado que no ha de funcionar como servidor de mapas fuera de este ámbito. así como del sistema WMS utilizado en este proyecto Para la instalación basta con descargarse la última versión disponible desde la página web oficial para nuestra distribución Ubuntu (http://geoserver.
indicando la url de procedencia. Al momento de la realización del proyecto. lo que implica que ante una petición de una tesela concreta.5.egg/TileCache/tilecache. Esta opción falsearía los resultados obtenidos dado que en nuestro protocolo de pruebas no es necesario que las teselas demandadas al servidor sean contiguas.py Successfully copied file /usr/lib/python2.10-py2.cfg to /etc/tilecache.cfg. tilecache efectuara una petición de AxB teselas alrededor de la deseada con el objetivo de dinamizar las búsquedas para el usuario final cargando las teselas contiguas a la consultada. el tipo y el formato del archivo de salida. incluyéndolas en el archivo Tilecache. Para desactivar esta funcionalidad basta con editar el archivo de configuración Tilecache. Tilecache implementa por defecto opciones de metatiling. TileCache está también disponible como un paquete Debian directamente desde el homepage del proyecto. las teselas cacheadas serán almacenadas en la carpeta /tmp/tilecache.cfg y establecer la opción metatile a 1x1 9 . bastará con cargar las capas que van a ser utilizadas a los largo del proyecto. el nombre de la capa.5.10py2. En el siguiente ejemplo se carga una capa contenida en el servidor local geoserver. [topp:hidrografia] type=WMS url=http://localhost:8080/geoserver/wms extension=png En nuestro caso./usr/lib/python2.egg $ sudo tilecache_install_config.5/site-packages/TileCache-2.cfg. Una vez realizada la instalación. por lo que será esta carpeta la que es necesario vaciar para limpiar la cache a la hora de realizar las pruebas. existen paquetes para distribución Feisty o Gutsy.5/site-packages/TileCache-2. por lo que aumentaría de manera innecesaria el tráfico y por tanto la eficiencia.
en nuestro caso tomcat.es/wms/CARTOCIUDAD/CARTOCIUDAD</string > </wmsUrl> <wmsLayers>DivisionTerritorial</wmsLayers> </wmsLayer> Al igual que sucedió con tilecache.2. Tomcat tiene una funcionalidad que permite desplegar de manera muy simple archivos . proporcionándole solamente la ubicación del archivo.xml. seleccionamos la pestaña Tomcat Manager y tras introducir loggin y password accedemos al gestor de las aplicaciones. será necesario deshabilitar la opción de metatiling.war desarrollado para contenedores de aplicaciones.cartociudad.1. Una vez desplegado el archivo sólo resta configurarlo para obtener los resultados que buscamos para nuestro proyecto. pero en nuestro caso hemos optado por instalar otra de manera independiente al servidor. Será necesario cargar la capa sobre la que vamos a trabajar editando el archivo geowebcache. En este punto ya podemos probar si hemos instalado y configurado correctamente la aplicación accediendo a través del mánager de tomcat. A continuación iniciamos el apache tomcat.­ GEOWEBCACHE Geoserver ya incluye una versión de GeowebCache. accediendo a la opción Dinamically generated list of layers y seleccionando la capa cartociudad.war.xml introduciendo una capa mas: </wmsLayer> <wmsLayer> <name>cartociudad</name> <wmsUrl> <string>http://www. modificando la opción metatiling a 1x1.5. Para la instalación bastará con descargarnos el archivo . En este caso el archivo que es necesario editar es geowebcache­servlet. 10 .
en nuestro caso Tomcat.6. Dado que por defecto ya está configurada la capa de cartociudad no será necesario añadirla como en los casos anteriores. con las tres tecnologías obteniendo las teselas de un mismo servidor en paralelo y con la aplicación que generaremos realizando las peticiones http: 11 . por lo que para su instalación sólo será necesario descargarse los archivos correspondientes y desplegarlos en un contenedor de aplicaciones java.­ WMSCWRAPPER Al igual que Geowebcache esta construido en java.2.2. 1.7.­ RESUMEN La idea global del montaje final del proyecto quedaría como indica la imagen.1. Podemos comprobar si hemos realizado correctamente la instalación accediendo a la aplicación a través del tomcat manager y probando las distintas funcionalidades disponibles.
APÉNDICE II MANUAL DE USO DE LA APLICACIÓN .
jar puede colocarse indistintamente en cualquier ubicación dado que en su interfaz puede indicarsele la ruta exacta donde crear el archivo . En el script bench_start. pudiéndose establecer las conexiones entre todos ellos mediante sus respectivos modos de configuración. Dentro de estos scripts.sh también se ha de indicar la ruta hasta JMeterReports. De todos modos aquí se va a detallar como han sido dispuestos en nuestro caso. En nuestro caso y dada la instalaci ón y configuración de ellas que se hizo en el Apéndice I estas corresponden a /tmp/tiilecache para tilecache. También se indicará en este archivo las direcciones a través de las cuales accedemos a cada una de las tres implementaciones (en nuestro caso /tilecache/tilecache. /tmp/cache para WMSCwrapper y /usr/local/apache­ tomcat/temp/geowebcache en el caso de Geowebcache. ● ● El ejecutable JMeterReports.2.jar así como la ruta hasta los archivos . Una vez en este punto podemos proceder a colocar las distintas aplicaciones y archivos que vamos a necesitar de manera adecuada. con el fin de poder eliminarlos antes de realizar otra. ● 1 .­ INSTALACIÓN Para su instalación en cualquier máquina.sh también habrá que indicar la ruta hasta el ejecutable de Jmeter y hasta el archivo que hemos generado (apartado 4. éstos pueden ser colocados casi en cualquier ubicación dentro del disco duro. Dada la flexibilidad de todos los componentes.py /geowebcache/service/wms /WMS_C_wrapper/wms para TileCache.csv con los distintos Bboxes.jar ha sido colocado directamente dentro de la carpeta principal de instalación. En esa misma carpeta se incluyen los tres scripts. será necesario especificar las rutas tanto a JmeterReports. es preciso contar con todos los componentes que se detallan en el Apéndice I configurados de forma correcta.csv generados en cada prueba. El ejecutable Bboxgenerator.1) para realizar las peticiones. GeowebCache y WMSCwrapper respectivamente). En el script benchmark.1.jar como a las distintas ubicaciones de las distintas caches que van a ser utilizadas.
Como ya se dijo con anterioridad. aunque su gran flexibilidad le permite adaptarse a otras formas de actuación: 1.jar la dirección donde se almacenan los distintos archivos .properties dentro del archivador JMeterReports. En nuestro caso esta tarea se puede efectuar en tres simples ordenes en linea de comandos: $ sudo /etc/init.properties que se adjunta con BboxGeneratos. y se puede resumir en 3 pasos. si se desea hacer uso de la opción que implementa BboxGenerator. Será necesario arrancar tanto el servidor apache y el apache tomcat como el servidor de mapas geoserver.5/bin/startup.7.jar y elegimos las opciones que se desean. será imprescindible haber configurado anteriormente el acceso a la misma. si se desea utilizar la opción BBDD para obtener los datos directamente desde la base de datos de cartociudad.­ UTILIZACIÓN El uso es bastante sencillo.csv con los datos de cada prueba y donde se desea colocar los archivos de salida. De manera adicional. pudiendo visualizar la zona sobre la que queremos trabajar con la opción BUILD.sh para el tomcat $ sudo /usr/local/geoserver­1. Una vez elegidos los parámetros. seleccionamos un nombre y una ubicación para el archivo resultante y pulsamos el botón de OK. mediante el archivo config.d/apache2 start para arrancar el servidor apache2 $ sudo /usr/local/apache­tomcat­6. será necesario indicar en el archivo config. 2.jar para obtener los distintos Bboxes a partir de una base de datos.0.● Finalmente. 2 .jar en la sección resources.sh para geoserver 2. habrá que indicarle también dónde se encuentra la base de datos y el usuario y password para poder acceder a ella.20/bin/startup. Ejecutamos BboxGenerator.
ya sólo resta ejecutar el script Bench_start. tendremos un archivo results.sh con las opciones que se deseen.xls con una visualización gráfica de los resultados y otro archivo store. La ubicación de estos archivos dependerá de lo que le hayamos indicado a cada uno de los archivos de configuración. Una vez realizados estos tres pasos. 3 . Una vez generado el archivo con los datos de los Bboxes que vamos a pedir al servidor. La dos opciones configuradas en nuestro caso han sido la opción de indicarle el número de threads en cada iteración y la posibilidad en el momento que se desee de vaciar las caches mediante el comando cleancache. Cabe recordar en este punto que es preciso tener bien configurado las distintas rutas dentro de los archivos de configuración para evitar errores no deseados.3.xls con todos los resultados obtenidos en cada una de las iteraciones.
En primer lugar estos son los distinto parámetros que hemos colocado en los distintos archivos de configuración: ● BboxGenerator.­ EJEMPLO Como complemento a la explicación anterior.properties tenemos lo siguiente: #template template = /template.jar: es su archiv config.properties tenemos lo siguiente: #user user=postgres #password password=navarrete #connectstring connectstring=jdbc:postgresql:test #driver driver=org. vamos a concretar los pasos que hemos dado y el modo en que tenemos configurados nuestro archivos en un ejemplo.xls #outfilename outfilename = /home/pablo/proyecto/resultados/results.xls #path csv files csvpath = /home/pablo/proyecto/resultados/files/ 4 .postgresql.jar : en su archivo config.Driver #BBDDName bbddname=cartociudad #outfilepath outfilepath=/home/pablo/proyecto/resultados/bboxes/ ● JmeterReports.3.
jar Una vez que tenemos esto configurado.sh tenemos lo siguiente en el inicio del archivo: JMETER="/home/pablo/proyecto/jakarta­jmeter­2. bastará con escribir: JMeterReportspath=/home/pablo/proyecto/resultados/app/JMeterReports.20/temp/geowebcache/cartociudad" CACHE_WMSCWRAPPER="/tmp/cache/cartociudad/" CSV_FILE="/home/pablo/proyecto/resultados/bboxes/bboxes.sh" JTL2CSV="/home/pablo/proyecto/resultados/files/jtl2csv.#store file path storepath = /home/pablo/proyecto/resultados/files/store.3.py" JMX_FILE="/home/pablo/proyecto/resultados/files/Non­GUI­Test.py" PATH_GEOWEBCACHE="/geowebcache/service/wms" PATH_WMSCWRAPPER="/WMS_C_wrapper/wms" CACHE_TILECACHE="/tmp/tilecache/" CACHE_GEOWEBCACHE="/usr/local/apache­ tomcat­6.4/bin/jmeter.jmx" PATH_TILECACHE="/tilecache/tilecache.jar Seleccionamos las opciones que indica la imagen y pulsamos BUILD ● 5 .jar: $ java ­jar /home/pablo/proyecto/resultados/app/BboxGenerator.0. abrimos un terminal y ejecutamos BboxGenerator.sh.csv" Y en el script Bench_start.xls ● En el script benchmark.
1: interfar gráfica del generador de BBoxes El area de la petición.Imagen A2.2: Representación visual de la zona de trabajo 6 . dibujado en un mapa será el siguiente: Imagen A2.
2 y 3.sh con las opciones cleancache. Los resultados al final de la ejecución... visualizados en el mismo terminal serán los siguientes: pablo@laptop:~/proyecto/resultados$ /home/pablo/proyecto/resultados/bench_start. Ahora ejecutamos en un terminal la siguiente orden: $ /home/pablo/proyecto/resultados/bench_start. luego vacia las caches de nuevo.sh para thread=1. lo que implica que el 50% de las peticiones estará cacheadas a la hora de ser emitidas. o lo que es lo mismo.sh cleancache 1 cleancache 2 3 ­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+ Deleting csv files. 1. cleancache. Si todo es correcto nos saldrá el siguiente mensaje: Imagen A2.csv ubicado en la carpeta /home/pablo/proyecto/resultados/bboxes/.A continuación cerramos el mapa pulsando OK y pulsamos de nuevo OK en la ventana de las opciones.sh para thread=3. con el nombre bboxes. ejecuta benchmark.sh para thread=2 y finalmente ejecuta de nuevo benchmark. en el cual cada bbox tiene un 100% de repetirse una vez.3: Mensaje de información Con estos datos habremos creado un archivo con diez Bboxes de una resolución entre 5 y 10 cada una.sh cleancache 1 cleancache 2 3 Esta orden ejecuta el script bench_start. ejecuta benchmark. limpia las caches. ­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+ 7 .
..4/s Avg: 222 Min: 2 Max: 610 Err: 0 (0..7/s Avg: 209 Min: 2 Max: 552 Err: 0 (0..0s = 4.00%) Results Summary + 5 in 1. *** will remove 0 tiles in the cache \n\n*** Removing WMSCWrapper's cache. ­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+ ********************************* * Benchmarking TileCache * ********************************* :> 0 tiles in the cache before execution Created the tree successfully using /home/pablo/proyecto/resultados/files/Non­GUI­Test.6s = 3.8s = 3.6s = 1.00%) Results Summary + 9 in 2. \n\n*** Removing GeoWebCache's cache.jmx Starting the test @ Thu Nov 26 12:23:58 CET 2009 (1259234638015) Waiting for possible shutdown message on port 4445 Results Summary + 5 in 1.00%) 8 .8s = 2.jmx Starting the test @ Thu Nov 26 12:24:02 CET 2009 (1259234642565) Waiting for possible shutdown message on port 4445 Results Summary + 1 in 0.. *** will remove 64 tiles in the cache Cache entries found: 64 Removed 64 files.\n\n*** Removing TileCache's cache..00%) Tidying up ..7/s Avg: 590 Min: 590 Max: 590 Err: 0 (0..00%) Results Summary = 10 in 2.5/s Avg: 277 Min: 2 Max: 670 Err: 0 (0... end of run :> 5 tiles in the cache after execution ********************************* * Benchmarking GeoWebCache * ********************************* :> 0 tiles in the cache before execution Created the tree successfully using /home/pablo/proyecto/resultados/files/Non­GUI­Test.00%) Results Summary = 10 in 2. *** will remove 0 tiles in the cache number of command line argument are 1 ­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+ 1 users running simultaneously.8/s Avg: 346 Min: 4 Max: 670 Err: 0 (0. @ Thu Nov 26 12:24:01 CET 2009 (1259234641170) .1s = 4.8/s Avg: 258 Min: 2 Max: 610 Err: 0 (0.
*** will remove 5 tiles in the cache number of command line argument are 1 ­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+ 2 users running simultaneously... *** will remove 5 tiles in the cache \n\n*** Removing WMSCWrapper's cache.. \n\n*** Removing GeoWebCache's cache...00%) Tidying up .7/s Avg: 616 Min: 2 Max: 3764 Err: 0 (0.0/s Avg: 136 Min: 2 Max: 383 Err: 0 (0......8s = 2.Tidying up ..jmx Starting the test @ Thu Nov 26 12:24:06 CET 2009 (1259234646950) Waiting for possible shutdown message on port 4445 Results Summary = 10 in 1.jmx Starting the test @ Thu Nov 26 12:24:11 CET 2009 (1259234651076) Waiting for possible shutdown message on port 4445 Results Summary = 10 in 3. end of run :> 5 tiles in the cache after execution \n\n*** Removing TileCache's cache. @ Thu Nov 26 12:24:08 CET 2009 (1259234648709) ... @ Thu Nov 26 12:24:05 CET 2009 (1259234645511) .. ­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+ ********************************* * Benchmarking TileCache * ********************************* :> 0 tiles in the cache before execution Created the tree successfully using /home/pablo/proyecto/resultados/files/Non­GUI­Test.00%) Tidying up . *** will remove 5 tiles in the cache Cache entries found: 5 Removed 5 files.4s = 7.. @ Thu Nov 26 12:24:15 CET 2009 (1259234655158) 9 .. end of run :> 5 tiles in the cache after execution ********************************* * Benchmarking WMS_C_Wrapper * ********************************* :> 0 tiles in the cache before execution Created the tree successfully using /home/pablo/proyecto/resultados/files/Non­GUI­Test.
.. end of run :> 5 tiles in the cache after execution ********************************* * Benchmarking WMS_C_Wrapper * ********************************* :> 0 tiles in the cache before execution Created the tree successfully using /home/pablo/proyecto/resultados/files/Non­GUI­Test. end of run :> 5 tiles in the cache after execution ********************************* * Benchmarking GeoWebCache * ********************************* :> 0 tiles in the cache before execution Created the tree successfully using /home/pablo/proyecto/resultados/files/Non­GUI­Test.. ­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+ ********************************* * Benchmarking TileCache * ********************************* 10 . end of run :> 5 tiles in the cache after execution number of command line argument are 1 ­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+­+ 3 users running simultaneously....00%) Tidying up ..2s = 8. @ Thu Nov 26 12:24:21 CET 2009 (1259234661491) .00%) Tidying up .6s = 6..jmx Starting the test @ Thu Nov 26 12:24:16 CET 2009 (1259234656609) Waiting for possible shutdown message on port 4445 Results Summary = 10 in 1..3/s Avg: 300 Min: 3 Max: 513 Err: 0 (0.1/s Avg: 239 Min: 172 Max: 383 Err: 0 (0.. @ Thu Nov 26 12:24:18 CET 2009 (1259234658154) ..jmx Starting the test @ Thu Nov 26 12:24:19 CET 2009 (1259234659544) Waiting for possible shutdown message on port 4445 Results Summary = 10 in 1.
.jmx Starting the test @ Thu Nov 26 12:24:23 CET 2009 (1259234663847) Waiting for possible shutdown message on port 4445 Results Summary = 10 in 0.00%) Tidying up . @ Thu Nov 26 12:24:24 CET 2009 (1259234664258) .5/s Avg: 14 Min: 2 Max: 35 Err: 0 (0.jmx Starting the test @ Thu Nov 26 12:24:27 CET 2009 (1259234667522) Waiting for possible shutdown message on port 4445 Results Summary = 10 in 0..00%) Tidying up . @ Thu Nov 26 12:24:27 CET 2009 (1259234667920) ..1s = 94.. end of run :> 5 tiles in the cache after execution ********************************* * Benchmarking GeoWebCache * ********************************* :> 5 tiles in the cache before execution Created the tree successfully using /home/pablo/proyecto/resultados/files/Non­GUI­Test..jmx Starting the test @ Thu Nov 26 12:24:25 CET 2009 (1259234665660) Waiting for possible shutdown message on port 4445 Results Summary = 10 in 0.1s = 114.. end of run :> 5 tiles in the cache after execution ********************************* * Benchmarking WMS_C_Wrapper * ********************************* :> 5 tiles in the cache before execution Created the tree successfully using /home/pablo/proyecto/resultados/files/Non­GUI­Test.. end of run :> 5 tiles in the cache after execution Finalmente se nos mostrará una tabla con el resumen de todo los datos como la que sigue: 11 ..9/s Avg: 18 Min: 3 Max: 46 Err: 0 (0.:> 5 tiles in the cache before execution Created the tree successfully using /home/pablo/proyecto/resultados/files/Non­GUI­Test...1s = 120.3/s Avg: 23 Min: 2 Max: 73 Err: 0 (0.00%) Tidying up . @ Thu Nov 26 12:24:26 CET 2009 (1259234666060) ...
79794910748196 |3.5161744022503516 | |2.656748140276302 | |3.csv como fuente de Bboxes.3 |6.0 |136.33962264150944 | _______________________________________________________________________________________________ En la ubicación indicada. 12 .94252873563218|94.7 |277. se encuentra el archivo results. y en la carpeta /home/pablo/proyecto/resultados/files/ encontramos store.48192771084338|114.333122229259025 |8.xls con todos los datos de cada iteración (en este caso esos datos son coincidentes dado que no hemos realizado ninguna ejecución con un numero de hilos repetida).8 |18. _______________________________________________________________________________________________ | Results Summary | _______________________________________________________________________________________________ | | AVG_TIME | AVG_RATE | _______________________________________________________________________________________________ |Threads |WMS­C­Wrapper |GeoWebCache |TileCache |WMS­C­Wrapper |GeoWebCache | TileCache | _______________________________________________________________________________________________ |1.027406886858749 |3.0 |120.6 |7. Si ahora se desease otra ejecución con el mismo archivo bboxes.8 |616.8 |239.2 |23. habría que tener en cuenta que los datos de la anterior prueba van a ser eliminados y sustituidos por los de la siguiente.0 |300. en nuestro caso /home/pablo/proyecto/resultados/.8 |258.123476848090982 |2.0 |13.xls.
wmsc.crsMaxX = crsMaxX.crsMinY = crsMinY. double crsMinY.benchmarking.java package org.­ Client. double crsMaxX. this. } } 1.benchmarking.crsMaxY = crsMaxY.1.wmsc.­ BBOXGENERATOR 1. private double crsMaxY. this. } 1 . } public void setCrsMinX(double crsMinX) { this. private double crsMinY. GraphInterface gi = new GraphInterface(ts).2. this. public BBox(double crsMinX.setVisible(true).crsMinX = crsMinX.uva. double crsMaxY) { this.java package org.uva. } public double getCrsMinX() { return crsMinX. public class Client { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub TileScheme ts = new TileScheme(). gi. private double crsMaxX. public class BBox { private double crsMinX.crsMinX = crsMinX.­ Bbox.1.
crsMaxX = crsMaxX. private int numberofbbox. } } 1. private double tileMatrixMaxYr. private double tileMatrixMinXr. private int prob1.crsMaxY = crsMaxY.benchmarking. private double tileMatrixMinY.public double getCrsMinY() { return crsMinY. private int prob3. private double tileMatrixMaxX.java package org.3.wmsc. private int prob2. 2 .uva. } public void setCrsMinY(double crsMinY) { this. private int prob4. private double tileMatrixMinYr.crsMinY = crsMinY. } public void setCrsMaxX(double crsMaxX) { this. } public double getCrsMaxY() { return crsMaxY. private double tileMatrixMaxY. private double tileMatrixMaxXr. private int counter. private int maxresolution. private int minresolution. public class TileScheme { // Maximal extent private static TileScheme ts. } public double getCrsMaxX() { return crsMaxX. private double tileMatrixMinX. } public void setCrsMaxY(double crsMaxY) { this.­ TileScheme.
int colmax = -(int) ((maxX / tileSpanX) + 0. if (maxX < -180) { maxX = -180. 0. 0.00002145767211914060. 0. if (maxX >= 0) { int colmax = (int) (maxX / tileSpanX). 0. 0.99999). double minXr. } } if (maxY >= 0) { int rowmax = (int) (maxY / tileSpanY).getHeight(). 0. double maxXr. // tile height double resmat[] = { 0. 0.getTileMatrixMaxX(). 0.17578125000000000000. int resolution = ts. double maxY = ts. 0. 0. // tile width private int height = 256. private int width = 256.getTileMatrixMinX().08789062500000000000. 0. 0. double tileSpanY = ts.00034332275390625000.getWidth().resmat[resolution] * ts.01098632812500000000. double minX = ts. } } else { maxX = -maxX.00000536441802978516.00008583068847656250. 0.00068664550781250000. public void Test() { // // Test and correct bbox // TileScheme ts = TileScheme.resmat[resolution] * ts.getMinresolution().04394531250000000000.getTs().00000134110450744629 }. 0.getTileMatrixMaxY(). double tileSpanX = ts.00000268220901489258. 0.00137329101562500000. maxX = colmax * tileSpanX. 0. if (maxX > 180) { maxX = 180.00549316406250000000.35156250000000000000. double maxX = ts.private String csvfilename. double maxYr.00004291534423828120. 0.02197265625000000000.getTileMatrixMinY().00001072883605957030.00274658203125000000. 0.70312500000000000000. 3 . double minY = ts. double minYr. 0.00017166137695312500. maxX = colmax * tileSpanX. private String numberofbboxstr.
int rowmax = -(int) ((maxY / tileSpanY) + 0. minX = colmin * tileSpanX.maxY = rowmax * tileSpanY. minX = colmin * tileSpanX. if (minX < -180) { minX = -180. if (maxY < -90) { maxY = -90. minY = -90.99999). } } else { minX = -minX. int rowmin = -(int) ((minY / tileSpanY)). int colmin = -(int) ((minX / tileSpanX)). if (minX > 180) { minX = 180. maxY = rowmax * tileSpanY. } if ((maxX > minX && maxY > minY)) { maxXr = maxX. 4 . } } if (minY >= 0) { int rowmin = (int) ((minY / tileSpanY) + 0. } } if (minX >= 0) { int colmin = (int) ((minX / tileSpanX) + 0.99999). if (minY < -90) { minY = -90. if (minY > 90) { minY = 90. minY = rowmin * tileSpanY. } } else { minY = -minY. } } else { maxY = -maxY. } } if ((maxY >= 90 && minY <= -90 && resolution == 0)) { maxY = 90. minY = rowmin * tileSpanY. if (maxY > 90) { maxY = 90.99999).
maxYr = maxY; minXr = minX; minYr = minY; } else { maxXr = 180; maxYr = 90; minXr = -180; minYr = -90; GraphInterface.Warning(); } ts.setTileMatrixMaxXr(maxXr); ts.setTileMatrixMinXr(minXr); ts.setTileMatrixMaxYr(maxYr); ts.setTileMatrixMinYr(minYr); TileScheme.setTs(ts); } public double getTileMatrixMaxX() { return tileMatrixMaxX; } public void setTileMatrixMaxX(double TileMatrixMaxX) { tileMatrixMaxX = TileMatrixMaxX; } public double getTileMatrixMinX() { return tileMatrixMinX; } public void setTileMatrixMinX(double TileMatrixMinX) { tileMatrixMinX = TileMatrixMinX; } public double getTileMatrixMaxY() { return tileMatrixMaxY; } public void setTileMatrixMaxY(double TileMatrixMaxY) { tileMatrixMaxY = TileMatrixMaxY; } public double getTileMatrixMinY() { return tileMatrixMinY; } public void setTileMatrixMinY(double TileMatrixMinY) { tileMatrixMinY = TileMatrixMinY; }
public double getTileMatrixMaxXr() { return tileMatrixMaxXr; } public void setTileMatrixMaxXr(double TileMatrixMaxXr) { tileMatrixMaxXr = TileMatrixMaxXr; } public double getTileMatrixMinXr() { return tileMatrixMinXr; } public void setTileMatrixMinXr(double TileMatrixMinXr) { tileMatrixMinXr = TileMatrixMinXr; } public double getTileMatrixMaxYr() { return tileMatrixMaxYr; } public void setTileMatrixMaxYr(double TileMatrixMaxYr) { tileMatrixMaxYr = TileMatrixMaxYr; } public double getTileMatrixMinYr() { return tileMatrixMinYr; } public void setTileMatrixMinYr(double TileMatrixMinYr) { tileMatrixMinYr = TileMatrixMinYr; } public int getNumberofbbox() { return numberofbbox; } public void setNumberofbbox(int Numberofbbox) { numberofbbox = Numberofbbox; } public int getProb1() { return prob1; } public void setProb1(int Prob1) { prob1 = Prob1; } public int getProb2() {
return prob2; } public void setProb2(int Prob2) { prob2 = Prob2; } public int getProb3() { return prob3; } public void setProb3(int Prob3) { prob3 = Prob3; } public int getProb4() { return prob4; } public void setProb4(int Prob4) { prob4 = Prob4; } public int getMinresolution() { return minresolution; } public void setMinresolution(int Minresolution) { minresolution = Minresolution; } public int getMaxresolution() { return maxresolution; } public void setMaxresolution(int Maxresolution) { maxresolution = Maxresolution; } public int getCounter() { return counter; } public void setCounter(int Counter) { counter = Counter; } public String getCsvfilename() { return csvfilename; }
} public void setWidth(int Width) { width = Width.properties". } public void setHeight(int Height) { height = Height.ts = ts. } public int getHeight() { return height.public void setCsvfilename(String Csvfilename) { csvfilename = Csvfilename.uva.4.util.­ Configuration.java package org. 8 .Properties. } public void setNumberofbboxstr(String Numberofbboxstr) { numberofbboxstr = Numberofbboxstr. } public String getNumberofbboxstr() { return numberofbboxstr. import java. } public int getWidth() { return width. } public static void setTs(TileScheme ts) { TileScheme.benchmarking. } } 1.wmsc. } public static TileScheme getTs() { return ts. public class Configuration { private static final String CONFIGURATION_FILE = "/config. private static Properties properties.
} return user.class . outfilepath = properties.getProperty("connectstring"). properties. } return connectstring.load(Configuration.getProperty("bbddname").getMessage()).private static String driver. } catch (Exception e) { System. password = properties. } 9 . private static String password.getProperty("user").getProperty("password"). private static void init() { try { properties = new Properties(). } public static String getUser() { if (user == null) { init().out. bbddname = properties. } } public static String getDriver() { if (driver == null) { init(). } return driver.getResourceAsStream(CONFIGURATION_FILE)). private static String outfilepath.println(e. private static String bbddname. connectstring = properties. private static String user.getProperty("outfilepath"). driver = properties.getProperty("driver"). } public static String getConnectString() { if (connectstring == null) { init(). user = properties. } public static String getPassword() { if (password == null) { init(). private static String connectstring.
java package org. private static WMSCBBddBBoxGenerator wmscbbddbboxgenerator = new WMSCBBddBBoxGenerator( TileScheme.JButton.getTs()). import java.swing. import javax.swing.wmsc. import javax. initComponents().AbstractButton.swing.SwingConstants.benchmarking. } return bbddname.ImageIcon. import javax.IOException.­ GraphInterface.Font.swing. } public static String getBbddName() { if (bbddname == null) { init().setTs(ts).JLabel.JFrame { TileScheme ts = new TileScheme().JFrame. import javax. private static WMSCRandomBBoxGenerator wmscrandombboxgenerator = new WMSCRandomBBoxGenerator( TileScheme. } public static String getOutFilePath() { if (outfilepath == null) { init(). public class GraphInterface extends javax. import java. import javax. } private void initComponents() {} 10 .getTs()).5.swing. import javax. private static final long serialVersionUID = 1L.return password. } return outfilepath. } } 1.swing.awt.swing.io.uva. public GraphInterface(TileScheme ts) { TileScheme.
} ConfirmWindow().parseInt(jTextField28. if (jTextField20.getText().trim()) .parseInt(jTextField32.setNumberofbboxstr(jTextField33.Test().setMaxresolution(Integer. try { wmscrandombboxgenerator.getText().setProb4(Integer.trim())).parseInt(jTextField29.getText()).setNumberofbboxstr(jTextField33.getText().awt.setCsvfilename(jTextField16. ts. ts.setProb2(Integer.setProb1(Integer.valueOf(jTextField22. } ConfirmWindow().event.private void jButton2ActionPerformed(java. ts. ts.trim())).getText().getText()).valueOf(jTextField20. } else { TileScheme. ts.csvwrite().getText(). ts.getText().parseInt(jTextField19. ts. } catch (IOException e) { e.valueOf(jTextField23.trim())).setTileMatrixMinX(Double.setTs(ts).getText(). } catch (IOException e) { e.getText().trim()) .setTileMatrixMinY(Double.parseInt(jTextField30.trim())).doubleValue()).getTs(). ts. } } 11 .printStackTrace(). TileScheme.doubleValue()). try { wmscbbddbboxgenerator.printStackTrace().setTs(ts).getText(). ts.getText().parseInt(jTextField33.getText().doubleValue()).setTileMatrixMaxX(Double.csvwrite().setTileMatrixMaxY(Double. ts.setNumberofbbox(Integer.trim())). ts.setMinresolution(Integer.trim())).trim()) . ts.trim())). ts.getText().valueOf(jTextField21.getText()).setProb3(Integer.parseInt(jTextField31. ts.doubleValue()).ActionEvent evt) { ts = TileScheme.trim()) .equals("bbdd") == false) { ts.
ts.valueOf(TileScheme.setTs(ts). ts.valueOf(jTextField21. jTextField25.ActionEvent evt) { System.awt.setTileMatrixMaxX(Double. } public static void main(String args[]) { java.setText("bbdd").getTs()).getTileMatrixMaxXr())).setTileMatrixMinX(Double.doubleValue()).awt.doubleValue()).awt.awt.event.event. } private void jButton8ActionPerformed(java. jTextField24.event.valueOf(TileScheme. jTextField21.valueOf(jTextField20. ts. jTextField27.getTs() .invokeLater(new Runnable() { public void run() { new GraphInterface(TileScheme.trim()) .getText().trim()) .trim()) .valueOf(jTextField22.setText("bbdd"). MapWindow().valueOf(TileScheme.getText().awt. jTextField23.valueOf(jTextField23.getTs() .exit(0).getText().setVisible(true).doubleValue()). } private void jMenuItem1ActionPerformed(java.getTs() .getTileMatrixMaxYr())).getTileMatrixMinYr())). ts.setText(String. TileScheme.ActionEvent evt) { System.getText().event. jTextField22.getTs().ActionEvent evt) { jTextField20.ActionEvent evt) { ts = TileScheme. ts.doubleValue()).valueOf(TileScheme.parseInt(jTextField19. } private void jButton9ActionPerformed(java.setText(String.Test(). 12 .getTileMatrixMinXr())).setText("bbdd"). ts. jTextField26.setTileMatrixMinY(Double.setTileMatrixMaxY(Double.exit(0).EventQueue.trim())).setText(String.private void jButton1ActionPerformed(java.getText().getTs() .setText(String.setText("bbdd").setMinresolution(Integer.trim()) .
swing. private javax.JTextField jTextField21. private javax. private javax. private java.swing. private java. private javax. } private javax.swing.JButton jButton2.awt.awt.swing. private java. private javax.JMenuItem jMenuItem1.JTextField jTextField31.JTextField jTextField27.JTextField jTextField19.awt. private javax. 200). private javax. private javax. 100. private javax.JMenu jMenu2. private javax.JButton jButton8.JTextField jTextField23. private java. private javax.JButton jButton1. private java.swing.JTextField jTextField33.swing.JTextField jTextField25.Label label21. nuevoFrame. private javax.awt.JButton jButton9.awt.swing.Label label23.awt. nuevoFrame.awt.Label label20.swing. private java. private javax.JTextField jTextField16.JTextField jTextField26.Label label25. nuevoFrame. private java. 13 .swing.awt.swing.Label label22.swing. private javax. 400.setVisible(true). private javax.swing.PopupMenu popupMenu1.Label label27.swing.JTextField jTextField22.swing.Label label28. private javax.pack().swing. private java. private java.JTextField jTextField24. private javax. private javax.swing. private javax.setBounds(300.swing.JMenuBar jMenuBar1.swing.swing.swing.swing.} }).JMenu jMenu1.JTextField jTextField20.awt.JTextField jTextField32.JTextField jTextField30. private java. private javax.Label label26. public static void Warning() { // // Error window (out of bounds) // final JFrame nuevoFrame = new JFrame().Label label24. private javax.JTextField jTextField29.JTextField jTextField28.swing.swing.swing. private javax. private javax.awt.
getTileMatrixMaxY(). Font. newFrame.CENTER). 50. 650). } }).setVerticalTextPosition(AbstractButton. 94. double MinX = ts.getTileMatrixMinXr(). double MaxXr = ts. nuevoFrame. 14 .getTileMatrixMaxX(). textLabel10. JButton12.PLAIN.add(JButton12).pack().setBounds(90.getTileMatrixMinY(). newFrame. double MinY = ts. nuevoFrame.setFont(new Font("error\n impossible borders".setLayout(null). final JFrame newFrame = new JFrame().setText("OK").getTileMatrixMaxXr(). double MinXr = ts. SwingConstants.event. JButton JButtonok = new JButton(). 1110. 16)). 29).BOTTOM). textLabel10.ActionEvent evt) { nuevoFrame.setHorizontalTextPosition(AbstractButton.getTs().awt. 29). double MaxY = ts.setBounds(150. 210. } public void MapWindow() { ts = TileScheme. JButton12. JButton12. JButton12.getTileMatrixMinYr(). 100. double MinYr = ts.add(textLabel10).setName("OKbutton").setVisible(false).addActionListener(new java. nuevoFrame.getContentPane().CENTER).event.awt.getContentPane().setBounds(100.JLabel textLabel10 = new JLabel("error impossible borders". JButton12.getTileMatrixMinX(). JButton12. 120. double MaxX = ts. JButton JButton12 = new JButton().ActionListener() { public void actionPerformed(java. double MaxYr = ts.getTileMatrixMaxYr().
(int) ((MaxY . 1.swing.MinXr) * 3) + 2. (int) ((MaxX .(int) MinY) * 3) + 10.(int) MinYr) * 3) + 10. JLabel map1lab = new javax. ((90 .add(JButtonok).JLabel(). 540). newFrame.JLabel(). (int) ((MaxYr . JLabel LabelMinY = new javax.setBounds((int) ((MaxXr + 180) * 3) + 10.setBounds((int) ((MaxX + 180) * 3) + 10. 4.JLabel().setBounds((((int) MinX + 180) * 3) + 6. 1.JLabel().MaxY) * 3 + 6. 580.swing.swing. (int) (90 .setBounds((((int) MinX + 180) * 3) + 6.MaxY) * 3 + 6. ImageIcon red = new ImageIcon().setBounds((((int) MinXr + 180) * 3) + 9.MinX) * 3) + 8.JLabel().JButtonok.setBounds((((int) MinX + 180) * 3) + 6. ImageIcon map0img = new ImageIcon().setHorizontalTextPosition(AbstractButton. LabelMaxXr. LabelMaxX.setVerticalTextPosition(AbstractButton.swing.CENTER).JLabel().setBounds(500. LabelMinXr.MinY) * 3) + 8). 100. JLabel LabelMaxX = new javax. 1).setText("OK"). 1). JButtonok. (int) (90 . LabelMinYr. 4).MaxY) * 3 + 6.getContentPane().setName("OKbutton"). JButtonok. (int) (90 . JLabel map0lab = new javax. (int) (90 .MinY) * 3) + 8). (int) ((MaxXr . (int) ((MaxXr .swing.JLabel().MinYr) * 3) + 2).setBounds(10.setBounds((((int) MinXr + 180) * 3) + 9. JLabel LabelMinXr = new javax.MinX) * 3) + 8.MinYr) * 3) + 2). 540). map0lab. (int) ((MaxX .JLabel(). ((90 .JLabel(). JButtonok.setBounds((((int) MinXr + 180) * 3) + 9.MaxYr) * 3 + 9. (int) ((MaxY .setBounds(550. 10.MinXr) * 3) + 2.setLayout(null). JButtonok.swing. 10. JLabel LabelMaxY = new javax. JLabel LabelMinX = new javax.MaxYr) * 3 + 9.MaxYr) * 3 + 9. newFrame. LabelMinX. 4.swing. (int) (90 . 30). JLabel LabelMinYr = new javax. LabelMaxY. ImageIcon black = new ImageIcon(). LabelMinY.JLabel().swing. JLabel LabelMaxYr = new javax. 540.swing. 540. (int) ((MaxYr . 4). LabelMaxYr. (int) (90 . 15 .BOTTOM). JLabel LabelMaxXr = new javax. map1lab.swing. ImageIcon map1img = new ImageIcon().
textLabel10. 29).event. newFrame.getContentPane().addActionListener(new java. 50. newFrame. map0img = new ImageIcon(GraphInterface.class .setIcon(black). LabelMaxY.event.setIcon(map1img). newFrame. newFrame.ActionListener() { public void actionPerformed(java.add(map0lab). map1img = new ImageIcon(GraphInterface.jpeg")).getContentPane().class.jpeg")).getContentPane().add(LabelMaxXr).add(LabelMinXr). LabelMaxXr. map0lab.getContentPane().setIcon(black).setBounds(135.getResource("/mundi1. nuevoFrame. LabelMaxX.jpeg")).getContentPane().add(LabelMinY). nuevoFrame.jpeg")). LabelMinXr.setBounds(300.setVisible(true).setIcon(black). newFrame.CENTER).awt. newFrame. 400. } }).add(LabelMaxYr).awt.setIcon(black).ActionEvent evt) { newFrame. LabelMaxYr.class .getContentPane().setVisible(true). LabelMinX.add(LabelMinYr). newFrame.add(map1lab). 200).add(LabelMaxX). } public static void ConfirmWindow() { final JFrame nuevoFrame = new JFrame().getResource("/red. LabelMinYr.getContentPane().getResource("/black.setIcon(red).setIcon(map0img). 124. LabelMinY.setVisible(false).class. map1lab.getContentPane(). if ((MaxX > MinX && MaxY > MinY)) { newFrame. black = new ImageIcon(GraphInterface. 16 .pack(). newFrame.setIcon(red).getContentPane(). newFrame. JLabel textLabel10 = new JLabel("file created". } JButtonok.getResource("/mundi0. newFrame.getContentPane().add(LabelMaxY).setIcon(red). 100.setIcon(red).add(LabelMinX).red = new ImageIcon(GraphInterface. nuevoFrame. SwingConstants.
event. 17 . 120. JButton12.benchmarking.BOTTOM).wmsc.ActionEvent evt) { nuevoFrame. JButton12.6.FileWriter.io. double MinX = ts.event.util.uva.getTileMatrixMaxXr().setText("OK"). } } 1.io.­ WMSCRandomBBoxGenerator.setLayout(null). nuevoFrame.setName("OKbutton").PLAIN.BufferedWriter. JButton JButton12 = new JButton(). JButton12. public class WMSCRandomBBoxGenerator { private TileScheme ts = null. JButton12.getContentPane().setBounds(150.ts = ts.add(JButton12).getContentPane().java package org. 94. JButton12. import java.textLabel10.IOException.setFont(new Font("File Created".awt. import java. 16)). public WMSCRandomBBoxGenerator(TileScheme ts) { this. } public BBox getRandomWMSCTileBBox() { double MaxX = ts. nuevoFrame.io.setHorizontalTextPosition(AbstractButton.awt.Random.setVerticalTextPosition(AbstractButton. nuevoFrame. JButton12. import java.add(textLabel10).getTileMatrixMinXr(). 29).addActionListener(new java. } }). Font.ActionListener() { public void actionPerformed(java.setVisible(false).CENTER). import java.
int tileCol = (int) Math. double diffMatrixY = MaxY . Random funcrand = new Random(). double BBox3 = (tileCol + 1) * tileSpanX + MinX.MinY.getTileMatrixMinYr(). int tileMaxCol = (int) Math.getMaxresolution().nextInt(100).round(diffMatrixX / (ts.resmat[funcrandint]. Random prob3rand = new Random().nextDouble().getTileMatrixMaxYr(). Random funcrand2 = new Random(). double tileSpanY = ts.getMinresolution(). 18 .minresolution + 1). BBox bbox = new BBox(BBox1.getWidth() * ts.getTs().(tileRow + 1) * tileSpanY.nextInt(100). int prob3randint = prob3rand. BBox4). BBox2. double BBox1 = tileCol * tileSpanX + MinX. int minresolution = ts. return (bbox). int maxresolution = ts.getHeight())).getHeight() * ts.floor(tileMaxCol * funcranddouble).getCsvfilename() + ". double tileSpanX = ts. Random prob2rand = new Random(). double BBox2 = MaxY . int funcrandint = minresolution + funcrand3.resmat[funcrandint] * ts.csv")).resmat[funcrandint] * ts. BBox3. Random funcrand3 = new Random(). Random prob1rand = new Random().tileRow * tileSpanY. double BBox4 = MaxY .nextInt(100). int tileMaxRow = (int) Math. double funcranddouble = funcrand.nextDouble().resmat[funcrandint]. double MinY = ts.getOutFilePath() + ts. } public void csvwrite() throws IOException { ts = TileScheme. BufferedWriter out = new BufferedWriter(new FileWriter(Configuration .double MaxY = ts. double diffMatrixX = MaxX .round(diffMatrixY / (ts.getWidth())). int tileRow = (int) Math. int prob2randint = prob2rand.nextInt(maxresolution .floor(tileMaxRow * funcranddouble2). double funcranddouble2 = funcrand2.MinX. BBox bbox = null. int prob1randint = prob1rand.
} } 19 . if (prob3randint < ts.) { bbox = getRandomWMSCTileBBox()." + bbox." + bbox.write(bbox.getCrsMaxX() + ".write(bbox.getCrsMinX() + ".getCrsMinY() + ".getCrsMaxY() + "\n"). if (prob4randint < ts.getProb3() & i < ts. for (int i = 0. i++.getNumberofbbox()." + bbox.getCrsMinX() + ". i++.write(bbox.nextInt(100).getCrsMinY() + ". if (prob2randint < ts.Random prob4rand = new Random(). i++.getCrsMaxX() + ".getCrsMaxX() + "." + bbox.getCrsMinX() + ".getCrsMaxX() + ".getNumberofbbox()) { out. i++.getCrsMaxY() + "\n").getCrsMinY() + ". if (prob1randint < ts.getCrsMaxY() + "\n").getProb1() & i < ts." + bbox.write(bbox.getProb2() & i < ts.getCrsMinX() + ".getProb4() & i < ts.write(bbox. i < ts." + bbox.getCrsMinY() + ".getCrsMaxY() + "\n")." + bbox.getCrsMaxY() + "\n").getNumberofbbox()) { out. } } } } } out." + bbox.close(). out.getCrsMinY() + ".getCrsMaxX() + "." + bbox.getNumberofbbox()) { out." + bbox." + bbox." + bbox. i++." + bbox." + bbox." + bbox.getCrsMinX() + ".getNumberofbbox()) { out. int prob4randint = prob4rand.
nextToken().Connection.sql.io.next()) { String bboxstr = rs. public class WMSCBBddBBoxGenerator { private TileScheme ts = null. import java. Configuration. 20 .sql.sql. String strb = stbbox. Configuration . Connection con = DriverManager.getDriver()). ". " ")."). String stra = stbbox. final StringTokenizer stCad = new StringTokenizer(bboxstr.IOException.createStatement().getNumberofbbox()].getBbddName() + " limit " + ts.StringTokenizer.nextToken(). } public BBox[] getBBddbboxes() { String[][] bbox = new String[10][ts.nextToken().getConnectString(). public WMSCBBddBBoxGenerator(TileScheme ts) { this. import java.­ WMSCBBddBBoxGenerator.forName(Configuration.java package org. ResultSet rs = stmt. BBox[] bboxes = new BBox[ts.1. import java.getNumberofbbox() + ""). while (stCad.getUser(). import java. bbox[j * 2][i] = stra.BufferedWriter. import java.uva.getNumberofbbox()]. Statement stmt = con.io.FileWriter.6.util.benchmarking.hasMoreTokens()) { final StringTokenizer stbbox = new StringTokenizer(stCad . while (rs. int i = 0.wmsc.getPassword()).ResultSet. try { Class. import java. import java.Statement. int j = 0.ts = ts.getConnection(Configuration . import java.getString(1).DriverManager.sql.io.executeQuery("SELECT asText(bbox) FROM " + Configuration.substring(9).
} out. j++.getCrsMinX() + ".out. } stmt." + bboxes[i].getTs().getCrsMaxY() + "\n"). con.println(e. Double . } public void csvwrite() throws IOException { ts = TileScheme." + bboxes[i].getCrsMaxX() + ".parseDouble(bbox[4][i]).length.parseDouble(bbox[1][i])).csv")).write(bboxes[i].close(). BufferedWriter out = new BufferedWriter(new FileWriter(Configuration . } } 21 .bbox[(j * 2) + 1][i] = strb. } return bboxes.close(). Double . for (int i = 0.getOutFilePath() + ts. } bboxes[i] = new BBox(Double." + bboxes[i]. i++.close().getCsvfilename() + ". i < bboxes. BBox[] bboxes = getBBddbboxes(). Double . } catch (Exception e) { System.parseDouble(bbox[3][i]). i++) { out.getMessage()).parseDouble(bbox[0][i]).getCrsMinY() + ".
// skip headers while ((str = in. public class Constants { public static String AVG_RATE = "AVG_RATE". import java.benchmarking. long sum = 0.readLine()) != null) { data_entry = str. j++."). public static final String AVG_TIME = "AVG_TIME". sum += Long.io.1. } } 2.java package es. String str = null.­ Constants.uva.idelab.BufferedReader.FileReader.uva. try { BufferedReader in = new BufferedReader(new FileReader(csvFile)). } public String getAvgTime(){ return AVG_TIME. public String getAvgRate(){ return AVG_RATE.io. str = in.2.2. } 22 .IOException. import java.java package es. double avg_time = 0.benchmarking.valueOf(data_entry[11]).idelab.readLine().­ JMeterReports 2. public class Stats { public static double getAvgTime(String csvFile) { String[] data_entry = null. int j = 0.longValue().io.split(". import java.­ Stats.
double avg_rate = 0.valueOf(data_entry[1]).longValue() + elapsed.valueOf(data_entry[0]). long end = 0. try { BufferedReader in = new BufferedReader(new FileReader(csvFile)).").longValue(). start_temp = Long. end_temp = Long. } if ((end_temp + elapsed) > end) { end = end_temp + elapsed. // skip header // labels str = in.longValue().longValue().split(".valueOf(data_entry[1]). long elapsed = 0. data_entry = str. long end_temp = 0.close().longValue().in.valueOf(data_entry[0]). return avg_time. elapsed = Long. data_entry = str. end = Long.valueOf(data_entry[0])."). str = in.split(". elapsed = Long.readLine(). } catch (IOException e) { } avg_time = (double) sum / j. while ((str = in. String str = null.readLine(). } } 23 . start = Long.longValue().readLine()) != null) { j++. long start_temp = 0. } public static double getAvgRate(String csvFile) { String[] data_entry = null. if (start_temp < start) { start = start_temp. int j = 1.valueOf(data_entry[0]). long start = 0.
apache.getMessage()). import java.close().properties". } } private void generateReport(String[] argthreads) throws IOException { 24 .3.io.Properties. private static double maxthread = 1.logging.generateReport(args).io. import java. import org. } catch (IOException e) { } avg_rate = (double) 1000 * (j) / (end .benchmarking.HSSFWorkbook.File.idelab.java package es.in.apache.util.hssf.poi.usermodel. import org. public class ReportGenerator { private static double numrow.uva.hssf.poi.println(e. try { rg.apache.poi. import java. import java. private static final String CONFIGURATION_FILE = "/config. import java.Logger.­ ReportGenerator. import java. return avg_rate.HSSFRow.Level.util.usermodel.start).IOException. } } 2.out.util.logging. private static double minthread = 1.FileInputStream.io.io. import java.FileOutputStream. } catch (IOException e) { System. import org.HSSFSheet. /** * @param args */ public static void main(String[] args) { ReportGenerator rg = new ReportGenerator().hssf.usermodel.
HSSFRow row = sheet.getSheetAt(1). row.createCell(4). try { Properties properties = new Properties().equals("store") == true) { String thread = argthreads[1].createRow(numrow). File outFile = new File(properties.getProperty("storepath")).getProperty("storepath")).getProperty("csvpath").createCell(3). row.createCell(0).properties")).class .setCellValue( Stats .createCell(5). int numrow = 0. row.createCell(6). 25 .csv")). properties.setCellValue(Double.getAvgRate(path + "geowebcache" + thread + ".getResourceAsStream("/config. row.createCell(2).parseDouble(thread)).csv")).getAvgRate(path + "wmscwrapper" + thread + ".setCellValue( Stats.setCellValue( Stats . row. FileInputStream store = new FileInputStream(properties .setCellValue( Stats .csv")).setCellValue( Stats .getAvgTime(path + "tilecache" + thread + ". HSSFSheet sheet = wb.getAvgTime(path + "geowebcache" + thread + ".load(ReportGenerator. HSSFWorkbook wb = new HSSFWorkbook(store).String summary = "".csv")).getAvgRate(path + "tilecache" + thread + ".setCellValue( Stats. if (argthreads[0].csv")). row.getRow(numrow) != null) { numrow++.createCell(1).getAvgTime(path + "wmscwrapper" + thread + ". row. FileOutputStream outputFile = new FileOutputStream(outFile). while (sheet. } String path = properties.csv")).
HSSFWorkbook databook = new HSSFWorkbook(storefile). HSSFWorkbook libro = new HSSFWorkbook(archivo).getResourceAsStream(CONFIGURATION_FILE)). double sumwmsrate = 0.getProperty("template")).equals("0") == true) { int numrows = 0. FileInputStream storefile = new FileInputStream(properties . try { Properties properties = new Properties(). double threads = 0.getProperty("storepath")).getSheetAt(1).write(outputFile). properties. HSSFSheet sheet = libro. double sumwmsctime = 0.wb.getRow(numrows) != null) { numrows++. int j = 0. 26 . HSSFRow[] rows = new HSSFRow[numrows]. } catch (Exception e) { } } if (argthreads[0]. HSSFRow[] rowsord = new HSSFRow[numrows]. while (datasheet.load(ReportGenerator. double threshold = 0. double sumgwcrate = 0. double sumtcrate = 0. } setNumRow(numrows). FileInputStream archivo = new FileInputStream(properties . HSSFSheet datasheet = databook. double sumgwctime = 0.class . double sumtctime = 0. outputFile.getSheet("hoja1").close(). double sumthreads = 0.
j++. for (int i = 0. } } int cont2 = 0. i++) { if (rows[i].getCell(1). i < numrows. rows).getCell(0). rows). sumwmsctime = rowsord[i].getNumericCellValue() <= getMinThread() && rows[i].getRow(i). i < getNumRow() . int cont1 = 1.getNumericCellValue() == getMaxThread()) { rowsord[j] = rows[i]. i++) { threads = rowsord[i]. while (getMinThread() < getMaxThread()) { for (int i = 2. setMinThread(getMinThread(). i++) { rows[i] = datasheet. 27 . } for (int i = 2.getCell(0).getNumericCellValue().getNumericCellValue() .threshold > 0) { rowsord[j] = rows[i]. i < numrows. setMinThread(0. } setMaxThread(rows).for (int i = 2. sumthreads = threads.getCell(0).2. j++. i < numrows. i++) { if (rows[i].getCell(0). } } threshold = getMinThread().getNumericCellValue().
setCellValue((sumgwctime / cont1)).getNumericCellValue().getCell(4).getCell(5).getNumericCellValue(). cont1 = 1.setCellValue((sumwmsrate / cont1)).getCell(6). k < getNumRow() . cont1++. sumtctime += rowsord[k]. Row. sumwmsrate = rowsord[i]. Row.createCell(0).getNumericCellValue(). sumtcrate += rowsord[k].getNumericCellValue(). k++) { if (threads == rowsord[k].getNumericCellValue().createCell(2). sumtctime = rowsord[i].getNumericCellValue(). cont2++. Row.getCell(3). 28 .getNumericCellValue(). } } if(cont2==0){ Row=sheet. Row.setCellValue((sumthreads / cont1)).createCell(1).setCellValue((sumwmsctime / cont1)). Row=sheet.getNumericCellValue().getCell(6) . i++.setCellValue((sumtctime / cont1)).getNumericCellValue().createCell(18).getNumericCellValue().getCell(2). sumgwcrate = rowsord[i]. sumgwcrate += rowsord[k]. Row. sumwmsctime += rowsord[k].createCell(3). HSSFRow Row = null.createCell(19).getCell(5) . sumtcrate = rowsord[i]. sumgwctime += rowsord[k].getCell(4) .createCell(17). for (int k = i + 1.getCell(2) .createCell(16).getCell(3) .getRow(28).2.setCellValue((sumtcrate / cont1)).getCell(0) .setCellValue((sumthreads / cont1)).getRow(1). Row.getNumericCellValue()) { sumthreads += rowsord[k].getNumericCellValue().getCell(0) . Row.sumgwctime = rowsord[i].getNumericCellValue(). sumwmsrate += rowsord[k]. Row.setCellValue((sumgwcrate / cont1)).getCell(1) .
Row. Row. 29 .".setCellValue((sumwmsctime / cont1)).createCell(0). null. i < numrows.createRow(cont2+28). } } } public static void setMinThread(double threshold. Row = sheet. File objFile = new File(strNombreArchivo). cont2++.class.getName()).close().removeSheetAt(1).createCell(18). } catch (IOException ex) { Logger.createCell(19).createRow(cont2 + 1). Row. Row.} else{ Row = sheet. FileOutputStream archivoSalida = new FileOutputStream(objFile).setCellValue((sumgwctime / cont1)).createCell(3). k < 7. } } for (int i = 2. archivoSalida. Row.getCell(k). HSSFRow[] rows) { double minthreads = getMaxThread(). Row.getLogger(ReportGenerator. k++) { summary += rows[i].createCell(1).createCell(17). PrintableTable.log( Level.write(archivoSalida). ex).getNumericCellValue() + " ".getProperty("outfilename"). i++) { for (int k = 0.setCellValue((sumtcrate / cont1)).setCellValue((sumtctime / cont1)).setCellValue((sumgwcrate / cont1)).setCellValue((sumthreads / cont1)).main(summary). libro. } summary += ".createCell(2). String strNombreArchivo = properties.SEVERE. } libro. Row.createCell(16).setCellValue((sumthreads / cont1)). Row.setCellValue((sumwmsrate / cont1)).
} public static double getMinThread() { 30 . } public static void setMaxThread(HSSFRow[] rows) { for (int i = 2.getNumericCellValue() .getCell(0).getNumericCellValue(). for (int i = 2.getCell(0). i < getNumRow(). i++) { threads = rows[i]. i < getNumRow(). } public static double getNumRow() { return numrow. if (threads > getMaxThread()) { maxthread = threads.threshold. i++) { double threads = rows[i]. } } minthread = minthreads. } public static double getMaxThread() { return maxthread. } public static void setNumRow(double numrows) { numrow = numrows. if (threads > 0 && threads < minthreads .threshold) { minthreads = threads + threshold.double threads = 0. } } } public static double getMaxThreads() { return maxthread.
public Constants cs = new Constants().length. int rowNumber = rowstr. } public void setTitle(String title) { this.title = title.benchmarking. row++) { String[] colstr = rowstr[row].split(" ").colNumber = colNumber. String summary) { String[] rowstr = summary.rowNumber = rowNumber. public class PrintableTable { private String title. if (colstr.title = title.uva. data = new String[rowNumber + 1][colNumber].java package es.length. } } this. this. } public String getTitle() { return title. int colNumber = 0."). private String[][] data. } } 2. private int rowNumber. for (int row = 0.return minthread.idelab.4.­ PrintableTable. row < rowstr. public PrintableTable(String title.length. private int colNumber.split(". } 31 . this.length > colNumber) { colNumber = colstr.
row++) { colstr = rowstr[row].data[0][0] = "Threads". } } } public String toString() { int colWidth = getColWidth().1) + "\n". this.colNumber.title. row < this.data[row + 1][col] = colstr[col]. (colNumber * (colWidth + 1) . for (int row = 0.split(" "). String line = " " + getRepeated("_".data[0][1] = "WMS-C-Wrapper". this.title.data[0][6] = "TileCache".split(". this. this. this. col < this.data[0][2] = "GeoWebCache".data[0][3] = "TileCache".length() + 0. (int) ((colNumber * (colWidth + 1) . table += "|" + getRepeated(" ".rowNumber. colNumber * (colWidth + 1) .length() .data[0][4] = "WMS-C-Wrapper". this. table += line.public String[][] getData() { return data.7) / 2)) + "|\n".1) / 2) + title + getRepeated(" ".data = data. } public void setData(String[][] data) { this. String[] colstr. } public void setData(String summary) { String[] rowstr = summary.data[0][5] = "GeoWebCache". 32 . col++) { this. this."). for (int col = 0. String table = "".
i++) { chain += s. } } return width. } return chain. table += line. return table.toString().getAvgRate()+getRepeated(" ".getAvgRate().(int) (3 * (colWidth + 1) . col < colNumber. } table += "|\n". for (int row = 0. if (row == 0) { table += line.getAvgTime(). row++) { for (int col = 0.toString(). } private int getColWidth() { int width = 0. table += getRepeated(" ".length()). (3 * (colWidth + 1) .length()) / 2)+cs. } private String getRepeated(String s.length() + 1)) / 2) + "|".getAvgTime()+ getRepeated(" ". row < rowNumber + 1. col++) { if (data[row][col]. table += data[row][col]. col < colNumber.data[row][col]. int n) { String chain = "".length()) / 2)+cs.table += line.length(). table += "|"+ getRepeated(" ". for (int i = 0.setData(summary). row++) { for (int col = 0. 33 . (3 * (colWidth + 1) cs. } } table += line. row < rowNumber + 1. i < n.toString().getAvgRate().cs. tbl.length() > width) width = data[row][col].length() + 1)) / 2) + "|\n".toString() + getRepeated(" ". } public static void main(String summary) { PrintableTable tbl = new PrintableTable("Results Summary". col++) { table += "|".getAvgTime(). for (int row = 0. summary).(int) (3 * (colWidth + 1) (cs.(cs. colWidth)+"|"+getRepeated(" ". colWidth .
out.println(tbl).System. } } 34 .
Documents Similar To 2010-02 benchmarking_servicios_wmsc.pdf
testayker
Jose Tomaylla Yupanqui
Hector Martinez Figueroa
Carlos Discalzi Mejias
Israel Pedro l. Sanches
alexandrejacques
api-15030801

References: resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución