Arquitectura de microservicios: diseño de arquitectura de plataforma en la nube PaaS basada en microservicios y tecnología de contenedores Docker
El objetivo de construir una plataforma en la nube PaaS basada en una arquitectura de microservicios y tecnología de contenedores Docker es proporcionar a nuestros desarrolladores un conjunto de servicios para un rápido desarrollo, implementación, gestión de operación y mantenimiento, y un desarrollo e integración continuos. procesos. La plataforma proporciona recursos como infraestructura, middleware, servicios de datos y servidores en la nube. Los desarrolladores solo necesitan desarrollar códigos comerciales y enviarlos a la biblioteca de códigos de la plataforma, realizar algunas configuraciones necesarias y el sistema se construirá e implementará automáticamente, logrando un desarrollo ágil. e implementación de aplicaciones. Iterar rápidamente. En términos de arquitectura del sistema, la plataforma en la nube PaaS se divide principalmente en tres partes: arquitectura de microservicio, tecnología de contenedor Docker y DveOps. Este artículo presenta principalmente la implementación de la arquitectura de microservicio.
Si quieres aprender más sobre ingeniería, alto rendimiento y distribución de Java. Los amigos que estén familiarizados con los microservicios, el análisis del código fuente de Spring, MyBatis y Netty pueden unirse a mi grupo de comunicación avanzada de Java: 854630135. En el grupo, Ali Daniel explicará la tecnología en vivo y compartirá videos de tecnología de Internet a gran escala de Java con todos gratis.
La implementación de microservicios requiere mucho esfuerzo técnico para desarrollar la infraestructura, lo que obviamente no es realista para muchas empresas. No te preocupes, la industria ya cuenta con muy buenos frameworks de código abierto para nuestra referencia. Actualmente, los marcos de microservicios relativamente maduros en la industria incluyen Netflix, Spring Cloud y Dubbo de Alibaba. Spring Cloud es un marco para implementar microservicios basado en Spring Boot. Proporciona los componentes necesarios para desarrollar microservicios. Cuando se combine con Spring Boot, será muy conveniente desarrollar servicios en la nube con una arquitectura de microservicios. Spring Cloud contiene muchos submarcos, de los cuales Spring Cloud Netflix es un conjunto de marcos. En nuestro diseño de arquitectura de microservicios, se utilizan muchos componentes del marco Spring Cloud Netflix. El proyecto Spring Cloud Netflix no existe desde hace mucho tiempo y hay muy pocos documentos relevantes. El blogger estaba estudiando este marco y leyó muchos documentos en inglés, lo cual fue muy problemático. Para los estudiantes que recién comienzan a usar este marco para construir una arquitectura de aplicaciones de microservicio, es posible que no sepan cómo comenzar. A continuación, presentaremos los marcos o componentes que necesitamos para respaldar la arquitectura de microservicio en el proceso de construcción de una arquitectura de microservicio.
Para demostrar directamente la composición de la arquitectura de microservicios y el principio de dibujar el diagrama de arquitectura del sistema, como se muestra en la siguiente figura:
En la figura anterior, podemos ver la ruta general de acceso al microservicio: Solicitud externa → Equilibrio de carga → Puerta de enlace de servicio (GateWay) → Microservicio → Servicio de datos/servicio de mensajes. Tanto las puertas de enlace de servicios como los microservicios utilizan el registro y el descubrimiento de servicios para llamar a otros servicios que dependen de ellos, y cada grupo de servicios puede obtener información de configuración a través del servicio del centro de configuración.
Service Gateway
El gateway es la puerta entre el mundo externo (como los navegadores de los clientes, los dispositivos móviles, etc.) y los sistemas internos de la organización. Todas las solicitudes de los clientes deben pasar por el. puerta de enlace para acceder a los servicios Backend. Para hacer frente a un alto acceso simultáneo, la puerta de enlace de servicio se implementa en un clúster, lo que significa que se requiere equilibrio de carga. Usamos Amazon EC2 como servidor virtual en la nube y usamos ELB (Elastic Load Balancing) para el equilibrio de carga. EC2 tiene la función de configurar automáticamente la capacidad. Cuando el tráfico de usuarios alcanza un pico, EC2 puede aumentar automáticamente la capacidad para mantener el rendimiento del host virtual. El equilibrio de carga elástico de ELB distribuye automáticamente el tráfico entrante de aplicaciones en múltiples instancias. Para garantizar la seguridad, las solicitudes de los clientes deben protegerse con cifrado https, lo que requiere que realicemos una descarga SSL y usemos Nginx para descargar las solicitudes cifradas. Las solicitudes externas se enrutan al servicio GateWay en el clúster GateWay después del equilibrio de carga de ELB y el servicio GateWay las reenvía a los microservicios. La puerta de enlace de servicio es el límite del sistema interno y tiene las siguientes funciones básicas:
1. Enrutamiento dinámico: enruta dinámicamente las solicitudes al clúster de servicios de back-end requerido. Aunque internamente existe una compleja red de microservicios distribuidos, desde la perspectiva de la puerta de enlace, el sistema externo parece un servicio general, lo que protege la complejidad de los servicios back-end.
2. Limitación actual y tolerancia a fallos: asigne capacidad para cada tipo de solicitud, inicie solicitudes externas cuando el número de solicitudes exceda el umbral, limite el tráfico y proteja los servicios back-end para que no se vean abrumados por el tráfico intenso. ; los servicios internos de una parte Cuando ocurre una falla, cree algunas respuestas directamente en el límite y concéntrese en la tolerancia a fallas en lugar de reenviar solicitudes al clúster interno para garantizar que los usuarios tengan una buena experiencia.
3. Autenticación y control de seguridad: realice la autenticación del usuario en cada solicitud externa, rechace las solicitudes que no superen la autenticación e implemente funciones anti-rastreadores mediante el análisis de patrones de acceso.
4. Monitoreo: la puerta de enlace puede recopilar datos significativos y realizar estadísticas para brindar soporte de datos para la optimización del servicio en segundo plano.
5. Registro de acceso: la puerta de enlace puede recopilar información del registro de acceso, como por ejemplo, ¿a qué servicio se accedió? ¿Procesamiento (qué excepciones ocurrieron) y resultados? ¿Cuánto tiempo tomó? Al analizar el contenido del registro, el sistema backend se puede optimizar aún más.
Utilizamos Zuul, un componente de código abierto del marco Spring Cloud Netflix, para implementar el servicio de puerta de enlace. Zuul utiliza una serie de diferentes tipos de filtros. Al anular los filtros, podemos implementar de manera flexible varias funciones de la puerta de enlace (GateWay).
Si quieres aprender más sobre ingeniería, alto rendimiento y distribución de Java. Los amigos que estén familiarizados con los microservicios, el análisis del código fuente de Spring, MyBatis y Netty pueden unirse a mi grupo de comunicación avanzada de Java: 854630135. En el grupo, Ali Daniel explicará la tecnología en vivo y se compartirán videos de tecnología de Internet a gran escala de Java. todos gratis.
Registro y descubrimiento de servicios
Dado que la arquitectura de microservicios es una estructura de malla compuesta por una serie de servicios detallados con responsabilidades únicas, y los servicios se comunican a través de mecanismos livianos, esto presenta la Problema de registro y descubrimiento de servicios. El proveedor de servicios necesita registrar e informar la dirección del servicio para que la llamada de servicio pueda descubrir el servicio de destino. Nuestra arquitectura de microservicios utiliza componentes Eureka para el registro y descubrimiento de servicios. Todos los microservicios (mediante la configuración de la información del servicio Eureka) se registrarán en el servidor Eureka y enviarán latidos periódicamente para realizar controles de estado. La configuración predeterminada de Eureka es enviar un latido cada 30 segundos para mostrar que el servicio aún está activo. El intervalo para enviar latidos se puede configurar a través de los parámetros de configuración de Eureka. Después de recibir el último latido de la instancia del servicio, el servidor Eureka necesita esperar 90 segundos (la configuración predeterminada es 90 segundos, que se puede modificar a través de los parámetros de configuración) para reconocer que el servicio está inactivo (es decir, no se reciben tres latidos). veces consecutivas). Si se cierra en el modo de autoprotección de Eureka, se borrará la información de registro del servicio. El llamado modo de autoprotección significa que cuando se produce una partición de la red y Eureka pierde demasiados servicios en un corto período de tiempo, entrará en el modo de autoprotección, es decir, si un servicio no envía latidos durante un tiempo prolongado. tiempo, Eureka no eliminará el servicio. El modo de autoprotección está activado de forma predeterminada y se puede desactivar mediante parámetros de configuración.
El servicio Eureka se implementa en el clúster (la implementación del clúster Eureka se describirá en detalle en otro artículo. Todos los nodos de Eureka en el clúster sincronizarán automáticamente la información de registro de los microservicios con regularidad para garantizar). que toda la información de registro de los servicios de Eureka permanezca consistente. Entonces, ¿cómo descubre un nodo Eureka otros nodos en el clúster de Eureka? Establecemos la asociación de todos los nodos de Eureka a través de un servidor DNS, lo que requiere construir un servidor DNS mientras implementamos el clúster de Eureka.
Cuando el servicio de puerta de enlace reenvía solicitudes externas o los microservicios de back-end se llaman entre sí, irá al servidor Eureka para buscar la información de registro del servicio de destino, descubrirá el servicio de destino y lo llamará, lo que forma un proceso de registro y descubrimiento del servicio. Todo el proceso.
Hay muchos parámetros de configuración en Eureka, cientos de ellos, que cubriremos en detalle en otro artículo.
Implementación de microservicios
Los microservicios son una serie de servicios con responsabilidades únicas y detalladas. Se dividen en unidades de servicio independientes y tienen buena escalabilidad y bajo acoplamiento. Pueden ser diferentes microservicios. desarrollado utilizando diferentes lenguajes, y cada servicio maneja un único negocio de servicios.
Los microservicios se pueden dividir en servicios de front-end (también llamados servicios de borde) y servicios de back-end (también llamados servicios intermedios). Los servicios de front-end son la agregación y adaptación necesarias de los servicios de back-end y luego se exponen a diferentes dispositivos externos (). PC, teléfono, etc.), todos los servicios se registrarán en el servidor Eureka una vez iniciados y habrá dependencias complejas entre los servicios. Cuando el servicio de puerta de enlace reenvía una solicitud externa para llamar al servicio de front-end, se puede encontrar el servicio de destino consultando el registro de servicios para llamarlo. Lo mismo ocurre cuando el servicio de front-end llama al servicio de back-end. puede implicar que varios servicios se llamen entre sí. Dado que cada microservicio se implementa como un clúster, se requiere equilibrio de carga cuando los servicios se llaman entre sí, por lo que hay un componente LB en cada servicio para el equilibrio de carga.
Los microservicios se ejecutan como imágenes en contenedores Docker. La tecnología de contenedores Docker hace que la implementación de nuestros servicios sea simple y eficiente. Los métodos de implementación tradicionales requieren que el entorno de ejecución esté instalado en cada servidor. Si tenemos una gran cantidad de servidores, instalar el entorno de ejecución en cada servidor será una tarea muy laboriosa, y una vez que el entorno de ejecución cambie, será necesario reinstalarlo, lo cual es simplemente catastrófico. Al utilizar la tecnología de contenedor Docker, solo necesitamos generar una nueva imagen a partir de la imagen básica requerida (jdk, etc.) y los microservicios, e implementar la imagen final en el contenedor Docker para su ejecución. Este es un método de servicio de implementación rápida simple y eficiente. Se pueden ejecutar varios microservicios en cada contenedor Docker. Los contenedores Docker se implementan en clústeres y se administran mediante Docker Swarm. Creamos un almacén espejo para almacenar todas las imágenes base y las imágenes de entrega finales generadas, y administramos todas las imágenes en el almacén espejo.
Tolerancia a fallas del servicio
Existen dependencias intrincadas entre los microservicios. Una sola solicitud puede depender de múltiples servicios de back-end, y estos servicios pueden fallar o retrasarse en la producción real. En sistemas de alto tráfico, los retrasos en el servicio pueden agotar el servicio en un corto período de tiempo. En un sistema con mucho tráfico, una vez que un servicio se retrasa, puede agotar los recursos del sistema en un corto período de tiempo y arrastrar todo el sistema. Por lo tanto, un servicio que no puede aislar y tolerar fallas es en sí mismo catastrófico. Nuestra arquitectura de microservicio utiliza Hystrix, un componente de código abierto de Netflix, para brindar protección elástica de tolerancia a fallas para servicios a través de mecanismos como el modo de convergencia, el modo de aislamiento, la reversión y la limitación de corriente para garantizar la estabilidad del sistema.
1. Modo de soplado: El principio del modo de soplado es similar al de un fusible de circuito. Cuando el circuito sufre un cortocircuito, el fusible se funde para proteger el circuito de pérdidas catastróficas. Cuando una excepción de servicio o una gran cantidad de retraso cumple con las condiciones del disyuntor, la persona que llama al servicio iniciará activamente el disyuntor, ejecutará la lógica de reversión y retrocederá directamente, y no continuará llamando al servicio para derribar aún más el sistema. De forma predeterminada, el disyuntor está configurado con un umbral de tasa de error del 50% para llamadas de servicio. Cuando se excede el umbral, el modo de disyuntor se iniciará automáticamente. Después de que el servicio esté aislado por un período de tiempo, el fusor entrará en un estado semi-fusionado, lo que permitirá intentar una pequeña cantidad de solicitudes, regresará al estado fusionado si la llamada aún falla y desactivará el modo fusionado si la llamada tiene éxito.
2. Modo de aislamiento: Hystrix utiliza el aislamiento de subprocesos de forma predeterminada. Los diferentes servicios utilizan diferentes grupos de subprocesos y no se afectan entre sí. Cuando un servicio falla y agota su grupo de subprocesos, otros servicios se ejecutan normalmente y no se ven afectados, logrando así el aislamiento. Por ejemplo, usamos andThreadPoolKey para configurar el servicio para que use un grupo de subprocesos llamado TestThreadPool para lograr el aislamiento de otros grupos de subprocesos con nombre.
3. Reversión: el mecanismo de reversión es en realidad un tipo de tolerancia a fallas del servicio y su principio es similar al manejo de excepciones en Java. Simplemente herede HystixCommand y anule el método getFallBack() y escriba la lógica de procesamiento en este método. Por ejemplo, puede generar excepciones directamente (falla rápida), devolver valores nulos o predeterminados, o devolver datos de respaldo, etc. Cuando una llamada de servicio genera una excepción, se ejecutará getFallBack() en su lugar.
Las siguientes situaciones desencadenan la reversión:
1) El programa genera una excepción que no es HystrixBadRequestExcepption. Cuando se lanza una excepción HystrixBadRequestExcepption, el programa que llama puede detectar la excepción y no activará la reversión. Cuando ocurre una excepción, se activará una reversión;
2) El programa se queda sin tiempo
3) Se activa un disyuntor
4; ) El grupo de subprocesos está lleno.
4. Limitar el tráfico: limitar el tráfico se refiere a limitar el acceso simultáneo a los servicios, establecer el número de concurrencias por unidad de tiempo y rechazar y revertir las solicitudes que excedan el límite para evitar que se vacíen los servicios back-end. .
Hystix utiliza el modo de comando HystrixCommand para encapsular la lógica de llamadas de dependencia, de modo que las llamadas relacionadas estén protegidas automáticamente por la tolerancia elástica a fallas de Hystrix. El programa que llama debe heredar HystrixCommand, escribir la lógica de llamada en run () y usar ejecutar () (bloqueo sincrónico) o cola () (sin bloqueo asíncrono) para activar la ejecución de run ().
Centro de configuración dinámica
Los microservicios dependen en gran medida de la configuración. Es posible que algunos parámetros de configuración deban modificarse dinámicamente durante la operación del servicio, por ejemplo: ajustarse dinámicamente según el tráfico de acceso. La forma tradicional de implementar la configuración de la información, como xml, yml y otros archivos de configuración, es empaquetar junto con la aplicación. Cada vez que es necesario modificar, volver a enviar, empaquetar y compilar el código, generar nuevas imágenes y reiniciar el servicio. la eficiencia es demasiado baja, lo que obviamente no es razonable, por lo que necesitamos crear un servicio de centro de configuración dinámica para admitir la configuración dinámica de microservicios. Usamos el servicio Spring Cloud configserver para ayudarnos a implementar un centro de configuración dinámica. Los códigos de microservicio que desarrollamos se almacenan en el almacén privado del servidor git. Todos los archivos de configuración que requieren configuración dinámica se almacenan en el servicio configserver (centro de configuración, también un microservicio) en el servidor git y se implementan en los microservicios en el. Contenedor Docker. El servicio lee dinámicamente la información del archivo de configuración del servidor git. Cuando el código modificado del almacén git local se envía al almacén del servidor git, el enlace del lado del servidor git (posterior a la recepción, que se llamará automáticamente después de que se complete la actualización del código del lado del servidor) detectará automáticamente si hay un Actualización del archivo de configuración. Si es así, el enlace del lado del servidor git La cola de mensajes enviará un mensaje al centro de configuración (configserver, un microservicio implementado en un contenedor) para notificar al centro de configuración que actualice el archivo de configuración correspondiente. Esto permite que los microservicios obtengan la información más reciente del archivo de configuración, lo que permite la configuración dinámica.
Estos marcos o componentes son el núcleo para respaldar la implementación de la arquitectura de microservicios. En aplicaciones reales, también usaremos muchos otros componentes, como componentes de servicio de registro, componentes de servicio de mensajes, etc., que pueden ser. elegido según las necesidades del negocio. Cuando implementamos la arquitectura de microservicios, nos referimos a muchos componentes de código abierto del marco Spring Cloud Netflix, incluido Zuul (puerta de enlace de servicio), Eureka (registro y descubrimiento de servicios), Hystrix (tolerancia a fallas del servicio), Ribbon (equilibrio de carga del cliente), etc. Estos excelentes componentes de código abierto proporcionan un atajo para implementar la arquitectura de microservicios.
Si quieres aprender más sobre ingeniería, alto rendimiento y distribución de Java. Los amigos que estén familiarizados con los microservicios, el análisis del código fuente de Spring, MyBatis y Netty pueden unirse a mi grupo de comunicación avanzada de Java: 854630135. En el grupo, Ali Daniel explicará la tecnología en vivo y se compartirán videos de tecnología de Internet a gran escala de Java. todos gratis.