Emulación de servicios web de Amazon en un proceso JVM. Evitar Roskomnadzor y acelerar el desarrollo y las pruebas

¬ŅPor qu√© podr√≠a necesitar emular la infraestructura de servicios web de Amazon?

En primer lugar, está ahorrando, ahorrando tiempo para el desarrollo y la depuración, y lo que es igualmente importante, ahorrando dinero del presupuesto del proyecto. Está claro que el emulador no será 100% idéntico al entorno original que estamos tratando de emular. Pero con el propósito de acelerar el desarrollo y la automatización del proceso, las similitudes existentes deberían ser suficientes. Lo más actual que sucedió en 2018 con AWS fue el bloqueo por parte de los proveedores de IP de las direcciones IP de las subredes de AWS en la Federación de Rusia. Y estos bloqueos afectaron nuestra infraestructura ubicada en la nube de Amazon. Si planea usar la tecnología AWS y colocar el proyecto en esta nube, entonces para el desarrollo y la prueba de emulación más que vale la pena.



En la publicaci√≥n, le contar√© c√≥mo logramos realizar un truco con los servicios S3, SQS, RDS PostgreSQL y Redshift al migrar un almac√©n de datos existente a AWS durante muchos a√Īos.

Esto es solo una parte de mi reuni√≥n del a√Īo pasado en el mapa , que corresponde a los temas de los centros de AWS y Java. La segunda parte se refiere a PostgreSQL, Redshift y las bases de datos de columnas, y su versi√≥n de texto puede publicarse en los centros correspondientes, los videos y las diapositivas est√°n en el sitio web de la conferencia .

Al desarrollar una aplicación para AWS durante el bloqueo de subredes de AWS, el equipo prácticamente no los notó en el proceso diario de desarrollo de nuevas funcionalidades. Las pruebas también funcionaron y puede depurar la aplicación. Y solo cuando intentamos ver los registros de la aplicación en las logias, las métricas en SignalFX o el análisis de datos en Redshift / PostgreSQL RDS se decepcionaron: los servicios no estaban disponibles a través de la red del proveedor ruso. La emulación de AWS nos ayudó a no notar esto y evitar retrasos mucho mayores al trabajar con la nube de Amazon a través de una red VPN.

Cada proveedor de la nube "bajo el cap√≥" tiene muchos dragones y no debe ceder a la publicidad. Debe comprender por qu√© todo esto es necesario para el proveedor de servicios. Por supuesto, la infraestructura existente de Amazon, Microsoft y Google tiene ventajas. Y cuando le dicen que todo se hace solo para que sea conveniente para su desarrollo, lo m√°s probable es que est√©n tratando de ponerle la aguja y darle la primera dosis de forma gratuita. Para que luego no se salgan de la infraestructura y la tecnolog√≠a espec√≠fica. Por lo tanto, intentaremos evitar el bloqueo del proveedor. Est√° claro que no siempre es posible abstraerse por completo de decisiones espec√≠ficas y creo que a menudo es posible abstraer casi el 90% en un proyecto. Pero el 10% restante del proyecto, vinculado a un proveedor de tecnolog√≠as que son muy importantes, est√° optimizando el rendimiento de la aplicaci√≥n o las caracter√≠sticas √ļnicas de las cuales no se encuentran en ning√ļn otro lado. Siempre deben recordar las ventajas y desventajas de las tecnolog√≠as y protegerse lo m√°s posible, no "sentarse" en una API espec√≠fica de un proveedor de infraestructura en la nube.

Amazon escribe sobre el procesamiento de mensajes en su sitio web. La esencia y la abstracción de las tecnologías de intercambio de mensajes son las mismas en todas partes, aunque hay matices: mensajes que pasan por colas o por temas. Por lo tanto, AWS recomienda utilizar el Apache ActiveMQ proporcionado y administrado para migrar aplicaciones de un agente de mensajería existente y para nuevas aplicaciones de Amazon SQS / SNS. Este es un ejemplo de enlace a su propia API, en lugar de la API JMS estandarizada y los protocolos AMQP, MMQT, STOMP. Está claro que este proveedor con su solución puede tener un mayor rendimiento, admite escalabilidad, etc. Desde mi punto de vista, si usa sus bibliotecas, y no API estandarizadas, habrá muchos más problemas.

AWS tiene una base de datos Redshift. Es una base de datos distribuida con una arquitectura paralela masiva. Puede cargar una gran cantidad de sus datos en tablas en m√ļltiples sitios Redshft en Amazon y realizar consultas anal√≠ticas en grandes conjuntos de datos. Este no es un sistema OLTP en el que es importante que realice peque√Īas solicitudes en un peque√Īo n√ļmero de registros con la suficiente frecuencia con garant√≠as de ACID. Al trabajar con Redshift, se supone que no tiene una gran cantidad de consultas por unidad de tiempo, pero pueden leer agregados en una gran cantidad de datos. El proveedor coloca este sistema para actualizar su almac√©n de datos (almac√©n) en AWS y promete una carga de datos simple. Lo cual no es del todo cierto.

Un extracto de la documentación sobre qué tipos admite Amazon Redshift. Es un conjunto bastante escaso, y si necesita algo para almacenar y procesar datos que no figuran en esta lista, será difícil para usted trabajar. Por ejemplo un GUID.

Pregunta de la sala, "¬ŅY JSON?"

- JSON solo se puede escribir como VARCHAR y hay varias funciones para trabajar con JSON.
Comentario de la audiencia: "Postgres tiene soporte JSON normal".

- S√≠, tiene soporte para este tipo de datos y funciones. Pero Redshift se basa en PostgreSQL 8.0.2. Hubo un proyecto ParAccel, si no me equivoco, esta tecnolog√≠a de 2005 es una bifurcaci√≥n de postgres que tiene un programador para solicitudes distribuidas basadas en una arquitectura paralela masiva. Pasaron 5-6 a√Īos y este proyecto fue licenciado para la plataforma Amazon Web Servces y se llam√≥ Redshift. Se ha eliminado algo del Postgres original, se ha agregado mucho. Agregaron que relacionado con la autenticaci√≥n / autorizaci√≥n en AWS, con roles, la seguridad en Amazon funciona bien. Pero si necesita, por ejemplo, conectarse desde Redshift a otra base de datos utilizando Fuente de datos externa, entonces no encontrar√° esto. No hay funciones para trabajar con XML, funciones para trabajar con JSON dos veces y se calcularon mal.

Al desarrollar una aplicaci√≥n, intente no depender de implementaciones espec√≠ficas, y el c√≥digo de la aplicaci√≥n depende solo de abstracciones. Puede crear estas fachadas y abstracciones usted mismo, pero en este caso hay muchas bibliotecas listas para usar: fachadas. Que resumen el c√≥digo de implementaciones espec√≠ficas, de marcos espec√≠ficos. Est√° claro que pueden no admitir toda la funcionalidad como un "denominador com√ļn" para las tecnolog√≠as. Es mejor desarrollar software basado en abstracciones para simplificar las pruebas.

Para emular AWS, mencionaré dos opciones. El primero es más honesto y correcto, pero funciona más lentamente. El segundo es sucio y rápido. Le contaré sobre la opción de pirateo: estamos tratando de crear toda la infraestructura en un solo proceso; las pruebas y la opción multiplataforma funcionarán más rápido con el trabajo en Windows (donde Docker no siempre puede ganar dinero con usted).

El primer método es perfecto si está desarrollando en linux / macos y tiene docker, sería mejor usar atlassian localstack . Es conveniente utilizar contenedores de prueba para integrar localstack en la JVM.

Lo que me impidi√≥ usar lockalstack en Docker en el proyecto fue que el desarrollo estaba bajo Windows y nadie confirm√≥ la versi√≥n alfa de Docker cuando comenz√≥ este proyecto ... Tambi√©n es posible que no se les permita instalar una m√°quina virtual con Linux y Docker en ninguna compa√Ī√≠a que se tome en serio a la seguridad de la informaci√≥n. No estoy hablando de trabajar en un entorno seguro en bancos de inversi√≥n y de prohibir casi todos los firewalls de tr√°fico all√≠.

Consideremos las opciones para emular el almacenamiento simple S3. Este no es un sistema de archivos ordinario de Amazon, sino más bien un almacén de objetos distribuidos. En el que coloca sus datos como un BLOB, sin la posibilidad de modificación y adición de datos. Hay almacenamientos distribuidos similares de todos los fabricantes. Por ejemplo, el almacenamiento de objetos distribuidos de Ceph le permite trabajar con su funcionalidad utilizando el protocolo S3 REST y el cliente existente con una modificación mínima. Pero esta es una solución bastante pesada para el desarrollo y prueba de aplicaciones Java.

Un proyecto más rápido y más adecuado es la biblioteca s3proxy java. Emula el protocolo S3 REST y lo traduce a las llamadas API jcloud correspondientes y le permite utilizar muchas implementaciones para la lectura real y el almacenamiento de datos. Puede transmitir llamadas a la API de Google App Engine, la API de Microsoft Azure, pero para las pruebas es más conveniente usar el almacenamiento transitorio jcloud en RAM. También es necesario configurar la versión del protocolo de autenticación AWS S3 y especificar la clave y los valores secretos, también configurar el punto final: el puerto y la interfaz en la que escuchará este Proxy S3. En consecuencia, su código que utiliza el cliente AWS SDK debe conectarse en pruebas al punto final S3 AWS, no a la región AWS. Una vez más, recuerde que s3proxy no es compatible con todas las características de la API S3, ¡pero todos nuestros escenarios de uso emulan perfectamente! Incluso la carga multiparte para archivos grandes es compatible con s3proxy.



Amazon Simple Queue Service es un servicio de colas. Hay un servicio de cola elasticmq que está escrito en scala y se puede presentar a su aplicación utilizando el protocolo Amazon SQS. No lo utilicé en el proyecto, así que daré el código de inicialización, confiando en la información de sus desarrolladores.



En el proyecto, fui por el otro lado y el código depende de las abstracciones spring-jms de JmsTemplate y JmsListener y las dependencias del proyecto especifican el controlador JMS para SQS com.amazonaws: amazon-sqs-java-messaging-lib. Esto es lo que concierne al código de la aplicación principal.



En las pruebas, conectamos Artemis-jms-server como un servidor JMS incorporado para las pruebas, y en el contexto de Spring de prueba, en lugar de la fábrica de conexiones SQS, usamos la fábrica de conexiones Artemis. Artemis es la próxima versión de Apache ActiveMQ, un Middleware orientado a mensajes moderno y completo, no solo una solución de prueba. Quizás pasemos a su uso en el futuro, no solo en las pruebas automáticas. Por lo tanto, utilizando las abstracciones JMS junto con Spring, hemos simplificado tanto el código de la aplicación como la capacidad de probarlo fácilmente. Solo necesita agregar las dependencias org.springframework.boot: spring-boot-starter-artemis y org.apache.activemq: artemis-jms-server.



En algunas pruebas, PostgreSQL se puede emular reemplazándolo con H2Database . Esto funcionará si las pruebas no son aceptadas y no utilizan funciones PG específicas. Al mismo tiempo, H2 puede emular un subconjunto del protocolo de conexión PostgreSQL sin soporte para tipos de datos y funciones. En nuestro proyecto, utilizamos Foreing Data Wrapper, por lo que este método no funciona para nosotros.

Puede ejecutar PostgreSQL real. postgresql-embedded descarga la distribuci√≥n real, o m√°s bien el archivo con archivos binarios para la plataforma con la que corremos, lo descomprime. En Linux en tempfs en RAM, en Windows en% TEMP%, se inicia el proceso del servidor postgresql, configura los ajustes del servidor y los par√°metros de la base de datos. Debido a las caracter√≠sticas de distribuci√≥n de distribuci√≥n, las versiones anteriores a PG 11 no funcionan en Linux. Para m√≠, hice una biblioteca de contenedor que le permite obtener ensamblados binarios de PostgreSQL no solo desde un servidor HTTP sino tambi√©n desde el repositorio maven. Lo cual puede ser muy √ļtil cuando se trabaja en redes aisladas y se construye en un servidor CI sin acceso a Internet. Otra conveniencia de trabajar con mi contenedor es la anotaci√≥n del componente CDI, que facilita el uso del componente en el contexto Spring, por ejemplo. La implementaci√≥n de la interfaz del servidor AutoClosable apareci√≥ antes que en el proyecto original. No es necesario recordar detener el servidor, se detendr√° cuando el contexto Spring se cierre autom√°ticamente.

Al inicio, puede crear una base de datos basada en scripts, complementando el contexto de Spring con las propiedades apropiadas. Ahora estamos creando un esquema de base de datos usando scripts de ruta para migrar el esquema de la base de datos, que se inician cada vez que la base de datos se crea en pruebas.

Para verificar los datos después de ejecutar las pruebas, utilizamos la biblioteca spring-test-dbunit. En las anotaciones a los métodos de prueba, indicamos con qué cargas comparar el estado de la base de datos. Esto elimina la necesidad de escribir código para trabajar con dbunit, solo necesita agregar el oyente de la biblioteca al código de prueba. Puede especificar en qué orden se eliminan los datos de las tablas después de completar el método de prueba, si el contexto de la base de datos se reutiliza entre las pruebas. En 2019, hay un enfoque más moderno implementado en la base de datos que funciona con junit5. Puede ver un ejemplo de uso, por ejemplo aquí .

Lo más difícil fue emular Amazon Redshift. Existe un proyecto de controlador falso de desplazamiento al rojo . El proyecto se centra en emular la carga de datos por lotes en la base de datos analítica de AWS. En el emulador de protocolo jdbc: postgresqlredshift, se implementan los comandos COPY, UNLOAD, todos los demás comandos se delegan al controlador JDBC PostgreSQL normal.

Por lo tanto, las pruebas no funcionarán de la misma manera que en Redshift, la operación de actualización, que utiliza una tabla diferente como fuente de datos para la actualización (la sintaxis difiere en Redshift y PostgreSQL 9+. También noté una interpretación diferente de las citas entre líneas en comandos SQL entre estas bases de datos.

Debido a la arquitectura de una base de datos real de Redshift, las operaciones de inserción, actualización y eliminación de datos son bastante lentas y "costosas" en términos de E / S. Es posible insertar datos con un rendimiento aceptable solo en "paquetes" grandes y el comando COPIAR solo le permite descargar datos de un sistema de archivos S3 distribuido. Este comando en la base de datos admite varios formatos de datos AVRO, CSV, JSON, Parquet, ORC y TXT. Y el proyecto del emulador se centra en CSV, TXT, JSON.

Entonces, para emular Redshift en las pruebas, deberá iniciar la base de datos PostgreSQL como se describió anteriormente y ejecutar la emulación del repositorio S3, y al crear una conexión a los postgres, solo necesita agregar redshift-fake-driver en el classpath y especificar la clase de controlador jp.ne.opt.redshiftfake.postgres. FakePostgresqlDriver. Después de eso, puede usar la misma ruta migratoria para migrar el esquema de la base de datos, y dbunit ya está familiarizado para comparar datos después de ejecutar las pruebas.



Me pregunto cu√°ntos lectores usan AWS y Redshift en su trabajo. Escriba en los comentarios sobre su experiencia.

Utilizando solo proyectos de código abierto, el equipo pudo acelerar el desarrollo en el entorno de AWS, ahorrar dinero del presupuesto del proyecto y no detener el trabajo del equipo cuando Roskomnadzor bloqueó las subredes de AWS.

Source: https://habr.com/ru/post/444472/


All Articles